Merge from mainline
[official-gcc.git] / gcc / config / i386 / i386.md
blob868d33676162fdb831996ffb43ad36a62cf39242
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
480 (include "predicates.md")
483 ;; Compare instructions.
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
489 (define_expand "cmpti"
490   [(set (reg:CC FLAGS_REG)
491         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492                     (match_operand:TI 1 "x86_64_general_operand" "")))]
493   "TARGET_64BIT"
495   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496     operands[0] = force_reg (TImode, operands[0]);
497   ix86_compare_op0 = operands[0];
498   ix86_compare_op1 = operands[1];
499   DONE;
502 (define_expand "cmpdi"
503   [(set (reg:CC FLAGS_REG)
504         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505                     (match_operand:DI 1 "x86_64_general_operand" "")))]
506   ""
508   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509     operands[0] = force_reg (DImode, operands[0]);
510   ix86_compare_op0 = operands[0];
511   ix86_compare_op1 = operands[1];
512   DONE;
515 (define_expand "cmpsi"
516   [(set (reg:CC FLAGS_REG)
517         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518                     (match_operand:SI 1 "general_operand" "")))]
519   ""
521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522     operands[0] = force_reg (SImode, operands[0]);
523   ix86_compare_op0 = operands[0];
524   ix86_compare_op1 = operands[1];
525   DONE;
528 (define_expand "cmphi"
529   [(set (reg:CC FLAGS_REG)
530         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531                     (match_operand:HI 1 "general_operand" "")))]
532   ""
534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535     operands[0] = force_reg (HImode, operands[0]);
536   ix86_compare_op0 = operands[0];
537   ix86_compare_op1 = operands[1];
538   DONE;
541 (define_expand "cmpqi"
542   [(set (reg:CC FLAGS_REG)
543         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544                     (match_operand:QI 1 "general_operand" "")))]
545   "TARGET_QIMODE_MATH"
547   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548     operands[0] = force_reg (QImode, operands[0]);
549   ix86_compare_op0 = operands[0];
550   ix86_compare_op1 = operands[1];
551   DONE;
554 (define_insn "cmpdi_ccno_1_rex64"
555   [(set (reg FLAGS_REG)
556         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557                  (match_operand:DI 1 "const0_operand" "n,n")))]
558   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
559   "@
560    test{q}\t{%0, %0|%0, %0}
561    cmp{q}\t{%1, %0|%0, %1}"
562   [(set_attr "type" "test,icmp")
563    (set_attr "length_immediate" "0,1")
564    (set_attr "mode" "DI")])
566 (define_insn "*cmpdi_minus_1_rex64"
567   [(set (reg FLAGS_REG)
568         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
570                  (const_int 0)))]
571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572   "cmp{q}\t{%1, %0|%0, %1}"
573   [(set_attr "type" "icmp")
574    (set_attr "mode" "DI")])
576 (define_expand "cmpdi_1_rex64"
577   [(set (reg:CC FLAGS_REG)
578         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579                     (match_operand:DI 1 "general_operand" "")))]
580   "TARGET_64BIT"
581   "")
583 (define_insn "cmpdi_1_insn_rex64"
584   [(set (reg FLAGS_REG)
585         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
593 (define_insn "*cmpsi_ccno_1"
594   [(set (reg FLAGS_REG)
595         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596                  (match_operand:SI 1 "const0_operand" "n,n")))]
597   "ix86_match_ccmode (insn, CCNOmode)"
598   "@
599    test{l}\t{%0, %0|%0, %0}
600    cmp{l}\t{%1, %0|%0, %1}"
601   [(set_attr "type" "test,icmp")
602    (set_attr "length_immediate" "0,1")
603    (set_attr "mode" "SI")])
605 (define_insn "*cmpsi_minus_1"
606   [(set (reg FLAGS_REG)
607         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608                            (match_operand:SI 1 "general_operand" "ri,mr"))
609                  (const_int 0)))]
610   "ix86_match_ccmode (insn, CCGOCmode)"
611   "cmp{l}\t{%1, %0|%0, %1}"
612   [(set_attr "type" "icmp")
613    (set_attr "mode" "SI")])
615 (define_expand "cmpsi_1"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618                     (match_operand:SI 1 "general_operand" "ri,mr")))]
619   ""
620   "")
622 (define_insn "*cmpsi_1_insn"
623   [(set (reg FLAGS_REG)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625                  (match_operand:SI 1 "general_operand" "ri,mr")))]
626   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627     && ix86_match_ccmode (insn, CCmode)"
628   "cmp{l}\t{%1, %0|%0, %1}"
629   [(set_attr "type" "icmp")
630    (set_attr "mode" "SI")])
632 (define_insn "*cmphi_ccno_1"
633   [(set (reg FLAGS_REG)
634         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635                  (match_operand:HI 1 "const0_operand" "n,n")))]
636   "ix86_match_ccmode (insn, CCNOmode)"
637   "@
638    test{w}\t{%0, %0|%0, %0}
639    cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "test,icmp")
641    (set_attr "length_immediate" "0,1")
642    (set_attr "mode" "HI")])
644 (define_insn "*cmphi_minus_1"
645   [(set (reg FLAGS_REG)
646         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647                            (match_operand:HI 1 "general_operand" "ri,mr"))
648                  (const_int 0)))]
649   "ix86_match_ccmode (insn, CCGOCmode)"
650   "cmp{w}\t{%1, %0|%0, %1}"
651   [(set_attr "type" "icmp")
652    (set_attr "mode" "HI")])
654 (define_insn "*cmphi_1"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657                  (match_operand:HI 1 "general_operand" "ri,mr")))]
658   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659    && ix86_match_ccmode (insn, CCmode)"
660   "cmp{w}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "HI")])
664 (define_insn "*cmpqi_ccno_1"
665   [(set (reg FLAGS_REG)
666         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667                  (match_operand:QI 1 "const0_operand" "n,n")))]
668   "ix86_match_ccmode (insn, CCNOmode)"
669   "@
670    test{b}\t{%0, %0|%0, %0}
671    cmp{b}\t{$0, %0|%0, 0}"
672   [(set_attr "type" "test,icmp")
673    (set_attr "length_immediate" "0,1")
674    (set_attr "mode" "QI")])
676 (define_insn "*cmpqi_1"
677   [(set (reg FLAGS_REG)
678         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679                  (match_operand:QI 1 "general_operand" "qi,mq")))]
680   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681     && ix86_match_ccmode (insn, CCmode)"
682   "cmp{b}\t{%1, %0|%0, %1}"
683   [(set_attr "type" "icmp")
684    (set_attr "mode" "QI")])
686 (define_insn "*cmpqi_minus_1"
687   [(set (reg FLAGS_REG)
688         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689                            (match_operand:QI 1 "general_operand" "qi,mq"))
690                  (const_int 0)))]
691   "ix86_match_ccmode (insn, CCGOCmode)"
692   "cmp{b}\t{%1, %0|%0, %1}"
693   [(set_attr "type" "icmp")
694    (set_attr "mode" "QI")])
696 (define_insn "*cmpqi_ext_1"
697   [(set (reg FLAGS_REG)
698         (compare
699           (match_operand:QI 0 "general_operand" "Qm")
700           (subreg:QI
701             (zero_extract:SI
702               (match_operand 1 "ext_register_operand" "Q")
703               (const_int 8)
704               (const_int 8)) 0)))]
705   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%h1, %0|%0, %h1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_ext_1_rex64"
711   [(set (reg FLAGS_REG)
712         (compare
713           (match_operand:QI 0 "register_operand" "Q")
714           (subreg:QI
715             (zero_extract:SI
716               (match_operand 1 "ext_register_operand" "Q")
717               (const_int 8)
718               (const_int 8)) 0)))]
719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720   "cmp{b}\t{%h1, %0|%0, %h1}"
721   [(set_attr "type" "icmp")
722    (set_attr "mode" "QI")])
724 (define_insn "*cmpqi_ext_2"
725   [(set (reg FLAGS_REG)
726         (compare
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 0 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)
732           (match_operand:QI 1 "const0_operand" "n")))]
733   "ix86_match_ccmode (insn, CCNOmode)"
734   "test{b}\t%h0, %h0"
735   [(set_attr "type" "test")
736    (set_attr "length_immediate" "0")
737    (set_attr "mode" "QI")])
739 (define_expand "cmpqi_ext_3"
740   [(set (reg:CC FLAGS_REG)
741         (compare:CC
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "general_operand" "")))]
748   ""
749   "")
751 (define_insn "cmpqi_ext_3_insn"
752   [(set (reg FLAGS_REG)
753         (compare
754           (subreg:QI
755             (zero_extract:SI
756               (match_operand 0 "ext_register_operand" "Q")
757               (const_int 8)
758               (const_int 8)) 0)
759           (match_operand:QI 1 "general_operand" "Qmn")))]
760   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761   "cmp{b}\t{%1, %h0|%h0, %1}"
762   [(set_attr "type" "icmp")
763    (set_attr "mode" "QI")])
765 (define_insn "cmpqi_ext_3_insn_rex64"
766   [(set (reg FLAGS_REG)
767         (compare
768           (subreg:QI
769             (zero_extract:SI
770               (match_operand 0 "ext_register_operand" "Q")
771               (const_int 8)
772               (const_int 8)) 0)
773           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775   "cmp{b}\t{%1, %h0|%h0, %1}"
776   [(set_attr "type" "icmp")
777    (set_attr "mode" "QI")])
779 (define_insn "*cmpqi_ext_4"
780   [(set (reg FLAGS_REG)
781         (compare
782           (subreg:QI
783             (zero_extract:SI
784               (match_operand 0 "ext_register_operand" "Q")
785               (const_int 8)
786               (const_int 8)) 0)
787           (subreg:QI
788             (zero_extract:SI
789               (match_operand 1 "ext_register_operand" "Q")
790               (const_int 8)
791               (const_int 8)) 0)))]
792   "ix86_match_ccmode (insn, CCmode)"
793   "cmp{b}\t{%h1, %h0|%h0, %h1}"
794   [(set_attr "type" "icmp")
795    (set_attr "mode" "QI")])
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares.  Which is what
800 ;; the old patterns did, but with many more of them.
802 (define_expand "cmpxf"
803   [(set (reg:CC FLAGS_REG)
804         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805                     (match_operand:XF 1 "nonmemory_operand" "")))]
806   "TARGET_80387"
808   ix86_compare_op0 = operands[0];
809   ix86_compare_op1 = operands[1];
810   DONE;
813 (define_expand "cmpdf"
814   [(set (reg:CC FLAGS_REG)
815         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819   ix86_compare_op0 = operands[0];
820   ix86_compare_op1 = operands[1];
821   DONE;
824 (define_expand "cmpsf"
825   [(set (reg:CC FLAGS_REG)
826         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828   "TARGET_80387 || TARGET_SSE_MATH"
830   ix86_compare_op0 = operands[0];
831   ix86_compare_op1 = operands[1];
832   DONE;
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
838 ;; CCFPmode     compare with exceptions
839 ;; CCFPUmode    compare with no exceptions
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
844 (define_insn "*cmpfp_0"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand 1 "register_operand" "f")
849              (match_operand 2 "const0_operand" "X"))]
850         UNSPEC_FNSTSW))]
851   "TARGET_80387
852    && FLOAT_MODE_P (GET_MODE (operands[1]))
853    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854   "* return output_fp_compare (insn, operands, 0, 0);"
855   [(set_attr "type" "multi")
856    (set_attr "unit" "i387")
857    (set (attr "mode")
858      (cond [(match_operand:SF 1 "" "")
859               (const_string "SF")
860             (match_operand:DF 1 "" "")
861               (const_string "DF")
862            ]
863            (const_string "XF")))])
865 (define_insn "*cmpfp_sf"
866   [(set (match_operand:HI 0 "register_operand" "=a")
867         (unspec:HI
868           [(compare:CCFP
869              (match_operand:SF 1 "register_operand" "f")
870              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871           UNSPEC_FNSTSW))]
872   "TARGET_80387"
873   "* return output_fp_compare (insn, operands, 0, 0);"
874   [(set_attr "type" "multi")
875    (set_attr "unit" "i387")
876    (set_attr "mode" "SF")])
878 (define_insn "*cmpfp_df"
879   [(set (match_operand:HI 0 "register_operand" "=a")
880         (unspec:HI
881           [(compare:CCFP
882              (match_operand:DF 1 "register_operand" "f")
883              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884           UNSPEC_FNSTSW))]
885   "TARGET_80387"
886   "* return output_fp_compare (insn, operands, 0, 0);"
887   [(set_attr "type" "multi")
888    (set_attr "unit" "i387")
889    (set_attr "mode" "DF")])
891 (define_insn "*cmpfp_xf"
892   [(set (match_operand:HI 0 "register_operand" "=a")
893         (unspec:HI
894           [(compare:CCFP
895              (match_operand:XF 1 "register_operand" "f")
896              (match_operand:XF 2 "register_operand" "f"))]
897           UNSPEC_FNSTSW))]
898   "TARGET_80387"
899   "* return output_fp_compare (insn, operands, 0, 0);"
900   [(set_attr "type" "multi")
901    (set_attr "unit" "i387")
902    (set_attr "mode" "XF")])
904 (define_insn "*cmpfp_u"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFPU
908              (match_operand 1 "register_operand" "f")
909              (match_operand 2 "register_operand" "f"))]
910           UNSPEC_FNSTSW))]
911   "TARGET_80387
912    && FLOAT_MODE_P (GET_MODE (operands[1]))
913    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914   "* return output_fp_compare (insn, operands, 0, 1);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set (attr "mode")
918      (cond [(match_operand:SF 1 "" "")
919               (const_string "SF")
920             (match_operand:DF 1 "" "")
921               (const_string "DF")
922            ]
923            (const_string "XF")))])
925 (define_insn "*cmpfp_<mode>"
926   [(set (match_operand:HI 0 "register_operand" "=a")
927         (unspec:HI
928           [(compare:CCFP
929              (match_operand 1 "register_operand" "f")
930              (match_operator 3 "float_operator"
931                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
932           UNSPEC_FNSTSW))]
933   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934    && FLOAT_MODE_P (GET_MODE (operands[1]))
935    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936   "* return output_fp_compare (insn, operands, 0, 0);"
937   [(set_attr "type" "multi")
938    (set_attr "unit" "i387")
939    (set_attr "fp_int_src" "true")
940    (set_attr "mode" "<MODE>")])
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
945 (define_insn "x86_fnstsw_1"
946   [(set (match_operand:HI 0 "register_operand" "=a")
947         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948   "TARGET_80387"
949   "fnstsw\t%0"
950   [(set_attr "length" "2")
951    (set_attr "mode" "SI")
952    (set_attr "unit" "i387")])
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
957 (define_insn "x86_sahf_1"
958   [(set (reg:CC FLAGS_REG)
959         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960   "!TARGET_64BIT"
961   "sahf"
962   [(set_attr "length" "1")
963    (set_attr "athlon_decode" "vector")
964    (set_attr "mode" "SI")])
966 ;; Pentium Pro can do steps 1 through 3 in one go.
968 (define_insn "*cmpfp_i_mixed"
969   [(set (reg:CCFP FLAGS_REG)
970         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
972   "TARGET_MIX_SSE_I387
973    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975   "* return output_fp_compare (insn, operands, 1, 0);"
976   [(set_attr "type" "fcmp,ssecomi")
977    (set (attr "mode")
978      (if_then_else (match_operand:SF 1 "" "")
979         (const_string "SF")
980         (const_string "DF")))
981    (set_attr "athlon_decode" "vector")])
983 (define_insn "*cmpfp_i_sse"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "x")
986                       (match_operand 1 "nonimmediate_operand" "xm")))]
987   "TARGET_SSE_MATH
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
998 (define_insn "*cmpfp_i_i387"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "f")
1001                       (match_operand 1 "register_operand" "f")))]
1002   "TARGET_80387 && TARGET_CMOVE
1003    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004    && FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "fcmp")
1008    (set (attr "mode")
1009      (cond [(match_operand:SF 1 "" "")
1010               (const_string "SF")
1011             (match_operand:DF 1 "" "")
1012               (const_string "DF")
1013            ]
1014            (const_string "XF")))
1015    (set_attr "athlon_decode" "vector")])
1017 (define_insn "*cmpfp_iu_mixed"
1018   [(set (reg:CCFPU FLAGS_REG)
1019         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021   "TARGET_MIX_SSE_I387
1022    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 1);"
1025   [(set_attr "type" "fcmp,ssecomi")
1026    (set (attr "mode")
1027      (if_then_else (match_operand:SF 1 "" "")
1028         (const_string "SF")
1029         (const_string "DF")))
1030    (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu_sse"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "x")
1035                        (match_operand 1 "nonimmediate_operand" "xm")))]
1036   "TARGET_SSE_MATH
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_iu_387"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "f")
1050                        (match_operand 1 "register_operand" "f")))]
1051   "TARGET_80387 && TARGET_CMOVE
1052    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053    && FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "fcmp")
1057    (set (attr "mode")
1058      (cond [(match_operand:SF 1 "" "")
1059               (const_string "SF")
1060             (match_operand:DF 1 "" "")
1061               (const_string "DF")
1062            ]
1063            (const_string "XF")))
1064    (set_attr "athlon_decode" "vector")])
1066 ;; Move instructions.
1068 ;; General case of fullword move.
1070 (define_expand "movsi"
1071   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072         (match_operand:SI 1 "general_operand" ""))]
1073   ""
1074   "ix86_expand_move (SImode, operands); DONE;")
1076 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1077 ;; general_operand.
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1085 (define_insn "*pushsi2"
1086   [(set (match_operand:SI 0 "push_operand" "=<")
1087         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088   "!TARGET_64BIT"
1089   "push{l}\t%1"
1090   [(set_attr "type" "push")
1091    (set_attr "mode" "SI")])
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095   [(set (match_operand:SI 0 "push_operand" "=X")
1096         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097   "TARGET_64BIT"
1098   "push{q}\t%q1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1102 (define_insn "*pushsi2_prologue"
1103   [(set (match_operand:SI 0 "push_operand" "=<")
1104         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105    (clobber (mem:BLK (scratch)))]
1106   "!TARGET_64BIT"
1107   "push{l}\t%1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1111 (define_insn "*popsi1_epilogue"
1112   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113         (mem:SI (reg:SI SP_REG)))
1114    (set (reg:SI SP_REG)
1115         (plus:SI (reg:SI SP_REG) (const_int 4)))
1116    (clobber (mem:BLK (scratch)))]
1117   "!TARGET_64BIT"
1118   "pop{l}\t%0"
1119   [(set_attr "type" "pop")
1120    (set_attr "mode" "SI")])
1122 (define_insn "popsi1"
1123   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124         (mem:SI (reg:SI SP_REG)))
1125    (set (reg:SI SP_REG)
1126         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127   "!TARGET_64BIT"
1128   "pop{l}\t%0"
1129   [(set_attr "type" "pop")
1130    (set_attr "mode" "SI")])
1132 (define_insn "*movsi_xor"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (match_operand:SI 1 "const0_operand" "i"))
1135    (clobber (reg:CC FLAGS_REG))]
1136   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137   "xor{l}\t{%0, %0|%0, %0}"
1138   [(set_attr "type" "alu1")
1139    (set_attr "mode" "SI")
1140    (set_attr "length_immediate" "0")])
1142 (define_insn "*movsi_or"
1143   [(set (match_operand:SI 0 "register_operand" "=r")
1144         (match_operand:SI 1 "immediate_operand" "i"))
1145    (clobber (reg:CC FLAGS_REG))]
1146   "reload_completed
1147    && operands[1] == constm1_rtx
1148    && (TARGET_PENTIUM || optimize_size)"
1150   operands[1] = constm1_rtx;
1151   return "or{l}\t{%1, %0|%0, %1}";
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "1")])
1157 (define_insn "*movsi_1"
1158   [(set (match_operand:SI 0 "nonimmediate_operand"
1159                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160         (match_operand:SI 1 "general_operand"
1161                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1162   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164   switch (get_attr_type (insn))
1165     {
1166     case TYPE_SSELOG1:
1167       if (get_attr_mode (insn) == MODE_TI)
1168         return "pxor\t%0, %0";
1169       return "xorps\t%0, %0";
1171     case TYPE_SSEMOV:
1172       switch (get_attr_mode (insn))
1173         {
1174         case MODE_TI:
1175           return "movdqa\t{%1, %0|%0, %1}";
1176         case MODE_V4SF:
1177           return "movaps\t{%1, %0|%0, %1}";
1178         case MODE_SI:
1179           return "movd\t{%1, %0|%0, %1}";
1180         case MODE_SF:
1181           return "movss\t{%1, %0|%0, %1}";
1182         default:
1183           gcc_unreachable ();
1184         }
1186     case TYPE_MMXADD:
1187       return "pxor\t%0, %0";
1189     case TYPE_MMXMOV:
1190       if (get_attr_mode (insn) == MODE_DI)
1191         return "movq\t{%1, %0|%0, %1}";
1192       return "movd\t{%1, %0|%0, %1}";
1194     case TYPE_LEA:
1195       return "lea{l}\t{%1, %0|%0, %1}";
1197     default:
1198       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199       return "mov{l}\t{%1, %0|%0, %1}";
1200     }
1202   [(set (attr "type")
1203      (cond [(eq_attr "alternative" "2")
1204               (const_string "mmxadd")
1205             (eq_attr "alternative" "3,4,5")
1206               (const_string "mmxmov")
1207             (eq_attr "alternative" "6")
1208               (const_string "sselog1")
1209             (eq_attr "alternative" "7,8,9,10,11")
1210               (const_string "ssemov")
1211             (match_operand:DI 1 "pic_32bit_operand" "")
1212               (const_string "lea")
1213            ]
1214            (const_string "imov")))
1215    (set (attr "mode")
1216      (cond [(eq_attr "alternative" "2,3")
1217               (const_string "DI")
1218             (eq_attr "alternative" "6,7")
1219               (if_then_else
1220                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221                 (const_string "V4SF")
1222                 (const_string "TI"))
1223             (and (eq_attr "alternative" "8,9,10,11")
1224                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225               (const_string "SF")
1226            ]
1227            (const_string "SI")))])
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1236   "@
1237    movabs{l}\t{%1, %P0|%P0, %1}
1238    mov{l}\t{%1, %a0|%a0, %1}"
1239   [(set_attr "type" "imov")
1240    (set_attr "modrm" "0,*")
1241    (set_attr "length_address" "8,0")
1242    (set_attr "length_immediate" "0,*")
1243    (set_attr "memory" "store")
1244    (set_attr "mode" "SI")])
1246 (define_insn "*movabssi_2_rex64"
1247   [(set (match_operand:SI 0 "register_operand" "=a,r")
1248         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1250   "@
1251    movabs{l}\t{%P1, %0|%0, %P1}
1252    mov{l}\t{%a1, %0|%0, %a1}"
1253   [(set_attr "type" "imov")
1254    (set_attr "modrm" "0,*")
1255    (set_attr "length_address" "8,0")
1256    (set_attr "length_immediate" "0")
1257    (set_attr "memory" "load")
1258    (set_attr "mode" "SI")])
1260 (define_insn "*swapsi"
1261   [(set (match_operand:SI 0 "register_operand" "+r")
1262         (match_operand:SI 1 "register_operand" "+r"))
1263    (set (match_dup 1)
1264         (match_dup 0))]
1265   ""
1266   "xchg{l}\t%1, %0"
1267   [(set_attr "type" "imov")
1268    (set_attr "mode" "SI")
1269    (set_attr "pent_pair" "np")
1270    (set_attr "athlon_decode" "vector")])
1272 (define_expand "movhi"
1273   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274         (match_operand:HI 1 "general_operand" ""))]
1275   ""
1276   "ix86_expand_move (HImode, operands); DONE;")
1278 (define_insn "*pushhi2"
1279   [(set (match_operand:HI 0 "push_operand" "=X")
1280         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281   "!TARGET_64BIT"
1282   "push{l}\t%k1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "SI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "DI")])
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444   "!TARGET_64BIT"
1445   "push{l}\t%k1"
1446   [(set_attr "type" "push")
1447    (set_attr "mode" "SI")])
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453   "TARGET_64BIT"
1454   "push{q}\t%q1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "DI")])
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; instruction).
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there.  Then we use movzx.
1468 (define_insn "*movqi_1"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1471   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473   switch (get_attr_type (insn))
1474     {
1475     case TYPE_IMOVX:
1476       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478     default:
1479       if (get_attr_mode (insn) == MODE_SI)
1480         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481       else
1482         return "mov{b}\t{%1, %0|%0, %1}";
1483     }
1485   [(set (attr "type")
1486      (cond [(and (eq_attr "alternative" "5")
1487                  (not (match_operand:QI 1 "aligned_operand" "")))
1488               (const_string "imovx")
1489             (ne (symbol_ref "optimize_size") (const_int 0))
1490               (const_string "imov")
1491             (and (eq_attr "alternative" "3")
1492                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1493                           (const_int 0))
1494                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1495                           (const_int 0))))
1496               (const_string "imov")
1497             (eq_attr "alternative" "3,5")
1498               (const_string "imovx")
1499             (and (ne (symbol_ref "TARGET_MOVX")
1500                      (const_int 0))
1501                  (eq_attr "alternative" "2"))
1502               (const_string "imovx")
1503            ]
1504            (const_string "imov")))
1505    (set (attr "mode")
1506       (cond [(eq_attr "alternative" "3,4,5")
1507                (const_string "SI")
1508              (eq_attr "alternative" "6")
1509                (const_string "QI")
1510              (eq_attr "type" "imovx")
1511                (const_string "SI")
1512              (and (eq_attr "type" "imov")
1513                   (and (eq_attr "alternative" "0,1")
1514                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515                                 (const_int 0))
1516                             (and (eq (symbol_ref "optimize_size")
1517                                      (const_int 0))
1518                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519                                      (const_int 0))))))
1520                (const_string "SI")
1521              ;; Avoid partial register stalls when not using QImode arithmetic
1522              (and (eq_attr "type" "imov")
1523                   (and (eq_attr "alternative" "0,1")
1524                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525                                 (const_int 0))
1526                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1527                                 (const_int 0)))))
1528                (const_string "SI")
1529            ]
1530            (const_string "QI")))])
1532 (define_expand "reload_outqi"
1533   [(parallel [(match_operand:QI 0 "" "=m")
1534               (match_operand:QI 1 "register_operand" "r")
1535               (match_operand:QI 2 "register_operand" "=&q")])]
1536   ""
1538   rtx op0, op1, op2;
1539   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542   if (! q_regs_operand (op1, QImode))
1543     {
1544       emit_insn (gen_movqi (op2, op1));
1545       op1 = op2;
1546     }
1547   emit_insn (gen_movqi (op0, op1));
1548   DONE;
1551 (define_insn "*swapqi_1"
1552   [(set (match_operand:QI 0 "register_operand" "+r")
1553         (match_operand:QI 1 "register_operand" "+r"))
1554    (set (match_dup 1)
1555         (match_dup 0))]
1556   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1557   "xchg{l}\t%k1, %k0"
1558   [(set_attr "type" "imov")
1559    (set_attr "mode" "SI")
1560    (set_attr "pent_pair" "np")
1561    (set_attr "athlon_decode" "vector")])
1563 (define_insn "*swapqi_2"
1564   [(set (match_operand:QI 0 "register_operand" "+q")
1565         (match_operand:QI 1 "register_operand" "+q"))
1566    (set (match_dup 1)
1567         (match_dup 0))]
1568   "TARGET_PARTIAL_REG_STALL"
1569   "xchg{b}\t%1, %0"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "QI")
1572    (set_attr "pent_pair" "np")
1573    (set_attr "athlon_decode" "vector")])
1575 (define_expand "movstrictqi"
1576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577         (match_operand:QI 1 "general_operand" ""))]
1578   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580   /* Don't generate memory->memory moves, go through a register.  */
1581   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582     operands[1] = force_reg (QImode, operands[1]);
1585 (define_insn "*movstrictqi_1"
1586   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587         (match_operand:QI 1 "general_operand" "*qn,m"))]
1588   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590   "mov{b}\t{%1, %0|%0, %1}"
1591   [(set_attr "type" "imov")
1592    (set_attr "mode" "QI")])
1594 (define_insn "*movstrictqi_xor"
1595   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596         (match_operand:QI 1 "const0_operand" "i"))
1597    (clobber (reg:CC FLAGS_REG))]
1598   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599   "xor{b}\t{%0, %0|%0, %0}"
1600   [(set_attr "type" "alu1")
1601    (set_attr "mode" "QI")
1602    (set_attr "length_immediate" "0")])
1604 (define_insn "*movsi_extv_1"
1605   [(set (match_operand:SI 0 "register_operand" "=R")
1606         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607                          (const_int 8)
1608                          (const_int 8)))]
1609   ""
1610   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611   [(set_attr "type" "imovx")
1612    (set_attr "mode" "SI")])
1614 (define_insn "*movhi_extv_1"
1615   [(set (match_operand:HI 0 "register_operand" "=R")
1616         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   ""
1620   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621   [(set_attr "type" "imovx")
1622    (set_attr "mode" "SI")])
1624 (define_insn "*movqi_extv_1"
1625   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   "!TARGET_64BIT"
1631   switch (get_attr_type (insn))
1632     {
1633     case TYPE_IMOVX:
1634       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1635     default:
1636       return "mov{b}\t{%h1, %0|%0, %h1}";
1637     }
1639   [(set (attr "type")
1640      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642                              (ne (symbol_ref "TARGET_MOVX")
1643                                  (const_int 0))))
1644         (const_string "imovx")
1645         (const_string "imov")))
1646    (set (attr "mode")
1647      (if_then_else (eq_attr "type" "imovx")
1648         (const_string "SI")
1649         (const_string "QI")))])
1651 (define_insn "*movqi_extv_1_rex64"
1652   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654                          (const_int 8)
1655                          (const_int 8)))]
1656   "TARGET_64BIT"
1658   switch (get_attr_type (insn))
1659     {
1660     case TYPE_IMOVX:
1661       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662     default:
1663       return "mov{b}\t{%h1, %0|%0, %h1}";
1664     }
1666   [(set (attr "type")
1667      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669                              (ne (symbol_ref "TARGET_MOVX")
1670                                  (const_int 0))))
1671         (const_string "imovx")
1672         (const_string "imov")))
1673    (set (attr "mode")
1674      (if_then_else (eq_attr "type" "imovx")
1675         (const_string "SI")
1676         (const_string "QI")))])
1678 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1685   "@
1686    movabs{b}\t{%1, %P0|%P0, %1}
1687    mov{b}\t{%1, %a0|%a0, %1}"
1688   [(set_attr "type" "imov")
1689    (set_attr "modrm" "0,*")
1690    (set_attr "length_address" "8,0")
1691    (set_attr "length_immediate" "0,*")
1692    (set_attr "memory" "store")
1693    (set_attr "mode" "QI")])
1695 (define_insn "*movabsqi_2_rex64"
1696   [(set (match_operand:QI 0 "register_operand" "=a,r")
1697         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1699   "@
1700    movabs{b}\t{%P1, %0|%0, %P1}
1701    mov{b}\t{%a1, %0|%0, %a1}"
1702   [(set_attr "type" "imov")
1703    (set_attr "modrm" "0,*")
1704    (set_attr "length_address" "8,0")
1705    (set_attr "length_immediate" "0")
1706    (set_attr "memory" "load")
1707    (set_attr "mode" "QI")])
1709 (define_insn "*movdi_extzv_1"
1710   [(set (match_operand:DI 0 "register_operand" "=R")
1711         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712                          (const_int 8)
1713                          (const_int 8)))]
1714   "TARGET_64BIT"
1715   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716   [(set_attr "type" "imovx")
1717    (set_attr "mode" "DI")])
1719 (define_insn "*movsi_extzv_1"
1720   [(set (match_operand:SI 0 "register_operand" "=R")
1721         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722                          (const_int 8)
1723                          (const_int 8)))]
1724   ""
1725   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726   [(set_attr "type" "imovx")
1727    (set_attr "mode" "SI")])
1729 (define_insn "*movqi_extzv_2"
1730   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732                                     (const_int 8)
1733                                     (const_int 8)) 0))]
1734   "!TARGET_64BIT"
1736   switch (get_attr_type (insn))
1737     {
1738     case TYPE_IMOVX:
1739       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1740     default:
1741       return "mov{b}\t{%h1, %0|%0, %h1}";
1742     }
1744   [(set (attr "type")
1745      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747                              (ne (symbol_ref "TARGET_MOVX")
1748                                  (const_int 0))))
1749         (const_string "imovx")
1750         (const_string "imov")))
1751    (set (attr "mode")
1752      (if_then_else (eq_attr "type" "imovx")
1753         (const_string "SI")
1754         (const_string "QI")))])
1756 (define_insn "*movqi_extzv_2_rex64"
1757   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759                                     (const_int 8)
1760                                     (const_int 8)) 0))]
1761   "TARGET_64BIT"
1763   switch (get_attr_type (insn))
1764     {
1765     case TYPE_IMOVX:
1766       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767     default:
1768       return "mov{b}\t{%h1, %0|%0, %h1}";
1769     }
1771   [(set (attr "type")
1772      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773                         (ne (symbol_ref "TARGET_MOVX")
1774                             (const_int 0)))
1775         (const_string "imovx")
1776         (const_string "imov")))
1777    (set (attr "mode")
1778      (if_then_else (eq_attr "type" "imovx")
1779         (const_string "SI")
1780         (const_string "QI")))])
1782 (define_insn "movsi_insv_1"
1783   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784                          (const_int 8)
1785                          (const_int 8))
1786         (match_operand:SI 1 "general_operand" "Qmn"))]
1787   "!TARGET_64BIT"
1788   "mov{b}\t{%b1, %h0|%h0, %b1}"
1789   [(set_attr "type" "imov")
1790    (set_attr "mode" "QI")])
1792 (define_insn "movdi_insv_1_rex64"
1793   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794                          (const_int 8)
1795                          (const_int 8))
1796         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1797   "TARGET_64BIT"
1798   "mov{b}\t{%b1, %h0|%h0, %b1}"
1799   [(set_attr "type" "imov")
1800    (set_attr "mode" "QI")])
1802 (define_insn "*movqi_insv_2"
1803   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804                          (const_int 8)
1805                          (const_int 8))
1806         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807                      (const_int 8)))]
1808   ""
1809   "mov{b}\t{%h1, %h0|%h0, %h1}"
1810   [(set_attr "type" "imov")
1811    (set_attr "mode" "QI")])
1813 (define_expand "movdi"
1814   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815         (match_operand:DI 1 "general_operand" ""))]
1816   ""
1817   "ix86_expand_move (DImode, operands); DONE;")
1819 (define_insn "*pushdi"
1820   [(set (match_operand:DI 0 "push_operand" "=<")
1821         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822   "!TARGET_64BIT"
1823   "#")
1825 (define_insn "*pushdi2_rex64"
1826   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828   "TARGET_64BIT"
1829   "@
1830    push{q}\t%1
1831    #"
1832   [(set_attr "type" "push,multi")
1833    (set_attr "mode" "DI")])
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it.  In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1839 (define_peephole2
1840   [(match_scratch:DI 2 "r")
1841    (set (match_operand:DI 0 "push_operand" "")
1842         (match_operand:DI 1 "immediate_operand" ""))]
1843   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844    && !x86_64_immediate_operand (operands[1], DImode)"
1845   [(set (match_dup 2) (match_dup 1))
1846    (set (match_dup 0) (match_dup 2))]
1847   "")
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1852 (define_peephole2
1853   [(set (match_operand:DI 0 "push_operand" "")
1854         (match_operand:DI 1 "immediate_operand" ""))]
1855   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857   [(set (match_dup 0) (match_dup 1))
1858    (set (match_dup 2) (match_dup 3))]
1859   "split_di (operands + 1, 1, operands + 2, operands + 3);
1860    operands[1] = gen_lowpart (DImode, operands[2]);
1861    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862                                                     GEN_INT (4)));
1863   ")
1865 (define_split
1866   [(set (match_operand:DI 0 "push_operand" "")
1867         (match_operand:DI 1 "immediate_operand" ""))]
1868   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869                     ? flow2_completed : reload_completed)
1870    && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 0) (match_dup 1))
1873    (set (match_dup 2) (match_dup 3))]
1874   "split_di (operands + 1, 1, operands + 2, operands + 3);
1875    operands[1] = gen_lowpart (DImode, operands[2]);
1876    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877                                                     GEN_INT (4)));
1878   ")
1880 (define_insn "*pushdi2_prologue_rex64"
1881   [(set (match_operand:DI 0 "push_operand" "=<")
1882         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883    (clobber (mem:BLK (scratch)))]
1884   "TARGET_64BIT"
1885   "push{q}\t%1"
1886   [(set_attr "type" "push")
1887    (set_attr "mode" "DI")])
1889 (define_insn "*popdi1_epilogue_rex64"
1890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891         (mem:DI (reg:DI SP_REG)))
1892    (set (reg:DI SP_REG)
1893         (plus:DI (reg:DI SP_REG) (const_int 8)))
1894    (clobber (mem:BLK (scratch)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1900 (define_insn "popdi1"
1901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902         (mem:DI (reg:DI SP_REG)))
1903    (set (reg:DI SP_REG)
1904         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905   "TARGET_64BIT"
1906   "pop{q}\t%0"
1907   [(set_attr "type" "pop")
1908    (set_attr "mode" "DI")])
1910 (define_insn "*movdi_xor_rex64"
1911   [(set (match_operand:DI 0 "register_operand" "=r")
1912         (match_operand:DI 1 "const0_operand" "i"))
1913    (clobber (reg:CC FLAGS_REG))]
1914   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915    && reload_completed"
1916   "xor{l}\t{%k0, %k0|%k0, %k0}"
1917   [(set_attr "type" "alu1")
1918    (set_attr "mode" "SI")
1919    (set_attr "length_immediate" "0")])
1921 (define_insn "*movdi_or_rex64"
1922   [(set (match_operand:DI 0 "register_operand" "=r")
1923         (match_operand:DI 1 "const_int_operand" "i"))
1924    (clobber (reg:CC FLAGS_REG))]
1925   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926    && reload_completed
1927    && operands[1] == constm1_rtx"
1929   operands[1] = constm1_rtx;
1930   return "or{q}\t{%1, %0|%0, %1}";
1932   [(set_attr "type" "alu1")
1933    (set_attr "mode" "DI")
1934    (set_attr "length_immediate" "1")])
1936 (define_insn "*movdi_2"
1937   [(set (match_operand:DI 0 "nonimmediate_operand"
1938                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939         (match_operand:DI 1 "general_operand"
1940                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942   "@
1943    #
1944    #
1945    pxor\t%0, %0
1946    movq\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    pxor\t%0, %0
1949    movq\t{%1, %0|%0, %1}
1950    movdqa\t{%1, %0|%0, %1}
1951    movq\t{%1, %0|%0, %1}
1952    xorps\t%0, %0
1953    movlps\t{%1, %0|%0, %1}
1954    movaps\t{%1, %0|%0, %1}
1955    movlps\t{%1, %0|%0, %1}"
1956   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1959 (define_split
1960   [(set (match_operand:DI 0 "push_operand" "")
1961         (match_operand:DI 1 "general_operand" ""))]
1962   "!TARGET_64BIT && reload_completed
1963    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1967 ;; %%% This multiword shite has got to go.
1968 (define_split
1969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974   [(const_int 0)]
1975   "ix86_split_long_move (operands); DONE;")
1977 (define_insn "*movdi_1_rex64"
1978   [(set (match_operand:DI 0 "nonimmediate_operand"
1979                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980         (match_operand:DI 1 "general_operand"
1981                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984   switch (get_attr_type (insn))
1985     {
1986     case TYPE_SSECVT:
1987       if (which_alternative == 13)
1988         return "movq2dq\t{%1, %0|%0, %1}";
1989       else
1990         return "movdq2q\t{%1, %0|%0, %1}";
1991     case TYPE_SSEMOV:
1992       if (get_attr_mode (insn) == MODE_TI)
1993           return "movdqa\t{%1, %0|%0, %1}";
1994       /* FALLTHRU */
1995     case TYPE_MMXMOV:
1996       /* Moves from and into integer register is done using movd opcode with
1997          REX prefix.  */
1998       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999           return "movd\t{%1, %0|%0, %1}";
2000       return "movq\t{%1, %0|%0, %1}";
2001     case TYPE_SSELOG1:
2002     case TYPE_MMXADD:
2003       return "pxor\t%0, %0";
2004     case TYPE_MULTI:
2005       return "#";
2006     case TYPE_LEA:
2007       return "lea{q}\t{%a1, %0|%0, %a1}";
2008     default:
2009       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010       if (get_attr_mode (insn) == MODE_SI)
2011         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012       else if (which_alternative == 2)
2013         return "movabs{q}\t{%1, %0|%0, %1}";
2014       else
2015         return "mov{q}\t{%1, %0|%0, %1}";
2016     }
2018   [(set (attr "type")
2019      (cond [(eq_attr "alternative" "5")
2020               (const_string "mmxadd")
2021             (eq_attr "alternative" "6,7,8")
2022               (const_string "mmxmov")
2023             (eq_attr "alternative" "9")
2024               (const_string "sselog1")
2025             (eq_attr "alternative" "10,11,12")
2026               (const_string "ssemov")
2027             (eq_attr "alternative" "13,14")
2028               (const_string "ssecvt")
2029             (eq_attr "alternative" "4")
2030               (const_string "multi")
2031             (match_operand:DI 1 "pic_32bit_operand" "")
2032               (const_string "lea")
2033            ]
2034            (const_string "imov")))
2035    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046   "@
2047    movabs{q}\t{%1, %P0|%P0, %1}
2048    mov{q}\t{%1, %a0|%a0, %1}"
2049   [(set_attr "type" "imov")
2050    (set_attr "modrm" "0,*")
2051    (set_attr "length_address" "8,0")
2052    (set_attr "length_immediate" "0,*")
2053    (set_attr "memory" "store")
2054    (set_attr "mode" "DI")])
2056 (define_insn "*movabsdi_2_rex64"
2057   [(set (match_operand:DI 0 "register_operand" "=a,r")
2058         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060   "@
2061    movabs{q}\t{%P1, %0|%0, %P1}
2062    mov{q}\t{%a1, %0|%0, %a1}"
2063   [(set_attr "type" "imov")
2064    (set_attr "modrm" "0,*")
2065    (set_attr "length_address" "8,0")
2066    (set_attr "length_immediate" "0")
2067    (set_attr "memory" "load")
2068    (set_attr "mode" "DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it.  In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "memory_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))]
2081   "")
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 (define_peephole2
2087   [(set (match_operand:DI 0 "memory_operand" "")
2088         (match_operand:DI 1 "immediate_operand" ""))]
2089   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2095 (define_split
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099                     ? flow2_completed : reload_completed)
2100    && !symbolic_operand (operands[1], DImode)
2101    && !x86_64_immediate_operand (operands[1], DImode)"
2102   [(set (match_dup 2) (match_dup 3))
2103    (set (match_dup 4) (match_dup 5))]
2104   "split_di (operands, 2, operands + 2, operands + 4);")
2106 (define_insn "*swapdi_rex64"
2107   [(set (match_operand:DI 0 "register_operand" "+r")
2108         (match_operand:DI 1 "register_operand" "+r"))
2109    (set (match_dup 1)
2110         (match_dup 0))]
2111   "TARGET_64BIT"
2112   "xchg{q}\t%1, %0"
2113   [(set_attr "type" "imov")
2114    (set_attr "mode" "DI")
2115    (set_attr "pent_pair" "np")
2116    (set_attr "athlon_decode" "vector")])
2118 (define_expand "movti"
2119   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120         (match_operand:TI 1 "nonimmediate_operand" ""))]
2121   "TARGET_SSE || TARGET_64BIT"
2123   if (TARGET_64BIT)
2124     ix86_expand_move (TImode, operands);
2125   else
2126     ix86_expand_vector_move (TImode, operands);
2127   DONE;
2130 (define_insn "*movti_internal"
2131   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133   "TARGET_SSE && !TARGET_64BIT
2134    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136   switch (which_alternative)
2137     {
2138     case 0:
2139       if (get_attr_mode (insn) == MODE_V4SF)
2140         return "xorps\t%0, %0";
2141       else
2142         return "pxor\t%0, %0";
2143     case 1:
2144     case 2:
2145       if (get_attr_mode (insn) == MODE_V4SF)
2146         return "movaps\t{%1, %0|%0, %1}";
2147       else
2148         return "movdqa\t{%1, %0|%0, %1}";
2149     default:
2150       gcc_unreachable ();
2151     }
2153   [(set_attr "type" "sselog1,ssemov,ssemov")
2154    (set (attr "mode")
2155         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156                     (ne (symbol_ref "optimize_size") (const_int 0)))
2157                  (const_string "V4SF")
2158                (and (eq_attr "alternative" "2")
2159                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2160                         (const_int 0)))
2161                  (const_string "V4SF")]
2162               (const_string "TI")))])
2164 (define_insn "*movti_rex64"
2165   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167   "TARGET_64BIT
2168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170   switch (which_alternative)
2171     {
2172     case 0:
2173     case 1:
2174       return "#";
2175     case 2:
2176       if (get_attr_mode (insn) == MODE_V4SF)
2177         return "xorps\t%0, %0";
2178       else
2179         return "pxor\t%0, %0";
2180     case 3:
2181     case 4:
2182       if (get_attr_mode (insn) == MODE_V4SF)
2183         return "movaps\t{%1, %0|%0, %1}";
2184       else
2185         return "movdqa\t{%1, %0|%0, %1}";
2186     default:
2187       gcc_unreachable ();
2188     }
2190   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2191    (set (attr "mode")
2192         (cond [(eq_attr "alternative" "2,3")
2193                  (if_then_else
2194                    (ne (symbol_ref "optimize_size")
2195                        (const_int 0))
2196                    (const_string "V4SF")
2197                    (const_string "TI"))
2198                (eq_attr "alternative" "4")
2199                  (if_then_else
2200                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201                             (const_int 0))
2202                         (ne (symbol_ref "optimize_size")
2203                             (const_int 0)))
2204                    (const_string "V4SF")
2205                    (const_string "TI"))]
2206                (const_string "DI")))])
2208 (define_split
2209   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210         (match_operand:TI 1 "general_operand" ""))]
2211   "reload_completed && !SSE_REG_P (operands[0])
2212    && !SSE_REG_P (operands[1])"
2213   [(const_int 0)]
2214   "ix86_split_long_move (operands); DONE;")
2216 (define_expand "movsf"
2217   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218         (match_operand:SF 1 "general_operand" ""))]
2219   ""
2220   "ix86_expand_move (SFmode, operands); DONE;")
2222 (define_insn "*pushsf"
2223   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2225   "!TARGET_64BIT"
2227   /* Anything else should be already split before reg-stack.  */
2228   gcc_assert (which_alternative == 1);
2229   return "push{l}\t%1";
2231   [(set_attr "type" "multi,push,multi")
2232    (set_attr "unit" "i387,*,*")
2233    (set_attr "mode" "SF,SI,SF")])
2235 (define_insn "*pushsf_rex64"
2236   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2238   "TARGET_64BIT"
2240   /* Anything else should be already split before reg-stack.  */
2241   gcc_assert (which_alternative == 1);
2242   return "push{q}\t%q1";
2244   [(set_attr "type" "multi,push,multi")
2245    (set_attr "unit" "i387,*,*")
2246    (set_attr "mode" "SF,DI,SF")])
2248 (define_split
2249   [(set (match_operand:SF 0 "push_operand" "")
2250         (match_operand:SF 1 "memory_operand" ""))]
2251   "reload_completed
2252    && GET_CODE (operands[1]) == MEM
2253    && constant_pool_reference_p (operands[1])"
2254   [(set (match_dup 0)
2255         (match_dup 1))]
2256   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2259 ;; %%% Kill this when call knows how to work this out.
2260 (define_split
2261   [(set (match_operand:SF 0 "push_operand" "")
2262         (match_operand:SF 1 "any_fp_register_operand" ""))]
2263   "!TARGET_64BIT"
2264   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2267 (define_split
2268   [(set (match_operand:SF 0 "push_operand" "")
2269         (match_operand:SF 1 "any_fp_register_operand" ""))]
2270   "TARGET_64BIT"
2271   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274 (define_insn "*movsf_1"
2275   [(set (match_operand:SF 0 "nonimmediate_operand"
2276           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2277         (match_operand:SF 1 "general_operand"
2278           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2279   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280    && (reload_in_progress || reload_completed
2281        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282        || GET_CODE (operands[1]) != CONST_DOUBLE
2283        || memory_operand (operands[0], SFmode))" 
2285   switch (which_alternative)
2286     {
2287     case 0:
2288       return output_387_reg_move (insn, operands);
2290     case 1:
2291       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292         return "fstp%z0\t%y0";
2293       else
2294         return "fst%z0\t%y0";
2296     case 2:
2297       return standard_80387_constant_opcode (operands[1]);
2299     case 3:
2300     case 4:
2301       return "mov{l}\t{%1, %0|%0, %1}";
2302     case 5:
2303       if (get_attr_mode (insn) == MODE_TI)
2304         return "pxor\t%0, %0";
2305       else
2306         return "xorps\t%0, %0";
2307     case 6:
2308       if (get_attr_mode (insn) == MODE_V4SF)
2309         return "movaps\t{%1, %0|%0, %1}";
2310       else
2311         return "movss\t{%1, %0|%0, %1}";
2312     case 7:
2313     case 8:
2314       return "movss\t{%1, %0|%0, %1}";
2316     case 9:
2317     case 10:
2318       return "movd\t{%1, %0|%0, %1}";
2320     case 11:
2321       return "movq\t{%1, %0|%0, %1}";
2323     default:
2324       gcc_unreachable ();
2325     }
2327   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2328    (set (attr "mode")
2329         (cond [(eq_attr "alternative" "3,4,9,10")
2330                  (const_string "SI")
2331                (eq_attr "alternative" "5")
2332                  (if_then_else
2333                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2334                                  (const_int 0))
2335                              (ne (symbol_ref "TARGET_SSE2")
2336                                  (const_int 0)))
2337                         (eq (symbol_ref "optimize_size")
2338                             (const_int 0)))
2339                    (const_string "TI")
2340                    (const_string "V4SF"))
2341                /* For architectures resolving dependencies on
2342                   whole SSE registers use APS move to break dependency
2343                   chains, otherwise use short move to avoid extra work. 
2345                   Do the same for architectures resolving dependencies on
2346                   the parts.  While in DF mode it is better to always handle
2347                   just register parts, the SF mode is different due to lack
2348                   of instructions to load just part of the register.  It is
2349                   better to maintain the whole registers in single format
2350                   to avoid problems on using packed logical operations.  */
2351                (eq_attr "alternative" "6")
2352                  (if_then_else
2353                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2354                             (const_int 0))
2355                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2356                             (const_int 0)))
2357                    (const_string "V4SF")
2358                    (const_string "SF"))
2359                (eq_attr "alternative" "11")
2360                  (const_string "DI")]
2361                (const_string "SF")))])
2363 (define_insn "*swapsf"
2364   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365         (match_operand:SF 1 "fp_register_operand" "+f"))
2366    (set (match_dup 1)
2367         (match_dup 0))]
2368   "reload_completed || TARGET_80387"
2370   if (STACK_TOP_P (operands[0]))
2371     return "fxch\t%1";
2372   else
2373     return "fxch\t%0";
2375   [(set_attr "type" "fxch")
2376    (set_attr "mode" "SF")])
2378 (define_expand "movdf"
2379   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380         (match_operand:DF 1 "general_operand" ""))]
2381   ""
2382   "ix86_expand_move (DFmode, operands); DONE;")
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter.  Allow this
2387 ;; pattern for optimize_size too.
2389 (define_insn "*pushdf_nointeger"
2390   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394   /* This insn should be already split before reg-stack.  */
2395   gcc_unreachable ();
2397   [(set_attr "type" "multi")
2398    (set_attr "unit" "i387,*,*,*")
2399    (set_attr "mode" "DF,SI,SI,DF")])
2401 (define_insn "*pushdf_integer"
2402   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406   /* This insn should be already split before reg-stack.  */
2407   gcc_unreachable ();
2409   [(set_attr "type" "multi")
2410    (set_attr "unit" "i387,*,*")
2411    (set_attr "mode" "DF,SI,DF")])
2413 ;; %%% Kill this when call knows how to work this out.
2414 (define_split
2415   [(set (match_operand:DF 0 "push_operand" "")
2416         (match_operand:DF 1 "any_fp_register_operand" ""))]
2417   "!TARGET_64BIT && reload_completed"
2418   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2420   "")
2422 (define_split
2423   [(set (match_operand:DF 0 "push_operand" "")
2424         (match_operand:DF 1 "any_fp_register_operand" ""))]
2425   "TARGET_64BIT && reload_completed"
2426   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2428   "")
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "general_operand" ""))]
2433   "reload_completed"
2434   [(const_int 0)]
2435   "ix86_split_long_move (operands); DONE;")
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2441 (define_insn "*movdf_nointeger"
2442   [(set (match_operand:DF 0 "nonimmediate_operand"
2443                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2444         (match_operand:DF 1 "general_operand"
2445                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2446   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448    && (reload_in_progress || reload_completed
2449        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450        || GET_CODE (operands[1]) != CONST_DOUBLE
2451        || memory_operand (operands[0], DFmode))" 
2453   switch (which_alternative)
2454     {
2455     case 0:
2456       return output_387_reg_move (insn, operands);
2458     case 1:
2459       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460         return "fstp%z0\t%y0";
2461       else
2462         return "fst%z0\t%y0";
2464     case 2:
2465       return standard_80387_constant_opcode (operands[1]);
2467     case 3:
2468     case 4:
2469       return "#";
2470     case 5:
2471       switch (get_attr_mode (insn))
2472         {
2473         case MODE_V4SF:
2474           return "xorps\t%0, %0";
2475         case MODE_V2DF:
2476           return "xorpd\t%0, %0";
2477         case MODE_TI:
2478           return "pxor\t%0, %0";
2479         default:
2480           gcc_unreachable ();
2481         }
2482     case 6:
2483     case 7:
2484     case 8:
2485       switch (get_attr_mode (insn))
2486         {
2487         case MODE_V4SF:
2488           return "movaps\t{%1, %0|%0, %1}";
2489         case MODE_V2DF:
2490           return "movapd\t{%1, %0|%0, %1}";
2491         case MODE_TI:
2492           return "movdqa\t{%1, %0|%0, %1}";
2493         case MODE_DI:
2494           return "movq\t{%1, %0|%0, %1}";
2495         case MODE_DF:
2496           return "movsd\t{%1, %0|%0, %1}";
2497         case MODE_V1DF:
2498           return "movlpd\t{%1, %0|%0, %1}";
2499         case MODE_V2SF:
2500           return "movlps\t{%1, %0|%0, %1}";
2501         default:
2502           gcc_unreachable ();
2503         }
2505     default:
2506       gcc_unreachable ();
2507     }
2509   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2510    (set (attr "mode")
2511         (cond [(eq_attr "alternative" "0,1,2")
2512                  (const_string "DF")
2513                (eq_attr "alternative" "3,4")
2514                  (const_string "SI")
2516                /* For SSE1, we have many fewer alternatives.  */
2517                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518                  (cond [(eq_attr "alternative" "5,6")
2519                           (const_string "V4SF")
2520                        ]
2521                    (const_string "V2SF"))
2523                /* xorps is one byte shorter.  */
2524                (eq_attr "alternative" "5")
2525                  (cond [(ne (symbol_ref "optimize_size")
2526                             (const_int 0))
2527                           (const_string "V4SF")
2528                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2529                             (const_int 0))
2530                           (const_string "TI")
2531                        ]
2532                        (const_string "V2DF"))
2534                /* For architectures resolving dependencies on
2535                   whole SSE registers use APD move to break dependency
2536                   chains, otherwise use short move to avoid extra work.
2538                   movaps encodes one byte shorter.  */
2539                (eq_attr "alternative" "6")
2540                  (cond
2541                    [(ne (symbol_ref "optimize_size")
2542                         (const_int 0))
2543                       (const_string "V4SF")
2544                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2545                         (const_int 0))
2546                       (const_string "V2DF")
2547                    ]
2548                    (const_string "DF"))
2549                /* For architectures resolving dependencies on register
2550                   parts we may avoid extra work to zero out upper part
2551                   of register.  */
2552                (eq_attr "alternative" "7")
2553                  (if_then_else
2554                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2555                        (const_int 0))
2556                    (const_string "V1DF")
2557                    (const_string "DF"))
2558               ]
2559               (const_string "DF")))])
2561 (define_insn "*movdf_integer"
2562   [(set (match_operand:DF 0 "nonimmediate_operand"
2563                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564         (match_operand:DF 1 "general_operand"
2565                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2566   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568    && (reload_in_progress || reload_completed
2569        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570        || GET_CODE (operands[1]) != CONST_DOUBLE
2571        || memory_operand (operands[0], DFmode))" 
2573   switch (which_alternative)
2574     {
2575     case 0:
2576       return output_387_reg_move (insn, operands);
2578     case 1:
2579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580         return "fstp%z0\t%y0";
2581       else
2582         return "fst%z0\t%y0";
2584     case 2:
2585       return standard_80387_constant_opcode (operands[1]);
2587     case 3:
2588     case 4:
2589       return "#";
2591     case 5:
2592       switch (get_attr_mode (insn))
2593         {
2594         case MODE_V4SF:
2595           return "xorps\t%0, %0";
2596         case MODE_V2DF:
2597           return "xorpd\t%0, %0";
2598         case MODE_TI:
2599           return "pxor\t%0, %0";
2600         default:
2601           gcc_unreachable ();
2602         }
2603     case 6:
2604     case 7:
2605     case 8:
2606       switch (get_attr_mode (insn))
2607         {
2608         case MODE_V4SF:
2609           return "movaps\t{%1, %0|%0, %1}";
2610         case MODE_V2DF:
2611           return "movapd\t{%1, %0|%0, %1}";
2612         case MODE_TI:
2613           return "movdqa\t{%1, %0|%0, %1}";
2614         case MODE_DI:
2615           return "movq\t{%1, %0|%0, %1}";
2616         case MODE_DF:
2617           return "movsd\t{%1, %0|%0, %1}";
2618         case MODE_V1DF:
2619           return "movlpd\t{%1, %0|%0, %1}";
2620         case MODE_V2SF:
2621           return "movlps\t{%1, %0|%0, %1}";
2622         default:
2623           gcc_unreachable ();
2624         }
2626     default:
2627       gcc_unreachable();
2628     }
2630   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2631    (set (attr "mode")
2632         (cond [(eq_attr "alternative" "0,1,2")
2633                  (const_string "DF")
2634                (eq_attr "alternative" "3,4")
2635                  (const_string "SI")
2637                /* For SSE1, we have many fewer alternatives.  */
2638                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639                  (cond [(eq_attr "alternative" "5,6")
2640                           (const_string "V4SF")
2641                        ]
2642                    (const_string "V2SF"))
2644                /* xorps is one byte shorter.  */
2645                (eq_attr "alternative" "5")
2646                  (cond [(ne (symbol_ref "optimize_size")
2647                             (const_int 0))
2648                           (const_string "V4SF")
2649                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650                             (const_int 0))
2651                           (const_string "TI")
2652                        ]
2653                        (const_string "V2DF"))
2655                /* For architectures resolving dependencies on
2656                   whole SSE registers use APD move to break dependency
2657                   chains, otherwise use short move to avoid extra work.
2659                   movaps encodes one byte shorter.  */
2660                (eq_attr "alternative" "6")
2661                  (cond
2662                    [(ne (symbol_ref "optimize_size")
2663                         (const_int 0))
2664                       (const_string "V4SF")
2665                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2666                         (const_int 0))
2667                       (const_string "V2DF")
2668                    ]
2669                    (const_string "DF"))
2670                /* For architectures resolving dependencies on register
2671                   parts we may avoid extra work to zero out upper part
2672                   of register.  */
2673                (eq_attr "alternative" "7")
2674                  (if_then_else
2675                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2676                        (const_int 0))
2677                    (const_string "V1DF")
2678                    (const_string "DF"))
2679               ]
2680               (const_string "DF")))])
2682 (define_split
2683   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684         (match_operand:DF 1 "general_operand" ""))]
2685   "reload_completed
2686    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687    && ! (ANY_FP_REG_P (operands[0]) || 
2688          (GET_CODE (operands[0]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690    && ! (ANY_FP_REG_P (operands[1]) || 
2691          (GET_CODE (operands[1]) == SUBREG
2692           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693   [(const_int 0)]
2694   "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*swapdf"
2697   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698         (match_operand:DF 1 "fp_register_operand" "+f"))
2699    (set (match_dup 1)
2700         (match_dup 0))]
2701   "reload_completed || TARGET_80387"
2703   if (STACK_TOP_P (operands[0]))
2704     return "fxch\t%1";
2705   else
2706     return "fxch\t%0";
2708   [(set_attr "type" "fxch")
2709    (set_attr "mode" "DF")])
2711 (define_expand "movxf"
2712   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713         (match_operand:XF 1 "general_operand" ""))]
2714   ""
2715   "ix86_expand_move (XFmode, operands); DONE;")
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;;  handled elsewhere).
2724 (define_insn "*pushxf_nointeger"
2725   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727   "optimize_size"
2729   /* This insn should be already split before reg-stack.  */
2730   gcc_unreachable ();
2732   [(set_attr "type" "multi")
2733    (set_attr "unit" "i387,*,*")
2734    (set_attr "mode" "XF,SI,SI")])
2736 (define_insn "*pushxf_integer"
2737   [(set (match_operand:XF 0 "push_operand" "=<,<")
2738         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739   "!optimize_size"
2741   /* This insn should be already split before reg-stack.  */
2742   gcc_unreachable ();
2744   [(set_attr "type" "multi")
2745    (set_attr "unit" "i387,*")
2746    (set_attr "mode" "XF,SI")])
2748 (define_split
2749   [(set (match_operand 0 "push_operand" "")
2750         (match_operand 1 "general_operand" ""))]
2751   "reload_completed
2752    && (GET_MODE (operands[0]) == XFmode
2753        || GET_MODE (operands[0]) == DFmode)
2754    && !ANY_FP_REG_P (operands[1])"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2758 (define_split
2759   [(set (match_operand:XF 0 "push_operand" "")
2760         (match_operand:XF 1 "any_fp_register_operand" ""))]
2761   "!TARGET_64BIT"
2762   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766 (define_split
2767   [(set (match_operand:XF 0 "push_operand" "")
2768         (match_operand:XF 1 "any_fp_register_operand" ""))]
2769   "TARGET_64BIT"
2770   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2778   "optimize_size
2779    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780    && (reload_in_progress || reload_completed
2781        || GET_CODE (operands[1]) != CONST_DOUBLE
2782        || memory_operand (operands[0], XFmode))" 
2784   switch (which_alternative)
2785     {
2786     case 0:
2787       return output_387_reg_move (insn, operands);
2789     case 1:
2790       /* There is no non-popping store to memory for XFmode.  So if
2791          we need one, follow the store with a load.  */
2792       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793         return "fstp%z0\t%y0\;fld%z0\t%y0";
2794       else
2795         return "fstp%z0\t%y0";
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2800     case 3: case 4:
2801       return "#";
2802     default:
2803       gcc_unreachable ();
2804     }
2806   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807    (set_attr "mode" "XF,XF,XF,SI,SI")])
2809 (define_insn "*movxf_integer"
2810   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2812   "!optimize_size
2813    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814    && (reload_in_progress || reload_completed
2815        || GET_CODE (operands[1]) != CONST_DOUBLE
2816        || memory_operand (operands[0], XFmode))" 
2818   switch (which_alternative)
2819     {
2820     case 0:
2821       return output_387_reg_move (insn, operands);
2823     case 1:
2824       /* There is no non-popping store to memory for XFmode.  So if
2825          we need one, follow the store with a load.  */
2826       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827         return "fstp%z0\t%y0\;fld%z0\t%y0";
2828       else
2829         return "fstp%z0\t%y0";
2831     case 2:
2832       return standard_80387_constant_opcode (operands[1]);
2834     case 3: case 4:
2835       return "#";
2837     default:
2838       gcc_unreachable ();
2839     }
2841   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842    (set_attr "mode" "XF,XF,XF,SI,SI")])
2844 (define_split
2845   [(set (match_operand 0 "nonimmediate_operand" "")
2846         (match_operand 1 "general_operand" ""))]
2847   "reload_completed
2848    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849    && GET_MODE (operands[0]) == XFmode
2850    && ! (ANY_FP_REG_P (operands[0]) || 
2851          (GET_CODE (operands[0]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853    && ! (ANY_FP_REG_P (operands[1]) || 
2854          (GET_CODE (operands[1]) == SUBREG
2855           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2856   [(const_int 0)]
2857   "ix86_split_long_move (operands); DONE;")
2859 (define_split
2860   [(set (match_operand 0 "register_operand" "")
2861         (match_operand 1 "memory_operand" ""))]
2862   "reload_completed
2863    && GET_CODE (operands[1]) == MEM
2864    && (GET_MODE (operands[0]) == XFmode
2865        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866    && constant_pool_reference_p (operands[1])"
2867   [(set (match_dup 0) (match_dup 1))]
2869   rtx c = avoid_constant_pool_reference (operands[1]);
2870   rtx r = operands[0];
2872   if (GET_CODE (r) == SUBREG)
2873     r = SUBREG_REG (r);
2875   if (SSE_REG_P (r))
2876     {
2877       if (!standard_sse_constant_p (c))
2878         FAIL;
2879     }
2880   else if (FP_REG_P (r))
2881     {
2882       if (!standard_80387_constant_p (c))
2883         FAIL;
2884     }
2885   else if (MMX_REG_P (r))
2886     FAIL;
2888   operands[1] = c;
2891 (define_insn "swapxf"
2892   [(set (match_operand:XF 0 "register_operand" "+f")
2893         (match_operand:XF 1 "register_operand" "+f"))
2894    (set (match_dup 1)
2895         (match_dup 0))]
2896   "TARGET_80387"
2898   if (STACK_TOP_P (operands[0]))
2899     return "fxch\t%1";
2900   else
2901     return "fxch\t%0";
2903   [(set_attr "type" "fxch")
2904    (set_attr "mode" "XF")])
2906 (define_expand "movtf"
2907   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908         (match_operand:TF 1 "nonimmediate_operand" ""))]
2909   "TARGET_64BIT"
2911   ix86_expand_move (TFmode, operands);
2912   DONE;
2915 (define_insn "*movtf_internal"
2916   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2918   "TARGET_64BIT
2919    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921   switch (which_alternative)
2922     {
2923     case 0:
2924     case 1:
2925       return "#";
2926     case 2:
2927       if (get_attr_mode (insn) == MODE_V4SF)
2928         return "xorps\t%0, %0";
2929       else
2930         return "pxor\t%0, %0";
2931     case 3:
2932     case 4:
2933       if (get_attr_mode (insn) == MODE_V4SF)
2934         return "movaps\t{%1, %0|%0, %1}";
2935       else
2936         return "movdqa\t{%1, %0|%0, %1}";
2937     default:
2938       gcc_unreachable ();
2939     }
2941   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2942    (set (attr "mode")
2943         (cond [(eq_attr "alternative" "2,3")
2944                  (if_then_else
2945                    (ne (symbol_ref "optimize_size")
2946                        (const_int 0))
2947                    (const_string "V4SF")
2948                    (const_string "TI"))
2949                (eq_attr "alternative" "4")
2950                  (if_then_else
2951                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2952                             (const_int 0))
2953                         (ne (symbol_ref "optimize_size")
2954                             (const_int 0)))
2955                    (const_string "V4SF")
2956                    (const_string "TI"))]
2957                (const_string "DI")))])
2959 (define_split
2960   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961         (match_operand:TF 1 "general_operand" ""))]
2962   "reload_completed && !SSE_REG_P (operands[0])
2963    && !SSE_REG_P (operands[1])"
2964   [(const_int 0)]
2965   "ix86_split_long_move (operands); DONE;")
2967 ;; Zero extension instructions
2969 (define_expand "zero_extendhisi2"
2970   [(set (match_operand:SI 0 "register_operand" "")
2971      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972   ""
2974   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2975     {
2976       operands[1] = force_reg (HImode, operands[1]);
2977       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978       DONE;
2979     }
2982 (define_insn "zero_extendhisi2_and"
2983   [(set (match_operand:SI 0 "register_operand" "=r")
2984      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985    (clobber (reg:CC FLAGS_REG))]
2986   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987   "#"
2988   [(set_attr "type" "alu1")
2989    (set_attr "mode" "SI")])
2991 (define_split
2992   [(set (match_operand:SI 0 "register_operand" "")
2993         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994    (clobber (reg:CC FLAGS_REG))]
2995   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997               (clobber (reg:CC FLAGS_REG))])]
2998   "")
3000 (define_insn "*zero_extendhisi2_movzwl"
3001   [(set (match_operand:SI 0 "register_operand" "=r")
3002      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004   "movz{wl|x}\t{%1, %0|%0, %1}"
3005   [(set_attr "type" "imovx")
3006    (set_attr "mode" "SI")])
3008 (define_expand "zero_extendqihi2"
3009   [(parallel
3010     [(set (match_operand:HI 0 "register_operand" "")
3011        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012      (clobber (reg:CC FLAGS_REG))])]
3013   ""
3014   "")
3016 (define_insn "*zero_extendqihi2_and"
3017   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019    (clobber (reg:CC FLAGS_REG))]
3020   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3021   "#"
3022   [(set_attr "type" "alu1")
3023    (set_attr "mode" "HI")])
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026   [(set (match_operand:HI 0 "register_operand" "=r,r")
3027      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028    (clobber (reg:CC FLAGS_REG))]
3029   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3030   "#"
3031   [(set_attr "type" "imovx,alu1")
3032    (set_attr "mode" "HI")])
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
3036   [(set (match_operand:HI 0 "register_operand" "=r")
3037      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040   [(set_attr "type" "imovx")
3041    (set_attr "mode" "SI")])
3043 ;; For the movzbw case strip only the clobber
3044 (define_split
3045   [(set (match_operand:HI 0 "register_operand" "")
3046         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "reload_completed 
3049    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051   [(set (match_operand:HI 0 "register_operand" "")
3052         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3056 (define_split
3057   [(set (match_operand:HI 0 "register_operand" "")
3058         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "reload_completed
3061    && ANY_QI_REG_P (operands[0])
3062    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064   [(set (match_dup 0) (const_int 0))
3065    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066   "operands[2] = gen_lowpart (QImode, operands[0]);")
3068 ;; Rest is handled by single and.
3069 (define_split
3070   [(set (match_operand:HI 0 "register_operand" "")
3071         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "reload_completed
3074    && true_regnum (operands[0]) == true_regnum (operands[1])"
3075   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076               (clobber (reg:CC FLAGS_REG))])]
3077   "")
3079 (define_expand "zero_extendqisi2"
3080   [(parallel
3081     [(set (match_operand:SI 0 "register_operand" "")
3082        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083      (clobber (reg:CC FLAGS_REG))])]
3084   ""
3085   "")
3087 (define_insn "*zero_extendqisi2_and"
3088   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092   "#"
3093   [(set_attr "type" "alu1")
3094    (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,r")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101   "#"
3102   [(set_attr "type" "imovx,alu1")
3103    (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw"
3106   [(set (match_operand:SI 0 "register_operand" "=r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109   "movz{bl|x}\t{%1, %0|%0, %1}"
3110   [(set_attr "type" "imovx")
3111    (set_attr "mode" "SI")])
3113 ;; For the movzbl case strip only the clobber
3114 (define_split
3115   [(set (match_operand:SI 0 "register_operand" "")
3116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117    (clobber (reg:CC FLAGS_REG))]
3118   "reload_completed 
3119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121   [(set (match_dup 0)
3122         (zero_extend:SI (match_dup 1)))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3126 (define_split
3127   [(set (match_operand:SI 0 "register_operand" "")
3128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129    (clobber (reg:CC FLAGS_REG))]
3130   "reload_completed
3131    && ANY_QI_REG_P (operands[0])
3132    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135   [(set (match_dup 0) (const_int 0))
3136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137   "operands[2] = gen_lowpart (QImode, operands[0]);")
3139 ;; Rest is handled by single and.
3140 (define_split
3141   [(set (match_operand:SI 0 "register_operand" "")
3142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143    (clobber (reg:CC FLAGS_REG))]
3144   "reload_completed
3145    && true_regnum (operands[0]) == true_regnum (operands[1])"
3146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147               (clobber (reg:CC FLAGS_REG))])]
3148   "")
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152   [(set (match_operand:DI 0 "register_operand" "=r")
3153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3154   ""
3155   "if (!TARGET_64BIT)
3156      {
3157        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158        DONE;
3159      }
3160   ")
3162 (define_insn "zero_extendsidi2_32"
3163   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165    (clobber (reg:CC FLAGS_REG))]
3166   "!TARGET_64BIT"
3167   "@
3168    #
3169    #
3170    #
3171    movd\t{%1, %0|%0, %1}
3172    movd\t{%1, %0|%0, %1}"
3173   [(set_attr "mode" "SI,SI,SI,DI,TI")
3174    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176 (define_insn "zero_extendsidi2_rex64"
3177   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179   "TARGET_64BIT"
3180   "@
3181    mov\t{%k1, %k0|%k0, %k1}
3182    #
3183    movd\t{%1, %0|%0, %1}
3184    movd\t{%1, %0|%0, %1}"
3185   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186    (set_attr "mode" "SI,DI,SI,SI")])
3188 (define_split
3189   [(set (match_operand:DI 0 "memory_operand" "")
3190      (zero_extend:DI (match_dup 0)))]
3191   "TARGET_64BIT"
3192   [(set (match_dup 4) (const_int 0))]
3193   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3195 (define_split 
3196   [(set (match_operand:DI 0 "register_operand" "")
3197         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198    (clobber (reg:CC FLAGS_REG))]
3199   "!TARGET_64BIT && reload_completed
3200    && true_regnum (operands[0]) == true_regnum (operands[1])"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204 (define_split 
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210   [(set (match_dup 3) (match_dup 1))
3211    (set (match_dup 4) (const_int 0))]
3212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 (define_insn "zero_extendhidi2"
3215   [(set (match_operand:DI 0 "register_operand" "=r")
3216      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3217   "TARGET_64BIT"
3218   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219   [(set_attr "type" "imovx")
3220    (set_attr "mode" "DI")])
3222 (define_insn "zero_extendqidi2"
3223   [(set (match_operand:DI 0 "register_operand" "=r")
3224      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3225   "TARGET_64BIT"
3226   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227   [(set_attr "type" "imovx")
3228    (set_attr "mode" "DI")])
3230 ;; Sign extension instructions
3232 (define_expand "extendsidi2"
3233   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235               (clobber (reg:CC FLAGS_REG))
3236               (clobber (match_scratch:SI 2 ""))])]
3237   ""
3239   if (TARGET_64BIT)
3240     {
3241       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242       DONE;
3243     }
3246 (define_insn "*extendsidi2_1"
3247   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249    (clobber (reg:CC FLAGS_REG))
3250    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3251   "!TARGET_64BIT"
3252   "#")
3254 (define_insn "extendsidi2_rex64"
3255   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3257   "TARGET_64BIT"
3258   "@
3259    {cltq|cdqe}
3260    movs{lq|x}\t{%1,%0|%0, %1}"
3261   [(set_attr "type" "imovx")
3262    (set_attr "mode" "DI")
3263    (set_attr "prefix_0f" "0")
3264    (set_attr "modrm" "0,1")])
3266 (define_insn "extendhidi2"
3267   [(set (match_operand:DI 0 "register_operand" "=r")
3268         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3269   "TARGET_64BIT"
3270   "movs{wq|x}\t{%1,%0|%0, %1}"
3271   [(set_attr "type" "imovx")
3272    (set_attr "mode" "DI")])
3274 (define_insn "extendqidi2"
3275   [(set (match_operand:DI 0 "register_operand" "=r")
3276         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3277   "TARGET_64BIT"
3278   "movs{bq|x}\t{%1,%0|%0, %1}"
3279    [(set_attr "type" "imovx")
3280     (set_attr "mode" "DI")])
3282 ;; Extend to memory case when source register does die.
3283 (define_split 
3284   [(set (match_operand:DI 0 "memory_operand" "")
3285         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286    (clobber (reg:CC FLAGS_REG))
3287    (clobber (match_operand:SI 2 "register_operand" ""))]
3288   "(reload_completed
3289     && dead_or_set_p (insn, operands[1])
3290     && !reg_mentioned_p (operands[1], operands[0]))"
3291   [(set (match_dup 3) (match_dup 1))
3292    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293               (clobber (reg:CC FLAGS_REG))])
3294    (set (match_dup 4) (match_dup 1))]
3295   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297 ;; Extend to memory case when source register does not die.
3298 (define_split 
3299   [(set (match_operand:DI 0 "memory_operand" "")
3300         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301    (clobber (reg:CC FLAGS_REG))
3302    (clobber (match_operand:SI 2 "register_operand" ""))]
3303   "reload_completed"
3304   [(const_int 0)]
3306   split_di (&operands[0], 1, &operands[3], &operands[4]);
3308   emit_move_insn (operands[3], operands[1]);
3310   /* Generate a cltd if possible and doing so it profitable.  */
3311   if (true_regnum (operands[1]) == 0
3312       && true_regnum (operands[2]) == 1
3313       && (optimize_size || TARGET_USE_CLTD))
3314     {
3315       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3316     }
3317   else
3318     {
3319       emit_move_insn (operands[2], operands[1]);
3320       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3321     }
3322   emit_move_insn (operands[4], operands[2]);
3323   DONE;
3326 ;; Extend to register case.  Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3328 (define_split 
3329   [(set (match_operand:DI 0 "register_operand" "")
3330         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331    (clobber (reg:CC FLAGS_REG))
3332    (clobber (match_scratch:SI 2 ""))]
3333   "reload_completed"
3334   [(const_int 0)]
3336   split_di (&operands[0], 1, &operands[3], &operands[4]);
3338   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339     emit_move_insn (operands[3], operands[1]);
3341   /* Generate a cltd if possible and doing so it profitable.  */
3342   if (true_regnum (operands[3]) == 0
3343       && (optimize_size || TARGET_USE_CLTD))
3344     {
3345       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3346       DONE;
3347     }
3349   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350     emit_move_insn (operands[4], operands[1]);
3352   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3353   DONE;
3356 (define_insn "extendhisi2"
3357   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359   ""
3361   switch (get_attr_prefix_0f (insn))
3362     {
3363     case 0:
3364       return "{cwtl|cwde}";
3365     default:
3366       return "movs{wl|x}\t{%1,%0|%0, %1}";
3367     }
3369   [(set_attr "type" "imovx")
3370    (set_attr "mode" "SI")
3371    (set (attr "prefix_0f")
3372      ;; movsx is short decodable while cwtl is vector decoded.
3373      (if_then_else (and (eq_attr "cpu" "!k6")
3374                         (eq_attr "alternative" "0"))
3375         (const_string "0")
3376         (const_string "1")))
3377    (set (attr "modrm")
3378      (if_then_else (eq_attr "prefix_0f" "0")
3379         (const_string "0")
3380         (const_string "1")))])
3382 (define_insn "*extendhisi2_zext"
3383   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3384         (zero_extend:DI
3385           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386   "TARGET_64BIT"
3388   switch (get_attr_prefix_0f (insn))
3389     {
3390     case 0:
3391       return "{cwtl|cwde}";
3392     default:
3393       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394     }
3396   [(set_attr "type" "imovx")
3397    (set_attr "mode" "SI")
3398    (set (attr "prefix_0f")
3399      ;; movsx is short decodable while cwtl is vector decoded.
3400      (if_then_else (and (eq_attr "cpu" "!k6")
3401                         (eq_attr "alternative" "0"))
3402         (const_string "0")
3403         (const_string "1")))
3404    (set (attr "modrm")
3405      (if_then_else (eq_attr "prefix_0f" "0")
3406         (const_string "0")
3407         (const_string "1")))])
3409 (define_insn "extendqihi2"
3410   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412   ""
3414   switch (get_attr_prefix_0f (insn))
3415     {
3416     case 0:
3417       return "{cbtw|cbw}";
3418     default:
3419       return "movs{bw|x}\t{%1,%0|%0, %1}";
3420     }
3422   [(set_attr "type" "imovx")
3423    (set_attr "mode" "HI")
3424    (set (attr "prefix_0f")
3425      ;; movsx is short decodable while cwtl is vector decoded.
3426      (if_then_else (and (eq_attr "cpu" "!k6")
3427                         (eq_attr "alternative" "0"))
3428         (const_string "0")
3429         (const_string "1")))
3430    (set (attr "modrm")
3431      (if_then_else (eq_attr "prefix_0f" "0")
3432         (const_string "0")
3433         (const_string "1")))])
3435 (define_insn "extendqisi2"
3436   [(set (match_operand:SI 0 "register_operand" "=r")
3437         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3438   ""
3439   "movs{bl|x}\t{%1,%0|%0, %1}"
3440    [(set_attr "type" "imovx")
3441     (set_attr "mode" "SI")])
3443 (define_insn "*extendqisi2_zext"
3444   [(set (match_operand:DI 0 "register_operand" "=r")
3445         (zero_extend:DI
3446           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3447   "TARGET_64BIT"
3448   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3452 ;; Conversions between float and double.
3454 ;; These are all no-ops in the model used for the 80387.  So just
3455 ;; emit moves.
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3458 (define_insn "*dummy_extendsfdf2"
3459   [(set (match_operand:DF 0 "push_operand" "=<")
3460         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461   "0"
3462   "#")
3464 (define_split
3465   [(set (match_operand:DF 0 "push_operand" "")
3466         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3467   "!TARGET_64BIT"
3468   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3471 (define_split
3472   [(set (match_operand:DF 0 "push_operand" "")
3473         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474   "TARGET_64BIT"
3475   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478 (define_insn "*dummy_extendsfxf2"
3479   [(set (match_operand:XF 0 "push_operand" "=<")
3480         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481   "0"
3482   "#")
3484 (define_split
3485   [(set (match_operand:XF 0 "push_operand" "")
3486         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3487   ""
3488   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492 (define_split
3493   [(set (match_operand:XF 0 "push_operand" "")
3494         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "TARGET_64BIT"
3496   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500 (define_split
3501   [(set (match_operand:XF 0 "push_operand" "")
3502         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3503   ""
3504   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508 (define_split
3509   [(set (match_operand:XF 0 "push_operand" "")
3510         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3511   "TARGET_64BIT"
3512   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516 (define_expand "extendsfdf2"
3517   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521   /* ??? Needed for compress_float_constant since all fp constants
3522      are LEGITIMATE_CONSTANT_P.  */
3523   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524     {
3525       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3526           && standard_80387_constant_p (operands[1]) > 0)
3527         {
3528           operands[1] = simplify_const_unary_operation
3529             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3530           emit_move_insn_1 (operands[0], operands[1]);
3531           DONE;
3532         }
3533       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3534     }
3535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3536     operands[1] = force_reg (SFmode, operands[1]);
3539 (define_insn "*extendsfdf2_mixed"
3540   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3541         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3542   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3543    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3545   switch (which_alternative)
3546     {
3547     case 0:
3548       return output_387_reg_move (insn, operands);
3550     case 1:
3551       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3552         return "fstp%z0\t%y0";
3553       else
3554         return "fst%z0\t%y0";
3556     case 2:
3557       return "cvtss2sd\t{%1, %0|%0, %1}";
3559     default:
3560       gcc_unreachable ();
3561     }
3563   [(set_attr "type" "fmov,fmov,ssecvt")
3564    (set_attr "mode" "SF,XF,DF")])
3566 (define_insn "*extendsfdf2_sse"
3567   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3568         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3569   "TARGET_SSE2 && TARGET_SSE_MATH
3570    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571   "cvtss2sd\t{%1, %0|%0, %1}"
3572   [(set_attr "type" "ssecvt")
3573    (set_attr "mode" "DF")])
3575 (define_insn "*extendsfdf2_i387"
3576   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3577         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3578   "TARGET_80387
3579    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3581   switch (which_alternative)
3582     {
3583     case 0:
3584       return output_387_reg_move (insn, operands);
3586     case 1:
3587       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3588         return "fstp%z0\t%y0";
3589       else
3590         return "fst%z0\t%y0";
3592     default:
3593       gcc_unreachable ();
3594     }
3596   [(set_attr "type" "fmov")
3597    (set_attr "mode" "SF,XF")])
3599 (define_expand "extendsfxf2"
3600   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3601         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3602   "TARGET_80387"
3604   /* ??? Needed for compress_float_constant since all fp constants
3605      are LEGITIMATE_CONSTANT_P.  */
3606   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3607     {
3608       if (standard_80387_constant_p (operands[1]) > 0)
3609         {
3610           operands[1] = simplify_const_unary_operation
3611             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3612           emit_move_insn_1 (operands[0], operands[1]);
3613           DONE;
3614         }
3615       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3616     }
3617   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3618     operands[1] = force_reg (SFmode, operands[1]);
3621 (define_insn "*extendsfxf2_i387"
3622   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3623         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3624   "TARGET_80387
3625    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3627   switch (which_alternative)
3628     {
3629     case 0:
3630       return output_387_reg_move (insn, operands);
3632     case 1:
3633       /* There is no non-popping store to memory for XFmode.  So if
3634          we need one, follow the store with a load.  */
3635       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636         return "fstp%z0\t%y0";
3637       else
3638         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640     default:
3641       gcc_unreachable ();
3642     }
3644   [(set_attr "type" "fmov")
3645    (set_attr "mode" "SF,XF")])
3647 (define_expand "extenddfxf2"
3648   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3649         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3650   "TARGET_80387"
3652   /* ??? Needed for compress_float_constant since all fp constants
3653      are LEGITIMATE_CONSTANT_P.  */
3654   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3655     {
3656       if (standard_80387_constant_p (operands[1]) > 0)
3657         {
3658           operands[1] = simplify_const_unary_operation
3659             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3660           emit_move_insn_1 (operands[0], operands[1]);
3661           DONE;
3662         }
3663       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3664     }
3665   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3666     operands[1] = force_reg (DFmode, operands[1]);
3669 (define_insn "*extenddfxf2_i387"
3670   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3671         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3672   "TARGET_80387
3673    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3675   switch (which_alternative)
3676     {
3677     case 0:
3678       return output_387_reg_move (insn, operands);
3680     case 1:
3681       /* There is no non-popping store to memory for XFmode.  So if
3682          we need one, follow the store with a load.  */
3683       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3685       else
3686         return "fstp%z0\t%y0";
3688     default:
3689       gcc_unreachable ();
3690     }
3692   [(set_attr "type" "fmov")
3693    (set_attr "mode" "DF,XF")])
3695 ;; %%% This seems bad bad news.
3696 ;; This cannot output into an f-reg because there is no way to be sure
3697 ;; of truncating in that case.  Otherwise this is just like a simple move
3698 ;; insn.  So we pretend we can output to a reg in order to get better
3699 ;; register preferencing, but we really use a stack slot.
3701 ;; Conversion from DFmode to SFmode.
3703 (define_expand "truncdfsf2"
3704   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3705         (float_truncate:SF
3706           (match_operand:DF 1 "nonimmediate_operand" "")))]
3707   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3709   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3710     operands[1] = force_reg (DFmode, operands[1]);
3712   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3713     ;
3714   else if (flag_unsafe_math_optimizations)
3715     ;
3716   else
3717     {
3718       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3719       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3720       DONE;
3721     }
3724 (define_expand "truncdfsf2_with_temp"
3725   [(parallel [(set (match_operand:SF 0 "" "")
3726                    (float_truncate:SF (match_operand:DF 1 "" "")))
3727               (clobber (match_operand:SF 2 "" ""))])]
3728   "")
3730 (define_insn "*truncdfsf_fast_mixed"
3731   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3732         (float_truncate:SF
3733           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3734   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3736   switch (which_alternative)
3737     {
3738     case 0:
3739       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3740         return "fstp%z0\t%y0";
3741       else
3742         return "fst%z0\t%y0";
3743     case 1:
3744       return output_387_reg_move (insn, operands);
3745     case 2:
3746       return "cvtsd2ss\t{%1, %0|%0, %1}";
3747     default:
3748       gcc_unreachable ();
3749     }
3751   [(set_attr "type" "fmov,fmov,ssecvt")
3752    (set_attr "mode" "SF")])
3754 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3755 ;; because nothing we do here is unsafe.
3756 (define_insn "*truncdfsf_fast_sse"
3757   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3758         (float_truncate:SF
3759           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3760   "TARGET_SSE2 && TARGET_SSE_MATH"
3761   "cvtsd2ss\t{%1, %0|%0, %1}"
3762   [(set_attr "type" "ssecvt")
3763    (set_attr "mode" "SF")])
3765 (define_insn "*truncdfsf_fast_i387"
3766   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3767         (float_truncate:SF
3768           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3769   "TARGET_80387 && flag_unsafe_math_optimizations"
3770   "* return output_387_reg_move (insn, operands);"
3771   [(set_attr "type" "fmov")
3772    (set_attr "mode" "SF")])
3774 (define_insn "*truncdfsf_mixed"
3775   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3776         (float_truncate:SF
3777           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3778    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3779   "TARGET_MIX_SSE_I387"
3781   switch (which_alternative)
3782     {
3783     case 0:
3784       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3785         return "fstp%z0\t%y0";
3786       else
3787         return "fst%z0\t%y0";
3788     case 1:
3789       return "#";
3790     case 2:
3791       return "cvtsd2ss\t{%1, %0|%0, %1}";
3792     default:
3793       gcc_unreachable ();
3794     }
3796   [(set_attr "type" "fmov,multi,ssecvt")
3797    (set_attr "unit" "*,i387,*")
3798    (set_attr "mode" "SF")])
3800 (define_insn "*truncdfsf_i387"
3801   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3802         (float_truncate:SF
3803           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3804    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3805   "TARGET_80387"
3807   switch (which_alternative)
3808     {
3809     case 0:
3810       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811         return "fstp%z0\t%y0";
3812       else
3813         return "fst%z0\t%y0";
3814     case 1:
3815       return "#";
3816     default:
3817       gcc_unreachable ();
3818     }
3820   [(set_attr "type" "fmov,multi")
3821    (set_attr "unit" "*,i387")
3822    (set_attr "mode" "SF")])
3824 (define_insn "*truncdfsf2_i387_1"
3825   [(set (match_operand:SF 0 "memory_operand" "=m")
3826         (float_truncate:SF
3827           (match_operand:DF 1 "register_operand" "f")))]
3828   "TARGET_80387
3829    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3830    && !TARGET_MIX_SSE_I387"
3832   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833     return "fstp%z0\t%y0";
3834   else
3835     return "fst%z0\t%y0";
3837   [(set_attr "type" "fmov")
3838    (set_attr "mode" "SF")])
3840 (define_split
3841   [(set (match_operand:SF 0 "register_operand" "")
3842         (float_truncate:SF
3843          (match_operand:DF 1 "fp_register_operand" "")))
3844    (clobber (match_operand 2 "" ""))]
3845   "reload_completed"
3846   [(set (match_dup 2) (match_dup 1))
3847    (set (match_dup 0) (match_dup 2))]
3849   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3852 ;; Conversion from XFmode to SFmode.
3854 (define_expand "truncxfsf2"
3855   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3856                    (float_truncate:SF
3857                     (match_operand:XF 1 "register_operand" "")))
3858               (clobber (match_dup 2))])]
3859   "TARGET_80387"
3861   if (flag_unsafe_math_optimizations)
3862     {
3863       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3864       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3865       if (reg != operands[0])
3866         emit_move_insn (operands[0], reg);
3867       DONE;
3868     }
3869   else
3870     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3873 (define_insn "*truncxfsf2_mixed"
3874   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3875         (float_truncate:SF
3876          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3877    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3878   "TARGET_MIX_SSE_I387"
3880   gcc_assert (!which_alternative);
3881   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882     return "fstp%z0\t%y0";
3883   else
3884     return "fst%z0\t%y0";
3886   [(set_attr "type" "fmov,multi,multi,multi")
3887    (set_attr "unit" "*,i387,i387,i387")
3888    (set_attr "mode" "SF")])
3890 (define_insn "truncxfsf2_i387_noop"
3891   [(set (match_operand:SF 0 "register_operand" "=f")
3892         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3893   "TARGET_80387 && flag_unsafe_math_optimizations"
3895   return output_387_reg_move (insn, operands);
3897   [(set_attr "type" "fmov")
3898    (set_attr "mode" "SF")])
3900 (define_insn "*truncxfsf2_i387"
3901   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3902         (float_truncate:SF
3903          (match_operand:XF 1 "register_operand" "f,f,f")))
3904    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3905   "TARGET_80387"
3907   gcc_assert (!which_alternative);
3908   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3909     return "fstp%z0\t%y0";
3910    else
3911      return "fst%z0\t%y0";
3913   [(set_attr "type" "fmov,multi,multi")
3914    (set_attr "unit" "*,i387,i387")
3915    (set_attr "mode" "SF")])
3917 (define_insn "*truncxfsf2_i387_1"
3918   [(set (match_operand:SF 0 "memory_operand" "=m")
3919         (float_truncate:SF
3920          (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387"
3923   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924     return "fstp%z0\t%y0";
3925   else
3926     return "fst%z0\t%y0";
3928   [(set_attr "type" "fmov")
3929    (set_attr "mode" "SF")])
3931 (define_split
3932   [(set (match_operand:SF 0 "register_operand" "")
3933         (float_truncate:SF
3934          (match_operand:XF 1 "register_operand" "")))
3935    (clobber (match_operand:SF 2 "memory_operand" ""))]
3936   "TARGET_80387 && reload_completed"
3937   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3938    (set (match_dup 0) (match_dup 2))]
3939   "")
3941 (define_split
3942   [(set (match_operand:SF 0 "memory_operand" "")
3943         (float_truncate:SF
3944          (match_operand:XF 1 "register_operand" "")))
3945    (clobber (match_operand:SF 2 "memory_operand" ""))]
3946   "TARGET_80387"
3947   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3948   "")
3950 ;; Conversion from XFmode to DFmode.
3952 (define_expand "truncxfdf2"
3953   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3954                    (float_truncate:DF
3955                     (match_operand:XF 1 "register_operand" "")))
3956               (clobber (match_dup 2))])]
3957   "TARGET_80387"
3959   if (flag_unsafe_math_optimizations)
3960     {
3961       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3962       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3963       if (reg != operands[0])
3964         emit_move_insn (operands[0], reg);
3965       DONE;
3966     }
3967   else
3968     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3971 (define_insn "*truncxfdf2_mixed"
3972   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3973         (float_truncate:DF
3974          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3975    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3976   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3978   gcc_assert (!which_alternative);
3979   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3980     return "fstp%z0\t%y0";
3981   else
3982     return "fst%z0\t%y0";
3984   [(set_attr "type" "fmov,multi,multi,multi")
3985    (set_attr "unit" "*,i387,i387,i387")
3986    (set_attr "mode" "DF")])
3988 (define_insn "truncxfdf2_i387_noop"
3989   [(set (match_operand:DF 0 "register_operand" "=f")
3990         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3991   "TARGET_80387 && flag_unsafe_math_optimizations"
3993   return output_387_reg_move (insn, operands);
3995   [(set_attr "type" "fmov")
3996    (set_attr "mode" "DF")])
3998 (define_insn "*truncxfdf2_i387"
3999   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
4000         (float_truncate:DF
4001          (match_operand:XF 1 "register_operand" "f,f,f")))
4002    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4003   "TARGET_80387"
4005   gcc_assert (!which_alternative);
4006   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4007     return "fstp%z0\t%y0";
4008   else
4009     return "fst%z0\t%y0";
4011   [(set_attr "type" "fmov,multi,multi")
4012    (set_attr "unit" "*,i387,i387")
4013    (set_attr "mode" "DF")])
4015 (define_insn "*truncxfdf2_i387_1"
4016   [(set (match_operand:DF 0 "memory_operand" "=m")
4017         (float_truncate:DF
4018           (match_operand:XF 1 "register_operand" "f")))]
4019   "TARGET_80387"
4021   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022     return "fstp%z0\t%y0";
4023   else
4024     return "fst%z0\t%y0";
4026   [(set_attr "type" "fmov")
4027    (set_attr "mode" "DF")])
4029 (define_split
4030   [(set (match_operand:DF 0 "register_operand" "")
4031         (float_truncate:DF
4032          (match_operand:XF 1 "register_operand" "")))
4033    (clobber (match_operand:DF 2 "memory_operand" ""))]
4034   "TARGET_80387 && reload_completed"
4035   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4036    (set (match_dup 0) (match_dup 2))]
4037   "")
4039 (define_split
4040   [(set (match_operand:DF 0 "memory_operand" "")
4041         (float_truncate:DF
4042          (match_operand:XF 1 "register_operand" "")))
4043    (clobber (match_operand:DF 2 "memory_operand" ""))]
4044   "TARGET_80387"
4045   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4046   "")
4048 ;; Signed conversion to DImode.
4050 (define_expand "fix_truncxfdi2"
4051   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4053               (clobber (reg:CC FLAGS_REG))])]
4054   "TARGET_80387"
4056   if (TARGET_FISTTP)
4057    {
4058      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4059      DONE;
4060    }
4063 (define_expand "fix_trunc<mode>di2"
4064   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4065                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4066               (clobber (reg:CC FLAGS_REG))])]
4067   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4069   if (TARGET_FISTTP
4070       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4071    {
4072      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4073      DONE;
4074    }
4075   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4076    {
4077      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4078      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4079      if (out != operands[0])
4080         emit_move_insn (operands[0], out);
4081      DONE;
4082    }
4085 ;; Signed conversion to SImode.
4087 (define_expand "fix_truncxfsi2"
4088   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4090               (clobber (reg:CC FLAGS_REG))])]
4091   "TARGET_80387"
4093   if (TARGET_FISTTP)
4094    {
4095      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4096      DONE;
4097    }
4100 (define_expand "fix_trunc<mode>si2"
4101   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4102                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4103               (clobber (reg:CC FLAGS_REG))])]
4104   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4106   if (TARGET_FISTTP
4107       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4108    {
4109      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4110      DONE;
4111    }
4112   if (SSE_FLOAT_MODE_P (<MODE>mode))
4113    {
4114      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4115      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4116      if (out != operands[0])
4117         emit_move_insn (operands[0], out);
4118      DONE;
4119    }
4122 ;; Signed conversion to HImode.
4124 (define_expand "fix_trunc<mode>hi2"
4125   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4126                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4127               (clobber (reg:CC FLAGS_REG))])]
4128   "TARGET_80387
4129    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4131   if (TARGET_FISTTP)
4132    {
4133      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4134      DONE;
4135    }
4138 ;; When SSE is available, it is always faster to use it!
4139 (define_insn "fix_truncsfdi_sse"
4140   [(set (match_operand:DI 0 "register_operand" "=r,r")
4141         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4142   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143   "cvttss2si{q}\t{%1, %0|%0, %1}"
4144   [(set_attr "type" "sseicvt")
4145    (set_attr "mode" "SF")
4146    (set_attr "athlon_decode" "double,vector")])
4148 (define_insn "fix_truncdfdi_sse"
4149   [(set (match_operand:DI 0 "register_operand" "=r,r")
4150         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4151   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4152   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4153   [(set_attr "type" "sseicvt")
4154    (set_attr "mode" "DF")
4155    (set_attr "athlon_decode" "double,vector")])
4157 (define_insn "fix_truncsfsi_sse"
4158   [(set (match_operand:SI 0 "register_operand" "=r,r")
4159         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4160   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4161   "cvttss2si\t{%1, %0|%0, %1}"
4162   [(set_attr "type" "sseicvt")
4163    (set_attr "mode" "DF")
4164    (set_attr "athlon_decode" "double,vector")])
4166 (define_insn "fix_truncdfsi_sse"
4167   [(set (match_operand:SI 0 "register_operand" "=r,r")
4168         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4170   "cvttsd2si\t{%1, %0|%0, %1}"
4171   [(set_attr "type" "sseicvt")
4172    (set_attr "mode" "DF")
4173    (set_attr "athlon_decode" "double,vector")])
4175 ;; Avoid vector decoded forms of the instruction.
4176 (define_peephole2
4177   [(match_scratch:DF 2 "Y")
4178    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4179         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4180   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4181   [(set (match_dup 2) (match_dup 1))
4182    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4183   "")
4185 (define_peephole2
4186   [(match_scratch:SF 2 "x")
4187    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4188         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4189   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4190   [(set (match_dup 2) (match_dup 1))
4191    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4192   "")
4194 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4195   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4196         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4197   "TARGET_FISTTP
4198    && FLOAT_MODE_P (GET_MODE (operands[1]))
4199    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200          && (TARGET_64BIT || <MODE>mode != DImode))
4201         && TARGET_SSE_MATH)
4202    && !(reload_completed || reload_in_progress)"
4203   "#"
4204   "&& 1"
4205   [(const_int 0)]
4207   if (memory_operand (operands[0], VOIDmode))
4208     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4209   else
4210     {
4211       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4212       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4213                                                             operands[1],
4214                                                             operands[2]));
4215     }
4216   DONE;
4218   [(set_attr "type" "fisttp")
4219    (set_attr "mode" "<MODE>")])
4221 (define_insn "fix_trunc<mode>_i387_fisttp"
4222   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4223         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4224    (clobber (match_scratch:XF 2 "=&1f"))]
4225   "TARGET_FISTTP
4226    && FLOAT_MODE_P (GET_MODE (operands[1]))
4227    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4228          && (TARGET_64BIT || <MODE>mode != DImode))
4229         && TARGET_SSE_MATH)"
4230   "* return output_fix_trunc (insn, operands, 1);"
4231   [(set_attr "type" "fisttp")
4232    (set_attr "mode" "<MODE>")])
4234 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4235   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4236         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4237    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4238    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4239   "TARGET_FISTTP
4240    && FLOAT_MODE_P (GET_MODE (operands[1]))
4241    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4242         && (TARGET_64BIT || <MODE>mode != DImode))
4243         && TARGET_SSE_MATH)"
4244   "#"
4245   [(set_attr "type" "fisttp")
4246    (set_attr "mode" "<MODE>")])
4248 (define_split
4249   [(set (match_operand:X87MODEI 0 "register_operand" "")
4250         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4251    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4252    (clobber (match_scratch 3 ""))]
4253   "reload_completed"
4254   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4255               (clobber (match_dup 3))])
4256    (set (match_dup 0) (match_dup 2))]
4257   "")
4259 (define_split
4260   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4261         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4262    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4263    (clobber (match_scratch 3 ""))]
4264   "reload_completed"
4265   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4266               (clobber (match_dup 3))])]
4267   "")
4269 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4270 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4271 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4272 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4273 ;; function in i386.c.
4274 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4275   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4276         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4277    (clobber (reg:CC FLAGS_REG))]
4278   "TARGET_80387 && !TARGET_FISTTP
4279    && FLOAT_MODE_P (GET_MODE (operands[1]))
4280    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4281          && (TARGET_64BIT || <MODE>mode != DImode))
4282    && !(reload_completed || reload_in_progress)"
4283   "#"
4284   "&& 1"
4285   [(const_int 0)]
4287   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4289   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4290   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4291   if (memory_operand (operands[0], VOIDmode))
4292     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4293                                          operands[2], operands[3]));
4294   else
4295     {
4296       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4297       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4298                                                      operands[2], operands[3],
4299                                                      operands[4]));
4300     }
4301   DONE;
4303   [(set_attr "type" "fistp")
4304    (set_attr "i387_cw" "trunc")
4305    (set_attr "mode" "<MODE>")])
4307 (define_insn "fix_truncdi_i387"
4308   [(set (match_operand:DI 0 "memory_operand" "=m")
4309         (fix:DI (match_operand 1 "register_operand" "f")))
4310    (use (match_operand:HI 2 "memory_operand" "m"))
4311    (use (match_operand:HI 3 "memory_operand" "m"))
4312    (clobber (match_scratch:XF 4 "=&1f"))]
4313   "TARGET_80387 && !TARGET_FISTTP
4314    && FLOAT_MODE_P (GET_MODE (operands[1]))
4315    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4316   "* return output_fix_trunc (insn, operands, 0);"
4317   [(set_attr "type" "fistp")
4318    (set_attr "i387_cw" "trunc")
4319    (set_attr "mode" "DI")])
4321 (define_insn "fix_truncdi_i387_with_temp"
4322   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4323         (fix:DI (match_operand 1 "register_operand" "f,f")))
4324    (use (match_operand:HI 2 "memory_operand" "m,m"))
4325    (use (match_operand:HI 3 "memory_operand" "m,m"))
4326    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4327    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4328   "TARGET_80387 && !TARGET_FISTTP
4329    && FLOAT_MODE_P (GET_MODE (operands[1]))
4330    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4331   "#"
4332   [(set_attr "type" "fistp")
4333    (set_attr "i387_cw" "trunc")
4334    (set_attr "mode" "DI")])
4336 (define_split 
4337   [(set (match_operand:DI 0 "register_operand" "")
4338         (fix:DI (match_operand 1 "register_operand" "")))
4339    (use (match_operand:HI 2 "memory_operand" ""))
4340    (use (match_operand:HI 3 "memory_operand" ""))
4341    (clobber (match_operand:DI 4 "memory_operand" ""))
4342    (clobber (match_scratch 5 ""))]
4343   "reload_completed"
4344   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4345               (use (match_dup 2))
4346               (use (match_dup 3))
4347               (clobber (match_dup 5))])
4348    (set (match_dup 0) (match_dup 4))]
4349   "")
4351 (define_split 
4352   [(set (match_operand:DI 0 "memory_operand" "")
4353         (fix:DI (match_operand 1 "register_operand" "")))
4354    (use (match_operand:HI 2 "memory_operand" ""))
4355    (use (match_operand:HI 3 "memory_operand" ""))
4356    (clobber (match_operand:DI 4 "memory_operand" ""))
4357    (clobber (match_scratch 5 ""))]
4358   "reload_completed"
4359   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4360               (use (match_dup 2))
4361               (use (match_dup 3))
4362               (clobber (match_dup 5))])]
4363   "")
4365 (define_insn "fix_trunc<mode>_i387"
4366   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4367         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4368    (use (match_operand:HI 2 "memory_operand" "m"))
4369    (use (match_operand:HI 3 "memory_operand" "m"))]
4370   "TARGET_80387 && !TARGET_FISTTP
4371    && FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4373   "* return output_fix_trunc (insn, operands, 0);"
4374   [(set_attr "type" "fistp")
4375    (set_attr "i387_cw" "trunc")
4376    (set_attr "mode" "<MODE>")])
4378 (define_insn "fix_trunc<mode>_i387_with_temp"
4379   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4380         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4381    (use (match_operand:HI 2 "memory_operand" "m,m"))
4382    (use (match_operand:HI 3 "memory_operand" "m,m"))
4383    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4384   "TARGET_80387 && !TARGET_FISTTP
4385    && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "<MODE>")])
4392 (define_split 
4393   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4394         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4398   "reload_completed"
4399   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4400               (use (match_dup 2))
4401               (use (match_dup 3))])
4402    (set (match_dup 0) (match_dup 4))]
4403   "")
4405 (define_split 
4406   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4407         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4408    (use (match_operand:HI 2 "memory_operand" ""))
4409    (use (match_operand:HI 3 "memory_operand" ""))
4410    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4411   "reload_completed"
4412   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4413               (use (match_dup 2))
4414               (use (match_dup 3))])]
4415   "")
4417 (define_insn "x86_fnstcw_1"
4418   [(set (match_operand:HI 0 "memory_operand" "=m")
4419         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4420   "TARGET_80387"
4421   "fnstcw\t%0"
4422   [(set_attr "length" "2")
4423    (set_attr "mode" "HI")
4424    (set_attr "unit" "i387")])
4426 (define_insn "x86_fldcw_1"
4427   [(set (reg:HI FPSR_REG)
4428         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4429   "TARGET_80387"
4430   "fldcw\t%0"
4431   [(set_attr "length" "2")
4432    (set_attr "mode" "HI")
4433    (set_attr "unit" "i387")
4434    (set_attr "athlon_decode" "vector")])
4436 ;; Conversion between fixed point and floating point.
4438 ;; Even though we only accept memory inputs, the backend _really_
4439 ;; wants to be able to do this between registers.
4441 (define_expand "floathisf2"
4442   [(set (match_operand:SF 0 "register_operand" "")
4443         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4444   "TARGET_80387 || TARGET_SSE_MATH"
4446   if (TARGET_SSE_MATH)
4447     {
4448       emit_insn (gen_floatsisf2 (operands[0],
4449                                  convert_to_mode (SImode, operands[1], 0)));
4450       DONE;
4451     }
4454 (define_insn "*floathisf2_i387"
4455   [(set (match_operand:SF 0 "register_operand" "=f,f")
4456         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4457   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4458   "@
4459    fild%z1\t%1
4460    #"
4461   [(set_attr "type" "fmov,multi")
4462    (set_attr "mode" "SF")
4463    (set_attr "unit" "*,i387")
4464    (set_attr "fp_int_src" "true")])
4466 (define_expand "floatsisf2"
4467   [(set (match_operand:SF 0 "register_operand" "")
4468         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4469   "TARGET_80387 || TARGET_SSE_MATH"
4470   "")
4472 (define_insn "*floatsisf2_mixed"
4473   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4474         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4475   "TARGET_MIX_SSE_I387"
4476   "@
4477    fild%z1\t%1
4478    #
4479    cvtsi2ss\t{%1, %0|%0, %1}
4480    cvtsi2ss\t{%1, %0|%0, %1}"
4481   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4482    (set_attr "mode" "SF")
4483    (set_attr "unit" "*,i387,*,*")
4484    (set_attr "athlon_decode" "*,*,vector,double")
4485    (set_attr "fp_int_src" "true")])
4487 (define_insn "*floatsisf2_sse"
4488   [(set (match_operand:SF 0 "register_operand" "=x,x")
4489         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4490   "TARGET_SSE_MATH"
4491   "cvtsi2ss\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "athlon_decode" "vector,double")
4495    (set_attr "fp_int_src" "true")])
4497 (define_insn "*floatsisf2_i387"
4498   [(set (match_operand:SF 0 "register_operand" "=f,f")
4499         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4500   "TARGET_80387"
4501   "@
4502    fild%z1\t%1
4503    #"
4504   [(set_attr "type" "fmov,multi")
4505    (set_attr "mode" "SF")
4506    (set_attr "unit" "*,i387")
4507    (set_attr "fp_int_src" "true")])
4509 (define_expand "floatdisf2"
4510   [(set (match_operand:SF 0 "register_operand" "")
4511         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4512   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4513   "")
4515 (define_insn "*floatdisf2_mixed"
4516   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4517         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4518   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4519   "@
4520    fild%z1\t%1
4521    #
4522    cvtsi2ss{q}\t{%1, %0|%0, %1}
4523    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4524   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4525    (set_attr "mode" "SF")
4526    (set_attr "unit" "*,i387,*,*")
4527    (set_attr "athlon_decode" "*,*,vector,double")
4528    (set_attr "fp_int_src" "true")])
4530 (define_insn "*floatdisf2_sse"
4531   [(set (match_operand:SF 0 "register_operand" "=x,x")
4532         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4533   "TARGET_64BIT && TARGET_SSE_MATH"
4534   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4535   [(set_attr "type" "sseicvt")
4536    (set_attr "mode" "SF")
4537    (set_attr "athlon_decode" "vector,double")
4538    (set_attr "fp_int_src" "true")])
4540 (define_insn "*floatdisf2_i387"
4541   [(set (match_operand:SF 0 "register_operand" "=f,f")
4542         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4543   "TARGET_80387"
4544   "@
4545    fild%z1\t%1
4546    #"
4547   [(set_attr "type" "fmov,multi")
4548    (set_attr "mode" "SF")
4549    (set_attr "unit" "*,i387")
4550    (set_attr "fp_int_src" "true")])
4552 (define_expand "floathidf2"
4553   [(set (match_operand:DF 0 "register_operand" "")
4554         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4555   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4557   if (TARGET_SSE2 && TARGET_SSE_MATH)
4558     {
4559       emit_insn (gen_floatsidf2 (operands[0],
4560                                  convert_to_mode (SImode, operands[1], 0)));
4561       DONE;
4562     }
4565 (define_insn "*floathidf2_i387"
4566   [(set (match_operand:DF 0 "register_operand" "=f,f")
4567         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4568   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4569   "@
4570    fild%z1\t%1
4571    #"
4572   [(set_attr "type" "fmov,multi")
4573    (set_attr "mode" "DF")
4574    (set_attr "unit" "*,i387")
4575    (set_attr "fp_int_src" "true")])
4577 (define_expand "floatsidf2"
4578   [(set (match_operand:DF 0 "register_operand" "")
4579         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4580   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4581   "")
4583 (define_insn "*floatsidf2_mixed"
4584   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4586   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4587   "@
4588    fild%z1\t%1
4589    #
4590    cvtsi2sd\t{%1, %0|%0, %1}
4591    cvtsi2sd\t{%1, %0|%0, %1}"
4592   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4593    (set_attr "mode" "DF")
4594    (set_attr "unit" "*,i387,*,*")
4595    (set_attr "athlon_decode" "*,*,double,direct")
4596    (set_attr "fp_int_src" "true")])
4598 (define_insn "*floatsidf2_sse"
4599   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4600         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4601   "TARGET_SSE2 && TARGET_SSE_MATH"
4602   "cvtsi2sd\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "athlon_decode" "double,direct")
4606    (set_attr "fp_int_src" "true")])
4608 (define_insn "*floatsidf2_i387"
4609   [(set (match_operand:DF 0 "register_operand" "=f,f")
4610         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4611   "TARGET_80387"
4612   "@
4613    fild%z1\t%1
4614    #"
4615   [(set_attr "type" "fmov,multi")
4616    (set_attr "mode" "DF")
4617    (set_attr "unit" "*,i387")
4618    (set_attr "fp_int_src" "true")])
4620 (define_expand "floatdidf2"
4621   [(set (match_operand:DF 0 "register_operand" "")
4622         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4623   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4624   "")
4626 (define_insn "*floatdidf2_mixed"
4627   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4628         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4629   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4630   "@
4631    fild%z1\t%1
4632    #
4633    cvtsi2sd{q}\t{%1, %0|%0, %1}
4634    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4635   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4636    (set_attr "mode" "DF")
4637    (set_attr "unit" "*,i387,*,*")
4638    (set_attr "athlon_decode" "*,*,double,direct")
4639    (set_attr "fp_int_src" "true")])
4641 (define_insn "*floatdidf2_sse"
4642   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4643         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4644   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4645   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4646   [(set_attr "type" "sseicvt")
4647    (set_attr "mode" "DF")
4648    (set_attr "athlon_decode" "double,direct")
4649    (set_attr "fp_int_src" "true")])
4651 (define_insn "*floatdidf2_i387"
4652   [(set (match_operand:DF 0 "register_operand" "=f,f")
4653         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4654   "TARGET_80387"
4655   "@
4656    fild%z1\t%1
4657    #"
4658   [(set_attr "type" "fmov,multi")
4659    (set_attr "mode" "DF")
4660    (set_attr "unit" "*,i387")
4661    (set_attr "fp_int_src" "true")])
4663 (define_insn "floathixf2"
4664   [(set (match_operand:XF 0 "register_operand" "=f,f")
4665         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4666   "TARGET_80387"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "XF")
4672    (set_attr "unit" "*,i387")
4673    (set_attr "fp_int_src" "true")])
4675 (define_insn "floatsixf2"
4676   [(set (match_operand:XF 0 "register_operand" "=f,f")
4677         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "XF")
4684    (set_attr "unit" "*,i387")
4685    (set_attr "fp_int_src" "true")])
4687 (define_insn "floatdixf2"
4688   [(set (match_operand:XF 0 "register_operand" "=f,f")
4689         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4690   "TARGET_80387"
4691   "@
4692    fild%z1\t%1
4693    #"
4694   [(set_attr "type" "fmov,multi")
4695    (set_attr "mode" "XF")
4696    (set_attr "unit" "*,i387")
4697    (set_attr "fp_int_src" "true")])
4699 ;; %%% Kill these when reload knows how to do it.
4700 (define_split
4701   [(set (match_operand 0 "fp_register_operand" "")
4702         (float (match_operand 1 "register_operand" "")))]
4703   "reload_completed
4704    && TARGET_80387
4705    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4706   [(const_int 0)]
4708   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4709   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4710   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4711   ix86_free_from_memory (GET_MODE (operands[1]));
4712   DONE;
4715 (define_expand "floatunssisf2"
4716   [(use (match_operand:SF 0 "register_operand" ""))
4717    (use (match_operand:SI 1 "register_operand" ""))]
4718   "!TARGET_64BIT && TARGET_SSE_MATH"
4719   "x86_emit_floatuns (operands); DONE;")
4721 (define_expand "floatunsdisf2"
4722   [(use (match_operand:SF 0 "register_operand" ""))
4723    (use (match_operand:DI 1 "register_operand" ""))]
4724   "TARGET_64BIT && TARGET_SSE_MATH"
4725   "x86_emit_floatuns (operands); DONE;")
4727 (define_expand "floatunsdidf2"
4728   [(use (match_operand:DF 0 "register_operand" ""))
4729    (use (match_operand:DI 1 "register_operand" ""))]
4730   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731   "x86_emit_floatuns (operands); DONE;")
4733 ;; SSE extract/set expanders
4736 ;; Add instructions
4738 ;; %%% splits for addditi3
4740 (define_expand "addti3"
4741   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4742         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4743                  (match_operand:TI 2 "x86_64_general_operand" "")))
4744    (clobber (reg:CC FLAGS_REG))]
4745   "TARGET_64BIT"
4746   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4748 (define_insn "*addti3_1"
4749   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4750         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4751                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4754   "#")
4756 (define_split
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759                  (match_operand:TI 2 "general_operand" "")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT && reload_completed"
4762   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4763                                           UNSPEC_ADD_CARRY))
4764               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4765    (parallel [(set (match_dup 3)
4766                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4767                                      (match_dup 4))
4768                             (match_dup 5)))
4769               (clobber (reg:CC FLAGS_REG))])]
4770   "split_ti (operands+0, 1, operands+0, operands+3);
4771    split_ti (operands+1, 1, operands+1, operands+4);
4772    split_ti (operands+2, 1, operands+2, operands+5);")
4774 ;; %%% splits for addsidi3
4775 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4776 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4777 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4779 (define_expand "adddi3"
4780   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4781         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4782                  (match_operand:DI 2 "x86_64_general_operand" "")))
4783    (clobber (reg:CC FLAGS_REG))]
4784   ""
4785   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4787 (define_insn "*adddi3_1"
4788   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4789         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4790                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4791    (clobber (reg:CC FLAGS_REG))]
4792   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4793   "#")
4795 (define_split
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798                  (match_operand:DI 2 "general_operand" "")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "!TARGET_64BIT && reload_completed"
4801   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4802                                           UNSPEC_ADD_CARRY))
4803               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4804    (parallel [(set (match_dup 3)
4805                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4806                                      (match_dup 4))
4807                             (match_dup 5)))
4808               (clobber (reg:CC FLAGS_REG))])]
4809   "split_di (operands+0, 1, operands+0, operands+3);
4810    split_di (operands+1, 1, operands+1, operands+4);
4811    split_di (operands+2, 1, operands+2, operands+5);")
4813 (define_insn "adddi3_carry_rex64"
4814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4815           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4816                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4817                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4818    (clobber (reg:CC FLAGS_REG))]
4819   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4820   "adc{q}\t{%2, %0|%0, %2}"
4821   [(set_attr "type" "alu")
4822    (set_attr "pent_pair" "pu")
4823    (set_attr "mode" "DI")])
4825 (define_insn "*adddi3_cc_rex64"
4826   [(set (reg:CC FLAGS_REG)
4827         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4829                    UNSPEC_ADD_CARRY))
4830    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831         (plus:DI (match_dup 1) (match_dup 2)))]
4832   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4833   "add{q}\t{%2, %0|%0, %2}"
4834   [(set_attr "type" "alu")
4835    (set_attr "mode" "DI")])
4837 (define_insn "addqi3_carry"
4838   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4839           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4840                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4841                    (match_operand:QI 2 "general_operand" "qi,qm")))
4842    (clobber (reg:CC FLAGS_REG))]
4843   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4844   "adc{b}\t{%2, %0|%0, %2}"
4845   [(set_attr "type" "alu")
4846    (set_attr "pent_pair" "pu")
4847    (set_attr "mode" "QI")])
4849 (define_insn "addhi3_carry"
4850   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4851           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4852                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4853                    (match_operand:HI 2 "general_operand" "ri,rm")))
4854    (clobber (reg:CC FLAGS_REG))]
4855   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4856   "adc{w}\t{%2, %0|%0, %2}"
4857   [(set_attr "type" "alu")
4858    (set_attr "pent_pair" "pu")
4859    (set_attr "mode" "HI")])
4861 (define_insn "addsi3_carry"
4862   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4863           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4864                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4865                    (match_operand:SI 2 "general_operand" "ri,rm")))
4866    (clobber (reg:CC FLAGS_REG))]
4867   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4868   "adc{l}\t{%2, %0|%0, %2}"
4869   [(set_attr "type" "alu")
4870    (set_attr "pent_pair" "pu")
4871    (set_attr "mode" "SI")])
4873 (define_insn "*addsi3_carry_zext"
4874   [(set (match_operand:DI 0 "register_operand" "=r")
4875           (zero_extend:DI 
4876             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4877                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4878                      (match_operand:SI 2 "general_operand" "rim"))))
4879    (clobber (reg:CC FLAGS_REG))]
4880   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4881   "adc{l}\t{%2, %k0|%k0, %2}"
4882   [(set_attr "type" "alu")
4883    (set_attr "pent_pair" "pu")
4884    (set_attr "mode" "SI")])
4886 (define_insn "*addsi3_cc"
4887   [(set (reg:CC FLAGS_REG)
4888         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4889                     (match_operand:SI 2 "general_operand" "ri,rm")]
4890                    UNSPEC_ADD_CARRY))
4891    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4892         (plus:SI (match_dup 1) (match_dup 2)))]
4893   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4894   "add{l}\t{%2, %0|%0, %2}"
4895   [(set_attr "type" "alu")
4896    (set_attr "mode" "SI")])
4898 (define_insn "addqi3_cc"
4899   [(set (reg:CC FLAGS_REG)
4900         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4901                     (match_operand:QI 2 "general_operand" "qi,qm")]
4902                    UNSPEC_ADD_CARRY))
4903    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4904         (plus:QI (match_dup 1) (match_dup 2)))]
4905   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4906   "add{b}\t{%2, %0|%0, %2}"
4907   [(set_attr "type" "alu")
4908    (set_attr "mode" "QI")])
4910 (define_expand "addsi3"
4911   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4912                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4913                             (match_operand:SI 2 "general_operand" "")))
4914               (clobber (reg:CC FLAGS_REG))])]
4915   ""
4916   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4918 (define_insn "*lea_1"
4919   [(set (match_operand:SI 0 "register_operand" "=r")
4920         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4921   "!TARGET_64BIT"
4922   "lea{l}\t{%a1, %0|%0, %a1}"
4923   [(set_attr "type" "lea")
4924    (set_attr "mode" "SI")])
4926 (define_insn "*lea_1_rex64"
4927   [(set (match_operand:SI 0 "register_operand" "=r")
4928         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4929   "TARGET_64BIT"
4930   "lea{l}\t{%a1, %0|%0, %a1}"
4931   [(set_attr "type" "lea")
4932    (set_attr "mode" "SI")])
4934 (define_insn "*lea_1_zext"
4935   [(set (match_operand:DI 0 "register_operand" "=r")
4936         (zero_extend:DI
4937          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4938   "TARGET_64BIT"
4939   "lea{l}\t{%a1, %k0|%k0, %a1}"
4940   [(set_attr "type" "lea")
4941    (set_attr "mode" "SI")])
4943 (define_insn "*lea_2_rex64"
4944   [(set (match_operand:DI 0 "register_operand" "=r")
4945         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4946   "TARGET_64BIT"
4947   "lea{q}\t{%a1, %0|%0, %a1}"
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "DI")])
4951 ;; The lea patterns for non-Pmodes needs to be matched by several
4952 ;; insns converted to real lea by splitters.
4954 (define_insn_and_split "*lea_general_1"
4955   [(set (match_operand 0 "register_operand" "=r")
4956         (plus (plus (match_operand 1 "index_register_operand" "l")
4957                     (match_operand 2 "register_operand" "r"))
4958               (match_operand 3 "immediate_operand" "i")))]
4959   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4960     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4961    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4962    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4963    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4964    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4965        || GET_MODE (operands[3]) == VOIDmode)"
4966   "#"
4967   "&& reload_completed"
4968   [(const_int 0)]
4970   rtx pat;
4971   operands[0] = gen_lowpart (SImode, operands[0]);
4972   operands[1] = gen_lowpart (Pmode, operands[1]);
4973   operands[2] = gen_lowpart (Pmode, operands[2]);
4974   operands[3] = gen_lowpart (Pmode, operands[3]);
4975   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4976                       operands[3]);
4977   if (Pmode != SImode)
4978     pat = gen_rtx_SUBREG (SImode, pat, 0);
4979   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4980   DONE;
4982   [(set_attr "type" "lea")
4983    (set_attr "mode" "SI")])
4985 (define_insn_and_split "*lea_general_1_zext"
4986   [(set (match_operand:DI 0 "register_operand" "=r")
4987         (zero_extend:DI
4988           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4989                             (match_operand:SI 2 "register_operand" "r"))
4990                    (match_operand:SI 3 "immediate_operand" "i"))))]
4991   "TARGET_64BIT"
4992   "#"
4993   "&& reload_completed"
4994   [(set (match_dup 0)
4995         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4996                                                      (match_dup 2))
4997                                             (match_dup 3)) 0)))]
4999   operands[1] = gen_lowpart (Pmode, operands[1]);
5000   operands[2] = gen_lowpart (Pmode, operands[2]);
5001   operands[3] = gen_lowpart (Pmode, operands[3]);
5003   [(set_attr "type" "lea")
5004    (set_attr "mode" "SI")])
5006 (define_insn_and_split "*lea_general_2"
5007   [(set (match_operand 0 "register_operand" "=r")
5008         (plus (mult (match_operand 1 "index_register_operand" "l")
5009                     (match_operand 2 "const248_operand" "i"))
5010               (match_operand 3 "nonmemory_operand" "ri")))]
5011   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5012     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5013    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5014    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5015    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5016        || GET_MODE (operands[3]) == VOIDmode)"
5017   "#"
5018   "&& reload_completed"
5019   [(const_int 0)]
5021   rtx pat;
5022   operands[0] = gen_lowpart (SImode, operands[0]);
5023   operands[1] = gen_lowpart (Pmode, operands[1]);
5024   operands[3] = gen_lowpart (Pmode, operands[3]);
5025   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5026                       operands[3]);
5027   if (Pmode != SImode)
5028     pat = gen_rtx_SUBREG (SImode, pat, 0);
5029   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5030   DONE;
5032   [(set_attr "type" "lea")
5033    (set_attr "mode" "SI")])
5035 (define_insn_and_split "*lea_general_2_zext"
5036   [(set (match_operand:DI 0 "register_operand" "=r")
5037         (zero_extend:DI
5038           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5039                             (match_operand:SI 2 "const248_operand" "n"))
5040                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5041   "TARGET_64BIT"
5042   "#"
5043   "&& reload_completed"
5044   [(set (match_dup 0)
5045         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5046                                                      (match_dup 2))
5047                                             (match_dup 3)) 0)))]
5049   operands[1] = gen_lowpart (Pmode, operands[1]);
5050   operands[3] = gen_lowpart (Pmode, operands[3]);
5052   [(set_attr "type" "lea")
5053    (set_attr "mode" "SI")])
5055 (define_insn_and_split "*lea_general_3"
5056   [(set (match_operand 0 "register_operand" "=r")
5057         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5058                           (match_operand 2 "const248_operand" "i"))
5059                     (match_operand 3 "register_operand" "r"))
5060               (match_operand 4 "immediate_operand" "i")))]
5061   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5062     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5063    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5064    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5065    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5066   "#"
5067   "&& reload_completed"
5068   [(const_int 0)]
5070   rtx pat;
5071   operands[0] = gen_lowpart (SImode, operands[0]);
5072   operands[1] = gen_lowpart (Pmode, operands[1]);
5073   operands[3] = gen_lowpart (Pmode, operands[3]);
5074   operands[4] = gen_lowpart (Pmode, operands[4]);
5075   pat = gen_rtx_PLUS (Pmode,
5076                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5077                                                          operands[2]),
5078                                     operands[3]),
5079                       operands[4]);
5080   if (Pmode != SImode)
5081     pat = gen_rtx_SUBREG (SImode, pat, 0);
5082   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5083   DONE;
5085   [(set_attr "type" "lea")
5086    (set_attr "mode" "SI")])
5088 (define_insn_and_split "*lea_general_3_zext"
5089   [(set (match_operand:DI 0 "register_operand" "=r")
5090         (zero_extend:DI
5091           (plus:SI (plus:SI (mult:SI
5092                               (match_operand:SI 1 "index_register_operand" "l")
5093                               (match_operand:SI 2 "const248_operand" "n"))
5094                             (match_operand:SI 3 "register_operand" "r"))
5095                    (match_operand:SI 4 "immediate_operand" "i"))))]
5096   "TARGET_64BIT"
5097   "#"
5098   "&& reload_completed"
5099   [(set (match_dup 0)
5100         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5101                                                               (match_dup 2))
5102                                                      (match_dup 3))
5103                                             (match_dup 4)) 0)))]
5105   operands[1] = gen_lowpart (Pmode, operands[1]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5107   operands[4] = gen_lowpart (Pmode, operands[4]);
5109   [(set_attr "type" "lea")
5110    (set_attr "mode" "SI")])
5112 (define_insn "*adddi_1_rex64"
5113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5114         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5115                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5116    (clobber (reg:CC FLAGS_REG))]
5117   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5119   switch (get_attr_type (insn))
5120     {
5121     case TYPE_LEA:
5122       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5123       return "lea{q}\t{%a2, %0|%0, %a2}";
5125     case TYPE_INCDEC:
5126       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5127       if (operands[2] == const1_rtx)
5128         return "inc{q}\t%0";
5129       else
5130         {
5131           gcc_assert (operands[2] == constm1_rtx);
5132           return "dec{q}\t%0";
5133         }
5135     default:
5136       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5140       if (GET_CODE (operands[2]) == CONST_INT
5141           /* Avoid overflows.  */
5142           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5143           && (INTVAL (operands[2]) == 128
5144               || (INTVAL (operands[2]) < 0
5145                   && INTVAL (operands[2]) != -128)))
5146         {
5147           operands[2] = GEN_INT (-INTVAL (operands[2]));
5148           return "sub{q}\t{%2, %0|%0, %2}";
5149         }
5150       return "add{q}\t{%2, %0|%0, %2}";
5151     }
5153   [(set (attr "type")
5154      (cond [(eq_attr "alternative" "2")
5155               (const_string "lea")
5156             ; Current assemblers are broken and do not allow @GOTOFF in
5157             ; ought but a memory context.
5158             (match_operand:DI 2 "pic_symbolic_operand" "")
5159               (const_string "lea")
5160             (match_operand:DI 2 "incdec_operand" "")
5161               (const_string "incdec")
5162            ]
5163            (const_string "alu")))
5164    (set_attr "mode" "DI")])
5166 ;; Convert lea to the lea pattern to avoid flags dependency.
5167 (define_split
5168   [(set (match_operand:DI 0 "register_operand" "")
5169         (plus:DI (match_operand:DI 1 "register_operand" "")
5170                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5171    (clobber (reg:CC FLAGS_REG))]
5172   "TARGET_64BIT && reload_completed
5173    && true_regnum (operands[0]) != true_regnum (operands[1])"
5174   [(set (match_dup 0)
5175         (plus:DI (match_dup 1)
5176                  (match_dup 2)))]
5177   "")
5179 (define_insn "*adddi_2_rex64"
5180   [(set (reg FLAGS_REG)
5181         (compare
5182           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5183                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5184           (const_int 0)))                       
5185    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5186         (plus:DI (match_dup 1) (match_dup 2)))]
5187   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5188    && ix86_binary_operator_ok (PLUS, DImode, operands)
5189    /* Current assemblers are broken and do not allow @GOTOFF in
5190       ought but a memory context.  */
5191    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5193   switch (get_attr_type (insn))
5194     {
5195     case TYPE_INCDEC:
5196       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5197       if (operands[2] == const1_rtx)
5198         return "inc{q}\t%0";
5199       else
5200         {
5201           gcc_assert (operands[2] == constm1_rtx);
5202           return "dec{q}\t%0";
5203         }
5205     default:
5206       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5207       /* ???? We ought to handle there the 32bit case too
5208          - do we need new constraint?  */
5209       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5210          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5211       if (GET_CODE (operands[2]) == CONST_INT
5212           /* Avoid overflows.  */
5213           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5214           && (INTVAL (operands[2]) == 128
5215               || (INTVAL (operands[2]) < 0
5216                   && INTVAL (operands[2]) != -128)))
5217         {
5218           operands[2] = GEN_INT (-INTVAL (operands[2]));
5219           return "sub{q}\t{%2, %0|%0, %2}";
5220         }
5221       return "add{q}\t{%2, %0|%0, %2}";
5222     }
5224   [(set (attr "type")
5225      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5226         (const_string "incdec")
5227         (const_string "alu")))
5228    (set_attr "mode" "DI")])
5230 (define_insn "*adddi_3_rex64"
5231   [(set (reg FLAGS_REG)
5232         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5233                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5234    (clobber (match_scratch:DI 0 "=r"))]
5235   "TARGET_64BIT
5236    && ix86_match_ccmode (insn, CCZmode)
5237    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5238    /* Current assemblers are broken and do not allow @GOTOFF in
5239       ought but a memory context.  */
5240    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5242   switch (get_attr_type (insn))
5243     {
5244     case TYPE_INCDEC:
5245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5246       if (operands[2] == const1_rtx)
5247         return "inc{q}\t%0";
5248       else
5249         {
5250           gcc_assert (operands[2] == constm1_rtx);
5251           return "dec{q}\t%0";
5252         }
5254     default:
5255       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5256       /* ???? We ought to handle there the 32bit case too
5257          - do we need new constraint?  */
5258       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5259          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5260       if (GET_CODE (operands[2]) == CONST_INT
5261           /* Avoid overflows.  */
5262           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5263           && (INTVAL (operands[2]) == 128
5264               || (INTVAL (operands[2]) < 0
5265                   && INTVAL (operands[2]) != -128)))
5266         {
5267           operands[2] = GEN_INT (-INTVAL (operands[2]));
5268           return "sub{q}\t{%2, %0|%0, %2}";
5269         }
5270       return "add{q}\t{%2, %0|%0, %2}";
5271     }
5273   [(set (attr "type")
5274      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5275         (const_string "incdec")
5276         (const_string "alu")))
5277    (set_attr "mode" "DI")])
5279 ; For comparisons against 1, -1 and 128, we may generate better code
5280 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5281 ; is matched then.  We can't accept general immediate, because for
5282 ; case of overflows,  the result is messed up.
5283 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5284 ; when negated.
5285 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5286 ; only for comparisons not depending on it.
5287 (define_insn "*adddi_4_rex64"
5288   [(set (reg FLAGS_REG)
5289         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5290                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5291    (clobber (match_scratch:DI 0 "=rm"))]
5292   "TARGET_64BIT
5293    &&  ix86_match_ccmode (insn, CCGCmode)"
5295   switch (get_attr_type (insn))
5296     {
5297     case TYPE_INCDEC:
5298       if (operands[2] == constm1_rtx)
5299         return "inc{q}\t%0";
5300       else
5301         {
5302           gcc_assert (operands[2] == const1_rtx);
5303           return "dec{q}\t%0";
5304         }
5306     default:
5307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5310       if ((INTVAL (operands[2]) == -128
5311            || (INTVAL (operands[2]) > 0
5312                && INTVAL (operands[2]) != 128))
5313           /* Avoid overflows.  */
5314           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5315         return "sub{q}\t{%2, %0|%0, %2}";
5316       operands[2] = GEN_INT (-INTVAL (operands[2]));
5317       return "add{q}\t{%2, %0|%0, %2}";
5318     }
5320   [(set (attr "type")
5321      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5322         (const_string "incdec")
5323         (const_string "alu")))
5324    (set_attr "mode" "DI")])
5326 (define_insn "*adddi_5_rex64"
5327   [(set (reg FLAGS_REG)
5328         (compare
5329           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5330                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5331           (const_int 0)))                       
5332    (clobber (match_scratch:DI 0 "=r"))]
5333   "TARGET_64BIT
5334    && ix86_match_ccmode (insn, CCGOCmode)
5335    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5336    /* Current assemblers are broken and do not allow @GOTOFF in
5337       ought but a memory context.  */
5338    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5340   switch (get_attr_type (insn))
5341     {
5342     case TYPE_INCDEC:
5343       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5344       if (operands[2] == const1_rtx)
5345         return "inc{q}\t%0";
5346       else
5347         {
5348           gcc_assert (operands[2] == constm1_rtx);
5349           return "dec{q}\t%0";
5350         }
5352     default:
5353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5355          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5356       if (GET_CODE (operands[2]) == CONST_INT
5357           /* Avoid overflows.  */
5358           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5359           && (INTVAL (operands[2]) == 128
5360               || (INTVAL (operands[2]) < 0
5361                   && INTVAL (operands[2]) != -128)))
5362         {
5363           operands[2] = GEN_INT (-INTVAL (operands[2]));
5364           return "sub{q}\t{%2, %0|%0, %2}";
5365         }
5366       return "add{q}\t{%2, %0|%0, %2}";
5367     }
5369   [(set (attr "type")
5370      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5371         (const_string "incdec")
5372         (const_string "alu")))
5373    (set_attr "mode" "DI")])
5376 (define_insn "*addsi_1"
5377   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5378         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5379                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5380    (clobber (reg:CC FLAGS_REG))]
5381   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5383   switch (get_attr_type (insn))
5384     {
5385     case TYPE_LEA:
5386       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5387       return "lea{l}\t{%a2, %0|%0, %a2}";
5389     case TYPE_INCDEC:
5390       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5391       if (operands[2] == const1_rtx)
5392         return "inc{l}\t%0";
5393       else
5394         {
5395           gcc_assert (operands[2] == constm1_rtx);
5396           return "dec{l}\t%0";
5397         }
5399     default:
5400       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5403          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5404       if (GET_CODE (operands[2]) == CONST_INT
5405           && (INTVAL (operands[2]) == 128
5406               || (INTVAL (operands[2]) < 0
5407                   && INTVAL (operands[2]) != -128)))
5408         {
5409           operands[2] = GEN_INT (-INTVAL (operands[2]));
5410           return "sub{l}\t{%2, %0|%0, %2}";
5411         }
5412       return "add{l}\t{%2, %0|%0, %2}";
5413     }
5415   [(set (attr "type")
5416      (cond [(eq_attr "alternative" "2")
5417               (const_string "lea")
5418             ; Current assemblers are broken and do not allow @GOTOFF in
5419             ; ought but a memory context.
5420             (match_operand:SI 2 "pic_symbolic_operand" "")
5421               (const_string "lea")
5422             (match_operand:SI 2 "incdec_operand" "")
5423               (const_string "incdec")
5424            ]
5425            (const_string "alu")))
5426    (set_attr "mode" "SI")])
5428 ;; Convert lea to the lea pattern to avoid flags dependency.
5429 (define_split
5430   [(set (match_operand 0 "register_operand" "")
5431         (plus (match_operand 1 "register_operand" "")
5432               (match_operand 2 "nonmemory_operand" "")))
5433    (clobber (reg:CC FLAGS_REG))]
5434   "reload_completed
5435    && true_regnum (operands[0]) != true_regnum (operands[1])"
5436   [(const_int 0)]
5438   rtx pat;
5439   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5440      may confuse gen_lowpart.  */
5441   if (GET_MODE (operands[0]) != Pmode)
5442     {
5443       operands[1] = gen_lowpart (Pmode, operands[1]);
5444       operands[2] = gen_lowpart (Pmode, operands[2]);
5445     }
5446   operands[0] = gen_lowpart (SImode, operands[0]);
5447   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5448   if (Pmode != SImode)
5449     pat = gen_rtx_SUBREG (SImode, pat, 0);
5450   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5451   DONE;
5454 ;; It may seem that nonimmediate operand is proper one for operand 1.
5455 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5456 ;; we take care in ix86_binary_operator_ok to not allow two memory
5457 ;; operands so proper swapping will be done in reload.  This allow
5458 ;; patterns constructed from addsi_1 to match.
5459 (define_insn "addsi_1_zext"
5460   [(set (match_operand:DI 0 "register_operand" "=r,r")
5461         (zero_extend:DI
5462           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5463                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5464    (clobber (reg:CC FLAGS_REG))]
5465   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5467   switch (get_attr_type (insn))
5468     {
5469     case TYPE_LEA:
5470       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5471       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5473     case TYPE_INCDEC:
5474       if (operands[2] == const1_rtx)
5475         return "inc{l}\t%k0";
5476       else
5477         {
5478           gcc_assert (operands[2] == constm1_rtx);
5479           return "dec{l}\t%k0";
5480         }
5482     default:
5483       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5484          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5485       if (GET_CODE (operands[2]) == CONST_INT
5486           && (INTVAL (operands[2]) == 128
5487               || (INTVAL (operands[2]) < 0
5488                   && INTVAL (operands[2]) != -128)))
5489         {
5490           operands[2] = GEN_INT (-INTVAL (operands[2]));
5491           return "sub{l}\t{%2, %k0|%k0, %2}";
5492         }
5493       return "add{l}\t{%2, %k0|%k0, %2}";
5494     }
5496   [(set (attr "type")
5497      (cond [(eq_attr "alternative" "1")
5498               (const_string "lea")
5499             ; Current assemblers are broken and do not allow @GOTOFF in
5500             ; ought but a memory context.
5501             (match_operand:SI 2 "pic_symbolic_operand" "")
5502               (const_string "lea")
5503             (match_operand:SI 2 "incdec_operand" "")
5504               (const_string "incdec")
5505            ]
5506            (const_string "alu")))
5507    (set_attr "mode" "SI")])
5509 ;; Convert lea to the lea pattern to avoid flags dependency.
5510 (define_split
5511   [(set (match_operand:DI 0 "register_operand" "")
5512         (zero_extend:DI
5513           (plus:SI (match_operand:SI 1 "register_operand" "")
5514                    (match_operand:SI 2 "nonmemory_operand" ""))))
5515    (clobber (reg:CC FLAGS_REG))]
5516   "TARGET_64BIT && reload_completed
5517    && true_regnum (operands[0]) != true_regnum (operands[1])"
5518   [(set (match_dup 0)
5519         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5521   operands[1] = gen_lowpart (Pmode, operands[1]);
5522   operands[2] = gen_lowpart (Pmode, operands[2]);
5525 (define_insn "*addsi_2"
5526   [(set (reg FLAGS_REG)
5527         (compare
5528           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5529                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5530           (const_int 0)))                       
5531    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5532         (plus:SI (match_dup 1) (match_dup 2)))]
5533   "ix86_match_ccmode (insn, CCGOCmode)
5534    && ix86_binary_operator_ok (PLUS, SImode, operands)
5535    /* Current assemblers are broken and do not allow @GOTOFF in
5536       ought but a memory context.  */
5537    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5539   switch (get_attr_type (insn))
5540     {
5541     case TYPE_INCDEC:
5542       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543       if (operands[2] == const1_rtx)
5544         return "inc{l}\t%0";
5545       else
5546         {
5547           gcc_assert (operands[2] == constm1_rtx);
5548           return "dec{l}\t%0";
5549         }
5551     default:
5552       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5553       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5554          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5555       if (GET_CODE (operands[2]) == CONST_INT
5556           && (INTVAL (operands[2]) == 128
5557               || (INTVAL (operands[2]) < 0
5558                   && INTVAL (operands[2]) != -128)))
5559         {
5560           operands[2] = GEN_INT (-INTVAL (operands[2]));
5561           return "sub{l}\t{%2, %0|%0, %2}";
5562         }
5563       return "add{l}\t{%2, %0|%0, %2}";
5564     }
5566   [(set (attr "type")
5567      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5568         (const_string "incdec")
5569         (const_string "alu")))
5570    (set_attr "mode" "SI")])
5572 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5573 (define_insn "*addsi_2_zext"
5574   [(set (reg FLAGS_REG)
5575         (compare
5576           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5577                    (match_operand:SI 2 "general_operand" "rmni"))
5578           (const_int 0)))                       
5579    (set (match_operand:DI 0 "register_operand" "=r")
5580         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5581   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5582    && ix86_binary_operator_ok (PLUS, SImode, operands)
5583    /* Current assemblers are broken and do not allow @GOTOFF in
5584       ought but a memory context.  */
5585    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587   switch (get_attr_type (insn))
5588     {
5589     case TYPE_INCDEC:
5590       if (operands[2] == const1_rtx)
5591         return "inc{l}\t%k0";
5592       else
5593         {
5594           gcc_assert (operands[2] == constm1_rtx);
5595           return "dec{l}\t%k0";
5596         }
5598     default:
5599       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5600          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5601       if (GET_CODE (operands[2]) == CONST_INT
5602           && (INTVAL (operands[2]) == 128
5603               || (INTVAL (operands[2]) < 0
5604                   && INTVAL (operands[2]) != -128)))
5605         {
5606           operands[2] = GEN_INT (-INTVAL (operands[2]));
5607           return "sub{l}\t{%2, %k0|%k0, %2}";
5608         }
5609       return "add{l}\t{%2, %k0|%k0, %2}";
5610     }
5612   [(set (attr "type")
5613      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5614         (const_string "incdec")
5615         (const_string "alu")))
5616    (set_attr "mode" "SI")])
5618 (define_insn "*addsi_3"
5619   [(set (reg FLAGS_REG)
5620         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5621                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5622    (clobber (match_scratch:SI 0 "=r"))]
5623   "ix86_match_ccmode (insn, CCZmode)
5624    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5625    /* Current assemblers are broken and do not allow @GOTOFF in
5626       ought but a memory context.  */
5627    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629   switch (get_attr_type (insn))
5630     {
5631     case TYPE_INCDEC:
5632       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633       if (operands[2] == const1_rtx)
5634         return "inc{l}\t%0";
5635       else
5636         {
5637           gcc_assert (operands[2] == constm1_rtx);
5638           return "dec{l}\t%0";
5639         }
5641     default:
5642       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5644          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5645       if (GET_CODE (operands[2]) == CONST_INT
5646           && (INTVAL (operands[2]) == 128
5647               || (INTVAL (operands[2]) < 0
5648                   && INTVAL (operands[2]) != -128)))
5649         {
5650           operands[2] = GEN_INT (-INTVAL (operands[2]));
5651           return "sub{l}\t{%2, %0|%0, %2}";
5652         }
5653       return "add{l}\t{%2, %0|%0, %2}";
5654     }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5658         (const_string "incdec")
5659         (const_string "alu")))
5660    (set_attr "mode" "SI")])
5662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5663 (define_insn "*addsi_3_zext"
5664   [(set (reg FLAGS_REG)
5665         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5666                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5667    (set (match_operand:DI 0 "register_operand" "=r")
5668         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5669   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5670    && ix86_binary_operator_ok (PLUS, SImode, operands)
5671    /* Current assemblers are broken and do not allow @GOTOFF in
5672       ought but a memory context.  */
5673    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5675   switch (get_attr_type (insn))
5676     {
5677     case TYPE_INCDEC:
5678       if (operands[2] == const1_rtx)
5679         return "inc{l}\t%k0";
5680       else
5681         {
5682           gcc_assert (operands[2] == constm1_rtx);
5683           return "dec{l}\t%k0";
5684         }
5686     default:
5687       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5688          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5689       if (GET_CODE (operands[2]) == CONST_INT
5690           && (INTVAL (operands[2]) == 128
5691               || (INTVAL (operands[2]) < 0
5692                   && INTVAL (operands[2]) != -128)))
5693         {
5694           operands[2] = GEN_INT (-INTVAL (operands[2]));
5695           return "sub{l}\t{%2, %k0|%k0, %2}";
5696         }
5697       return "add{l}\t{%2, %k0|%k0, %2}";
5698     }
5700   [(set (attr "type")
5701      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5702         (const_string "incdec")
5703         (const_string "alu")))
5704    (set_attr "mode" "SI")])
5706 ; For comparisons against 1, -1 and 128, we may generate better code
5707 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5708 ; is matched then.  We can't accept general immediate, because for
5709 ; case of overflows,  the result is messed up.
5710 ; This pattern also don't hold of 0x80000000, since the value overflows
5711 ; when negated.
5712 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5713 ; only for comparisons not depending on it.
5714 (define_insn "*addsi_4"
5715   [(set (reg FLAGS_REG)
5716         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5717                  (match_operand:SI 2 "const_int_operand" "n")))
5718    (clobber (match_scratch:SI 0 "=rm"))]
5719   "ix86_match_ccmode (insn, CCGCmode)
5720    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5722   switch (get_attr_type (insn))
5723     {
5724     case TYPE_INCDEC:
5725       if (operands[2] == constm1_rtx)
5726         return "inc{l}\t%0";
5727       else
5728         {
5729           gcc_assert (operands[2] == const1_rtx);
5730           return "dec{l}\t%0";
5731         }
5733     default:
5734       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5735       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5737       if ((INTVAL (operands[2]) == -128
5738            || (INTVAL (operands[2]) > 0
5739                && INTVAL (operands[2]) != 128)))
5740         return "sub{l}\t{%2, %0|%0, %2}";
5741       operands[2] = GEN_INT (-INTVAL (operands[2]));
5742       return "add{l}\t{%2, %0|%0, %2}";
5743     }
5745   [(set (attr "type")
5746      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5747         (const_string "incdec")
5748         (const_string "alu")))
5749    (set_attr "mode" "SI")])
5751 (define_insn "*addsi_5"
5752   [(set (reg FLAGS_REG)
5753         (compare
5754           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5755                    (match_operand:SI 2 "general_operand" "rmni"))
5756           (const_int 0)))                       
5757    (clobber (match_scratch:SI 0 "=r"))]
5758   "ix86_match_ccmode (insn, CCGOCmode)
5759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5760    /* Current assemblers are broken and do not allow @GOTOFF in
5761       ought but a memory context.  */
5762    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764   switch (get_attr_type (insn))
5765     {
5766     case TYPE_INCDEC:
5767       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5768       if (operands[2] == const1_rtx)
5769         return "inc{l}\t%0";
5770       else
5771         {
5772           gcc_assert (operands[2] == constm1_rtx);
5773           return "dec{l}\t%0";
5774         }
5776     default:
5777       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5780       if (GET_CODE (operands[2]) == CONST_INT
5781           && (INTVAL (operands[2]) == 128
5782               || (INTVAL (operands[2]) < 0
5783                   && INTVAL (operands[2]) != -128)))
5784         {
5785           operands[2] = GEN_INT (-INTVAL (operands[2]));
5786           return "sub{l}\t{%2, %0|%0, %2}";
5787         }
5788       return "add{l}\t{%2, %0|%0, %2}";
5789     }
5791   [(set (attr "type")
5792      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5793         (const_string "incdec")
5794         (const_string "alu")))
5795    (set_attr "mode" "SI")])
5797 (define_expand "addhi3"
5798   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5799                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5800                             (match_operand:HI 2 "general_operand" "")))
5801               (clobber (reg:CC FLAGS_REG))])]
5802   "TARGET_HIMODE_MATH"
5803   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5805 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5806 ;; type optimizations enabled by define-splits.  This is not important
5807 ;; for PII, and in fact harmful because of partial register stalls.
5809 (define_insn "*addhi_1_lea"
5810   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5811         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5812                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5813    (clobber (reg:CC FLAGS_REG))]
5814   "!TARGET_PARTIAL_REG_STALL
5815    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5817   switch (get_attr_type (insn))
5818     {
5819     case TYPE_LEA:
5820       return "#";
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{w}\t%0";
5824       else
5825         {
5826           gcc_assert (operands[2] == constm1_rtx);
5827           return "dec{w}\t%0";
5828         }
5830     default:
5831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833       if (GET_CODE (operands[2]) == CONST_INT
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{w}\t{%2, %0|%0, %2}";
5840         }
5841       return "add{w}\t{%2, %0|%0, %2}";
5842     }
5844   [(set (attr "type")
5845      (if_then_else (eq_attr "alternative" "2")
5846         (const_string "lea")
5847         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5848            (const_string "incdec")
5849            (const_string "alu"))))
5850    (set_attr "mode" "HI,HI,SI")])
5852 (define_insn "*addhi_1"
5853   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5854         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5855                  (match_operand:HI 2 "general_operand" "ri,rm")))
5856    (clobber (reg:CC FLAGS_REG))]
5857   "TARGET_PARTIAL_REG_STALL
5858    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5860   switch (get_attr_type (insn))
5861     {
5862     case TYPE_INCDEC:
5863       if (operands[2] == const1_rtx)
5864         return "inc{w}\t%0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{w}\t%0";
5869         }
5871     default:
5872       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874       if (GET_CODE (operands[2]) == CONST_INT
5875           && (INTVAL (operands[2]) == 128
5876               || (INTVAL (operands[2]) < 0
5877                   && INTVAL (operands[2]) != -128)))
5878         {
5879           operands[2] = GEN_INT (-INTVAL (operands[2]));
5880           return "sub{w}\t{%2, %0|%0, %2}";
5881         }
5882       return "add{w}\t{%2, %0|%0, %2}";
5883     }
5885   [(set (attr "type")
5886      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5887         (const_string "incdec")
5888         (const_string "alu")))
5889    (set_attr "mode" "HI")])
5891 (define_insn "*addhi_2"
5892   [(set (reg FLAGS_REG)
5893         (compare
5894           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5895                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5896           (const_int 0)))                       
5897    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5898         (plus:HI (match_dup 1) (match_dup 2)))]
5899   "ix86_match_ccmode (insn, CCGOCmode)
5900    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5902   switch (get_attr_type (insn))
5903     {
5904     case TYPE_INCDEC:
5905       if (operands[2] == const1_rtx)
5906         return "inc{w}\t%0";
5907       else
5908         {
5909           gcc_assert (operands[2] == constm1_rtx);
5910           return "dec{w}\t%0";
5911         }
5913     default:
5914       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5916       if (GET_CODE (operands[2]) == CONST_INT
5917           && (INTVAL (operands[2]) == 128
5918               || (INTVAL (operands[2]) < 0
5919                   && INTVAL (operands[2]) != -128)))
5920         {
5921           operands[2] = GEN_INT (-INTVAL (operands[2]));
5922           return "sub{w}\t{%2, %0|%0, %2}";
5923         }
5924       return "add{w}\t{%2, %0|%0, %2}";
5925     }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set_attr "mode" "HI")])
5933 (define_insn "*addhi_3"
5934   [(set (reg FLAGS_REG)
5935         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5936                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5937    (clobber (match_scratch:HI 0 "=r"))]
5938   "ix86_match_ccmode (insn, CCZmode)
5939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941   switch (get_attr_type (insn))
5942     {
5943     case TYPE_INCDEC:
5944       if (operands[2] == const1_rtx)
5945         return "inc{w}\t%0";
5946       else
5947         {
5948           gcc_assert (operands[2] == constm1_rtx);
5949           return "dec{w}\t%0";
5950         }
5952     default:
5953       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5954          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5955       if (GET_CODE (operands[2]) == CONST_INT
5956           && (INTVAL (operands[2]) == 128
5957               || (INTVAL (operands[2]) < 0
5958                   && INTVAL (operands[2]) != -128)))
5959         {
5960           operands[2] = GEN_INT (-INTVAL (operands[2]));
5961           return "sub{w}\t{%2, %0|%0, %2}";
5962         }
5963       return "add{w}\t{%2, %0|%0, %2}";
5964     }
5966   [(set (attr "type")
5967      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5968         (const_string "incdec")
5969         (const_string "alu")))
5970    (set_attr "mode" "HI")])
5972 ; See comments above addsi_4 for details.
5973 (define_insn "*addhi_4"
5974   [(set (reg FLAGS_REG)
5975         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5976                  (match_operand:HI 2 "const_int_operand" "n")))
5977    (clobber (match_scratch:HI 0 "=rm"))]
5978   "ix86_match_ccmode (insn, CCGCmode)
5979    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5981   switch (get_attr_type (insn))
5982     {
5983     case TYPE_INCDEC:
5984       if (operands[2] == constm1_rtx)
5985         return "inc{w}\t%0";
5986       else
5987         {
5988           gcc_assert (operands[2] == const1_rtx);
5989           return "dec{w}\t%0";
5990         }
5992     default:
5993       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5996       if ((INTVAL (operands[2]) == -128
5997            || (INTVAL (operands[2]) > 0
5998                && INTVAL (operands[2]) != 128)))
5999         return "sub{w}\t{%2, %0|%0, %2}";
6000       operands[2] = GEN_INT (-INTVAL (operands[2]));
6001       return "add{w}\t{%2, %0|%0, %2}";
6002     }
6004   [(set (attr "type")
6005      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006         (const_string "incdec")
6007         (const_string "alu")))
6008    (set_attr "mode" "SI")])
6011 (define_insn "*addhi_5"
6012   [(set (reg FLAGS_REG)
6013         (compare
6014           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6015                    (match_operand:HI 2 "general_operand" "rmni"))
6016           (const_int 0)))                       
6017    (clobber (match_scratch:HI 0 "=r"))]
6018   "ix86_match_ccmode (insn, CCGOCmode)
6019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6021   switch (get_attr_type (insn))
6022     {
6023     case TYPE_INCDEC:
6024       if (operands[2] == const1_rtx)
6025         return "inc{w}\t%0";
6026       else
6027         {
6028           gcc_assert (operands[2] == constm1_rtx);
6029           return "dec{w}\t%0";
6030         }
6032     default:
6033       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6034          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6035       if (GET_CODE (operands[2]) == CONST_INT
6036           && (INTVAL (operands[2]) == 128
6037               || (INTVAL (operands[2]) < 0
6038                   && INTVAL (operands[2]) != -128)))
6039         {
6040           operands[2] = GEN_INT (-INTVAL (operands[2]));
6041           return "sub{w}\t{%2, %0|%0, %2}";
6042         }
6043       return "add{w}\t{%2, %0|%0, %2}";
6044     }
6046   [(set (attr "type")
6047      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6048         (const_string "incdec")
6049         (const_string "alu")))
6050    (set_attr "mode" "HI")])
6052 (define_expand "addqi3"
6053   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6054                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6055                             (match_operand:QI 2 "general_operand" "")))
6056               (clobber (reg:CC FLAGS_REG))])]
6057   "TARGET_QIMODE_MATH"
6058   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6060 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6061 (define_insn "*addqi_1_lea"
6062   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6063         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6064                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6065    (clobber (reg:CC FLAGS_REG))]
6066   "!TARGET_PARTIAL_REG_STALL
6067    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6069   int widen = (which_alternative == 2);
6070   switch (get_attr_type (insn))
6071     {
6072     case TYPE_LEA:
6073       return "#";
6074     case TYPE_INCDEC:
6075       if (operands[2] == const1_rtx)
6076         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6077       else
6078         {
6079           gcc_assert (operands[2] == constm1_rtx);
6080           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6081         }
6083     default:
6084       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6085          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6086       if (GET_CODE (operands[2]) == CONST_INT
6087           && (INTVAL (operands[2]) == 128
6088               || (INTVAL (operands[2]) < 0
6089                   && INTVAL (operands[2]) != -128)))
6090         {
6091           operands[2] = GEN_INT (-INTVAL (operands[2]));
6092           if (widen)
6093             return "sub{l}\t{%2, %k0|%k0, %2}";
6094           else
6095             return "sub{b}\t{%2, %0|%0, %2}";
6096         }
6097       if (widen)
6098         return "add{l}\t{%k2, %k0|%k0, %k2}";
6099       else
6100         return "add{b}\t{%2, %0|%0, %2}";
6101     }
6103   [(set (attr "type")
6104      (if_then_else (eq_attr "alternative" "3")
6105         (const_string "lea")
6106         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6107            (const_string "incdec")
6108            (const_string "alu"))))
6109    (set_attr "mode" "QI,QI,SI,SI")])
6111 (define_insn "*addqi_1"
6112   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6113         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6114                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6115    (clobber (reg:CC FLAGS_REG))]
6116   "TARGET_PARTIAL_REG_STALL
6117    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6119   int widen = (which_alternative == 2);
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == const1_rtx)
6124         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6125       else
6126         {
6127           gcc_assert (operands[2] == constm1_rtx);
6128           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6129         }
6131     default:
6132       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6133          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6134       if (GET_CODE (operands[2]) == CONST_INT
6135           && (INTVAL (operands[2]) == 128
6136               || (INTVAL (operands[2]) < 0
6137                   && INTVAL (operands[2]) != -128)))
6138         {
6139           operands[2] = GEN_INT (-INTVAL (operands[2]));
6140           if (widen)
6141             return "sub{l}\t{%2, %k0|%k0, %2}";
6142           else
6143             return "sub{b}\t{%2, %0|%0, %2}";
6144         }
6145       if (widen)
6146         return "add{l}\t{%k2, %k0|%k0, %k2}";
6147       else
6148         return "add{b}\t{%2, %0|%0, %2}";
6149     }
6151   [(set (attr "type")
6152      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6153         (const_string "incdec")
6154         (const_string "alu")))
6155    (set_attr "mode" "QI,QI,SI")])
6157 (define_insn "*addqi_1_slp"
6158   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6159         (plus:QI (match_dup 0)
6160                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6161    (clobber (reg:CC FLAGS_REG))]
6162   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6165   switch (get_attr_type (insn))
6166     {
6167     case TYPE_INCDEC:
6168       if (operands[1] == const1_rtx)
6169         return "inc{b}\t%0";
6170       else
6171         {
6172           gcc_assert (operands[1] == constm1_rtx);
6173           return "dec{b}\t%0";
6174         }
6176     default:
6177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6178       if (GET_CODE (operands[1]) == CONST_INT
6179           && INTVAL (operands[1]) < 0)
6180         {
6181           operands[1] = GEN_INT (-INTVAL (operands[1]));
6182           return "sub{b}\t{%1, %0|%0, %1}";
6183         }
6184       return "add{b}\t{%1, %0|%0, %1}";
6185     }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu1")))
6191    (set (attr "memory")
6192      (if_then_else (match_operand 1 "memory_operand" "")
6193         (const_string "load")
6194         (const_string "none")))
6195    (set_attr "mode" "QI")])
6197 (define_insn "*addqi_2"
6198   [(set (reg FLAGS_REG)
6199         (compare
6200           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6201                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6202           (const_int 0)))
6203    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6204         (plus:QI (match_dup 1) (match_dup 2)))]
6205   "ix86_match_ccmode (insn, CCGOCmode)
6206    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6208   switch (get_attr_type (insn))
6209     {
6210     case TYPE_INCDEC:
6211       if (operands[2] == const1_rtx)
6212         return "inc{b}\t%0";
6213       else
6214         {
6215           gcc_assert (operands[2] == constm1_rtx
6216                       || (GET_CODE (operands[2]) == CONST_INT
6217                           && INTVAL (operands[2]) == 255));
6218           return "dec{b}\t%0";
6219         }
6221     default:
6222       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6223       if (GET_CODE (operands[2]) == CONST_INT
6224           && INTVAL (operands[2]) < 0)
6225         {
6226           operands[2] = GEN_INT (-INTVAL (operands[2]));
6227           return "sub{b}\t{%2, %0|%0, %2}";
6228         }
6229       return "add{b}\t{%2, %0|%0, %2}";
6230     }
6232   [(set (attr "type")
6233      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6234         (const_string "incdec")
6235         (const_string "alu")))
6236    (set_attr "mode" "QI")])
6238 (define_insn "*addqi_3"
6239   [(set (reg FLAGS_REG)
6240         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6241                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6242    (clobber (match_scratch:QI 0 "=q"))]
6243   "ix86_match_ccmode (insn, CCZmode)
6244    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6246   switch (get_attr_type (insn))
6247     {
6248     case TYPE_INCDEC:
6249       if (operands[2] == const1_rtx)
6250         return "inc{b}\t%0";
6251       else
6252         {
6253           gcc_assert (operands[2] == constm1_rtx
6254                       || (GET_CODE (operands[2]) == CONST_INT
6255                           && INTVAL (operands[2]) == 255));
6256           return "dec{b}\t%0";
6257         }
6259     default:
6260       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6261       if (GET_CODE (operands[2]) == CONST_INT
6262           && INTVAL (operands[2]) < 0)
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           return "sub{b}\t{%2, %0|%0, %2}";
6266         }
6267       return "add{b}\t{%2, %0|%0, %2}";
6268     }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set_attr "mode" "QI")])
6276 ; See comments above addsi_4 for details.
6277 (define_insn "*addqi_4"
6278   [(set (reg FLAGS_REG)
6279         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6280                  (match_operand:QI 2 "const_int_operand" "n")))
6281    (clobber (match_scratch:QI 0 "=qm"))]
6282   "ix86_match_ccmode (insn, CCGCmode)
6283    && (INTVAL (operands[2]) & 0xff) != 0x80"
6285   switch (get_attr_type (insn))
6286     {
6287     case TYPE_INCDEC:
6288       if (operands[2] == constm1_rtx
6289           || (GET_CODE (operands[2]) == CONST_INT
6290               && INTVAL (operands[2]) == 255))
6291         return "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == const1_rtx);
6295           return "dec{b}\t%0";
6296         }
6298     default:
6299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300       if (INTVAL (operands[2]) < 0)
6301         {
6302           operands[2] = GEN_INT (-INTVAL (operands[2]));
6303           return "add{b}\t{%2, %0|%0, %2}";
6304         }
6305       return "sub{b}\t{%2, %0|%0, %2}";
6306     }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu")))
6312    (set_attr "mode" "QI")])
6315 (define_insn "*addqi_5"
6316   [(set (reg FLAGS_REG)
6317         (compare
6318           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6319                    (match_operand:QI 2 "general_operand" "qmni"))
6320           (const_int 0)))
6321    (clobber (match_scratch:QI 0 "=q"))]
6322   "ix86_match_ccmode (insn, CCGOCmode)
6323    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325   switch (get_attr_type (insn))
6326     {
6327     case TYPE_INCDEC:
6328       if (operands[2] == const1_rtx)
6329         return "inc{b}\t%0";
6330       else
6331         {
6332           gcc_assert (operands[2] == constm1_rtx
6333                       || (GET_CODE (operands[2]) == CONST_INT
6334                           && INTVAL (operands[2]) == 255));
6335           return "dec{b}\t%0";
6336         }
6338     default:
6339       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6340       if (GET_CODE (operands[2]) == CONST_INT
6341           && INTVAL (operands[2]) < 0)
6342         {
6343           operands[2] = GEN_INT (-INTVAL (operands[2]));
6344           return "sub{b}\t{%2, %0|%0, %2}";
6345         }
6346       return "add{b}\t{%2, %0|%0, %2}";
6347     }
6349   [(set (attr "type")
6350      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6351         (const_string "incdec")
6352         (const_string "alu")))
6353    (set_attr "mode" "QI")])
6356 (define_insn "addqi_ext_1"
6357   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6358                          (const_int 8)
6359                          (const_int 8))
6360         (plus:SI
6361           (zero_extract:SI
6362             (match_operand 1 "ext_register_operand" "0")
6363             (const_int 8)
6364             (const_int 8))
6365           (match_operand:QI 2 "general_operand" "Qmn")))
6366    (clobber (reg:CC FLAGS_REG))]
6367   "!TARGET_64BIT"
6369   switch (get_attr_type (insn))
6370     {
6371     case TYPE_INCDEC:
6372       if (operands[2] == const1_rtx)
6373         return "inc{b}\t%h0";
6374       else
6375         {
6376           gcc_assert (operands[2] == constm1_rtx
6377                       || (GET_CODE (operands[2]) == CONST_INT
6378                           && INTVAL (operands[2]) == 255));
6379           return "dec{b}\t%h0";
6380         }
6382     default:
6383       return "add{b}\t{%2, %h0|%h0, %2}";
6384     }
6386   [(set (attr "type")
6387      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6388         (const_string "incdec")
6389         (const_string "alu")))
6390    (set_attr "mode" "QI")])
6392 (define_insn "*addqi_ext_1_rex64"
6393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394                          (const_int 8)
6395                          (const_int 8))
6396         (plus:SI
6397           (zero_extract:SI
6398             (match_operand 1 "ext_register_operand" "0")
6399             (const_int 8)
6400             (const_int 8))
6401           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "TARGET_64BIT"
6405   switch (get_attr_type (insn))
6406     {
6407     case TYPE_INCDEC:
6408       if (operands[2] == const1_rtx)
6409         return "inc{b}\t%h0";
6410       else
6411         {
6412           gcc_assert (operands[2] == constm1_rtx
6413                       || (GET_CODE (operands[2]) == CONST_INT
6414                           && INTVAL (operands[2]) == 255));
6415           return "dec{b}\t%h0";
6416         }
6418     default:
6419       return "add{b}\t{%2, %h0|%h0, %2}";
6420     }
6422   [(set (attr "type")
6423      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424         (const_string "incdec")
6425         (const_string "alu")))
6426    (set_attr "mode" "QI")])
6428 (define_insn "*addqi_ext_2"
6429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6430                          (const_int 8)
6431                          (const_int 8))
6432         (plus:SI
6433           (zero_extract:SI
6434             (match_operand 1 "ext_register_operand" "%0")
6435             (const_int 8)
6436             (const_int 8))
6437           (zero_extract:SI
6438             (match_operand 2 "ext_register_operand" "Q")
6439             (const_int 8)
6440             (const_int 8))))
6441    (clobber (reg:CC FLAGS_REG))]
6442   ""
6443   "add{b}\t{%h2, %h0|%h0, %h2}"
6444   [(set_attr "type" "alu")
6445    (set_attr "mode" "QI")])
6447 ;; The patterns that match these are at the end of this file.
6449 (define_expand "addxf3"
6450   [(set (match_operand:XF 0 "register_operand" "")
6451         (plus:XF (match_operand:XF 1 "register_operand" "")
6452                  (match_operand:XF 2 "register_operand" "")))]
6453   "TARGET_80387"
6454   "")
6456 (define_expand "adddf3"
6457   [(set (match_operand:DF 0 "register_operand" "")
6458         (plus:DF (match_operand:DF 1 "register_operand" "")
6459                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6460   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6461   "")
6463 (define_expand "addsf3"
6464   [(set (match_operand:SF 0 "register_operand" "")
6465         (plus:SF (match_operand:SF 1 "register_operand" "")
6466                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6467   "TARGET_80387 || TARGET_SSE_MATH"
6468   "")
6470 ;; Subtract instructions
6472 ;; %%% splits for subditi3
6474 (define_expand "subti3"
6475   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6476                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6477                              (match_operand:TI 2 "x86_64_general_operand" "")))
6478               (clobber (reg:CC FLAGS_REG))])]
6479   "TARGET_64BIT"
6480   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6482 (define_insn "*subti3_1"
6483   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6484         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6485                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6488   "#")
6490 (define_split
6491   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493                   (match_operand:TI 2 "general_operand" "")))
6494    (clobber (reg:CC FLAGS_REG))]
6495   "TARGET_64BIT && reload_completed"
6496   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6497               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6498    (parallel [(set (match_dup 3)
6499                    (minus:DI (match_dup 4)
6500                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6501                                       (match_dup 5))))
6502               (clobber (reg:CC FLAGS_REG))])]
6503   "split_ti (operands+0, 1, operands+0, operands+3);
6504    split_ti (operands+1, 1, operands+1, operands+4);
6505    split_ti (operands+2, 1, operands+2, operands+5);")
6507 ;; %%% splits for subsidi3
6509 (define_expand "subdi3"
6510   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6511                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6512                              (match_operand:DI 2 "x86_64_general_operand" "")))
6513               (clobber (reg:CC FLAGS_REG))])]
6514   ""
6515   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6517 (define_insn "*subdi3_1"
6518   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6520                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6521    (clobber (reg:CC FLAGS_REG))]
6522   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6523   "#")
6525 (define_split
6526   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528                   (match_operand:DI 2 "general_operand" "")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "!TARGET_64BIT && reload_completed"
6531   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6532               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6533    (parallel [(set (match_dup 3)
6534                    (minus:SI (match_dup 4)
6535                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6536                                       (match_dup 5))))
6537               (clobber (reg:CC FLAGS_REG))])]
6538   "split_di (operands+0, 1, operands+0, operands+3);
6539    split_di (operands+1, 1, operands+1, operands+4);
6540    split_di (operands+2, 1, operands+2, operands+5);")
6542 (define_insn "subdi3_carry_rex64"
6543   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6544           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6545             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6546                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6547    (clobber (reg:CC FLAGS_REG))]
6548   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6549   "sbb{q}\t{%2, %0|%0, %2}"
6550   [(set_attr "type" "alu")
6551    (set_attr "pent_pair" "pu")
6552    (set_attr "mode" "DI")])
6554 (define_insn "*subdi_1_rex64"
6555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6556         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6557                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6558    (clobber (reg:CC FLAGS_REG))]
6559   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6560   "sub{q}\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "alu")
6562    (set_attr "mode" "DI")])
6564 (define_insn "*subdi_2_rex64"
6565   [(set (reg FLAGS_REG)
6566         (compare
6567           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6568                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6569           (const_int 0)))
6570    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6571         (minus:DI (match_dup 1) (match_dup 2)))]
6572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6573    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6574   "sub{q}\t{%2, %0|%0, %2}"
6575   [(set_attr "type" "alu")
6576    (set_attr "mode" "DI")])
6578 (define_insn "*subdi_3_rex63"
6579   [(set (reg FLAGS_REG)
6580         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6581                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6582    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6583         (minus:DI (match_dup 1) (match_dup 2)))]
6584   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6585    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6586   "sub{q}\t{%2, %0|%0, %2}"
6587   [(set_attr "type" "alu")
6588    (set_attr "mode" "DI")])
6590 (define_insn "subqi3_carry"
6591   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6592           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6593             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6594                (match_operand:QI 2 "general_operand" "qi,qm"))))
6595    (clobber (reg:CC FLAGS_REG))]
6596   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6597   "sbb{b}\t{%2, %0|%0, %2}"
6598   [(set_attr "type" "alu")
6599    (set_attr "pent_pair" "pu")
6600    (set_attr "mode" "QI")])
6602 (define_insn "subhi3_carry"
6603   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6604           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6605             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6606                (match_operand:HI 2 "general_operand" "ri,rm"))))
6607    (clobber (reg:CC FLAGS_REG))]
6608   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6609   "sbb{w}\t{%2, %0|%0, %2}"
6610   [(set_attr "type" "alu")
6611    (set_attr "pent_pair" "pu")
6612    (set_attr "mode" "HI")])
6614 (define_insn "subsi3_carry"
6615   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6616           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6617             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6618                (match_operand:SI 2 "general_operand" "ri,rm"))))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sbb{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "pent_pair" "pu")
6624    (set_attr "mode" "SI")])
6626 (define_insn "subsi3_carry_zext"
6627   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6628           (zero_extend:DI
6629             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6630               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6631                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6632    (clobber (reg:CC FLAGS_REG))]
6633   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6634   "sbb{l}\t{%2, %k0|%k0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "pent_pair" "pu")
6637    (set_attr "mode" "SI")])
6639 (define_expand "subsi3"
6640   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6641                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6642                              (match_operand:SI 2 "general_operand" "")))
6643               (clobber (reg:CC FLAGS_REG))])]
6644   ""
6645   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6647 (define_insn "*subsi_1"
6648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6649         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6650                   (match_operand:SI 2 "general_operand" "ri,rm")))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6653   "sub{l}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "mode" "SI")])
6657 (define_insn "*subsi_1_zext"
6658   [(set (match_operand:DI 0 "register_operand" "=r")
6659         (zero_extend:DI
6660           (minus:SI (match_operand:SI 1 "register_operand" "0")
6661                     (match_operand:SI 2 "general_operand" "rim"))))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6664   "sub{l}\t{%2, %k0|%k0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "SI")])
6668 (define_insn "*subsi_2"
6669   [(set (reg FLAGS_REG)
6670         (compare
6671           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672                     (match_operand:SI 2 "general_operand" "ri,rm"))
6673           (const_int 0)))
6674    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675         (minus:SI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCGOCmode)
6677    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678   "sub{l}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "SI")])
6682 (define_insn "*subsi_2_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare
6685           (minus:SI (match_operand:SI 1 "register_operand" "0")
6686                     (match_operand:SI 2 "general_operand" "rim"))
6687           (const_int 0)))
6688    (set (match_operand:DI 0 "register_operand" "=r")
6689         (zero_extend:DI
6690           (minus:SI (match_dup 1)
6691                     (match_dup 2))))]
6692   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %k0|%k0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6698 (define_insn "*subsi_3"
6699   [(set (reg FLAGS_REG)
6700         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6701                  (match_operand:SI 2 "general_operand" "ri,rm")))
6702    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6703         (minus:SI (match_dup 1) (match_dup 2)))]
6704   "ix86_match_ccmode (insn, CCmode)
6705    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6706   "sub{l}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "SI")])
6710 (define_insn "*subsi_3_zext"
6711   [(set (reg FLAGS_REG)
6712         (compare (match_operand:SI 1 "register_operand" "0")
6713                  (match_operand:SI 2 "general_operand" "rim")))
6714    (set (match_operand:DI 0 "register_operand" "=r")
6715         (zero_extend:DI
6716           (minus:SI (match_dup 1)
6717                     (match_dup 2))))]
6718   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6719    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sub{q}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "DI")])
6724 (define_expand "subhi3"
6725   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6726                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6727                              (match_operand:HI 2 "general_operand" "")))
6728               (clobber (reg:CC FLAGS_REG))])]
6729   "TARGET_HIMODE_MATH"
6730   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6732 (define_insn "*subhi_1"
6733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6734         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735                   (match_operand:HI 2 "general_operand" "ri,rm")))
6736    (clobber (reg:CC FLAGS_REG))]
6737   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6738   "sub{w}\t{%2, %0|%0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "HI")])
6742 (define_insn "*subhi_2"
6743   [(set (reg FLAGS_REG)
6744         (compare
6745           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6746                     (match_operand:HI 2 "general_operand" "ri,rm"))
6747           (const_int 0)))
6748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6749         (minus:HI (match_dup 1) (match_dup 2)))]
6750   "ix86_match_ccmode (insn, CCGOCmode)
6751    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6752   "sub{w}\t{%2, %0|%0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "HI")])
6756 (define_insn "*subhi_3"
6757   [(set (reg FLAGS_REG)
6758         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6759                  (match_operand:HI 2 "general_operand" "ri,rm")))
6760    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6761         (minus:HI (match_dup 1) (match_dup 2)))]
6762   "ix86_match_ccmode (insn, CCmode)
6763    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6764   "sub{w}\t{%2, %0|%0, %2}"
6765   [(set_attr "type" "alu")
6766    (set_attr "mode" "HI")])
6768 (define_expand "subqi3"
6769   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6770                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6771                              (match_operand:QI 2 "general_operand" "")))
6772               (clobber (reg:CC FLAGS_REG))])]
6773   "TARGET_QIMODE_MATH"
6774   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6776 (define_insn "*subqi_1"
6777   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6778         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6779                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6780    (clobber (reg:CC FLAGS_REG))]
6781   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6782   "sub{b}\t{%2, %0|%0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "mode" "QI")])
6786 (define_insn "*subqi_1_slp"
6787   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6788         (minus:QI (match_dup 0)
6789                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6792    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6793   "sub{b}\t{%1, %0|%0, %1}"
6794   [(set_attr "type" "alu1")
6795    (set_attr "mode" "QI")])
6797 (define_insn "*subqi_2"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6801                     (match_operand:QI 2 "general_operand" "qi,qm"))
6802           (const_int 0)))
6803    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6804         (minus:HI (match_dup 1) (match_dup 2)))]
6805   "ix86_match_ccmode (insn, CCGOCmode)
6806    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6807   "sub{b}\t{%2, %0|%0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "mode" "QI")])
6811 (define_insn "*subqi_3"
6812   [(set (reg FLAGS_REG)
6813         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6814                  (match_operand:QI 2 "general_operand" "qi,qm")))
6815    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6816         (minus:HI (match_dup 1) (match_dup 2)))]
6817   "ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6819   "sub{b}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "QI")])
6823 ;; The patterns that match these are at the end of this file.
6825 (define_expand "subxf3"
6826   [(set (match_operand:XF 0 "register_operand" "")
6827         (minus:XF (match_operand:XF 1 "register_operand" "")
6828                   (match_operand:XF 2 "register_operand" "")))]
6829   "TARGET_80387"
6830   "")
6832 (define_expand "subdf3"
6833   [(set (match_operand:DF 0 "register_operand" "")
6834         (minus:DF (match_operand:DF 1 "register_operand" "")
6835                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6836   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6837   "")
6839 (define_expand "subsf3"
6840   [(set (match_operand:SF 0 "register_operand" "")
6841         (minus:SF (match_operand:SF 1 "register_operand" "")
6842                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6843   "TARGET_80387 || TARGET_SSE_MATH"
6844   "")
6846 ;; Multiply instructions
6848 (define_expand "muldi3"
6849   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6850                    (mult:DI (match_operand:DI 1 "register_operand" "")
6851                             (match_operand:DI 2 "x86_64_general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   "TARGET_64BIT"
6854   "")
6856 (define_insn "*muldi3_1_rex64"
6857   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6858         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "TARGET_64BIT
6862    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6863   "@
6864    imul{q}\t{%2, %1, %0|%0, %1, %2}
6865    imul{q}\t{%2, %1, %0|%0, %1, %2}
6866    imul{q}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "imul")
6868    (set_attr "prefix_0f" "0,0,1")
6869    (set (attr "athlon_decode")
6870         (cond [(eq_attr "cpu" "athlon")
6871                   (const_string "vector")
6872                (eq_attr "alternative" "1")
6873                   (const_string "vector")
6874                (and (eq_attr "alternative" "2")
6875                     (match_operand 1 "memory_operand" ""))
6876                   (const_string "vector")]
6877               (const_string "direct")))
6878    (set_attr "mode" "DI")])
6880 (define_expand "mulsi3"
6881   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6882                    (mult:SI (match_operand:SI 1 "register_operand" "")
6883                             (match_operand:SI 2 "general_operand" "")))
6884               (clobber (reg:CC FLAGS_REG))])]
6885   ""
6886   "")
6888 (define_insn "*mulsi3_1"
6889   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6890         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6894   "@
6895    imul{l}\t{%2, %1, %0|%0, %1, %2}
6896    imul{l}\t{%2, %1, %0|%0, %1, %2}
6897    imul{l}\t{%2, %0|%0, %2}"
6898   [(set_attr "type" "imul")
6899    (set_attr "prefix_0f" "0,0,1")
6900    (set (attr "athlon_decode")
6901         (cond [(eq_attr "cpu" "athlon")
6902                   (const_string "vector")
6903                (eq_attr "alternative" "1")
6904                   (const_string "vector")
6905                (and (eq_attr "alternative" "2")
6906                     (match_operand 1 "memory_operand" ""))
6907                   (const_string "vector")]
6908               (const_string "direct")))
6909    (set_attr "mode" "SI")])
6911 (define_insn "*mulsi3_1_zext"
6912   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913         (zero_extend:DI
6914           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6915                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919   "@
6920    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922    imul{l}\t{%2, %k0|%k0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "SI")])
6936 (define_expand "mulhi3"
6937   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6938                    (mult:HI (match_operand:HI 1 "register_operand" "")
6939                             (match_operand:HI 2 "general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   "TARGET_HIMODE_MATH"
6942   "")
6944 (define_insn "*mulhi3_1"
6945   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6946         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6950   "@
6951    imul{w}\t{%2, %1, %0|%0, %1, %2}
6952    imul{w}\t{%2, %1, %0|%0, %1, %2}
6953    imul{w}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "imul")
6955    (set_attr "prefix_0f" "0,0,1")
6956    (set (attr "athlon_decode")
6957         (cond [(eq_attr "cpu" "athlon")
6958                   (const_string "vector")
6959                (eq_attr "alternative" "1,2")
6960                   (const_string "vector")]
6961               (const_string "direct")))
6962    (set_attr "mode" "HI")])
6964 (define_expand "mulqi3"
6965   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6966                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6967                             (match_operand:QI 2 "register_operand" "")))
6968               (clobber (reg:CC FLAGS_REG))])]
6969   "TARGET_QIMODE_MATH"
6970   "")
6972 (define_insn "*mulqi3_1"
6973   [(set (match_operand:QI 0 "register_operand" "=a")
6974         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6975                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "TARGET_QIMODE_MATH
6978    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6979   "mul{b}\t%2"
6980   [(set_attr "type" "imul")
6981    (set_attr "length_immediate" "0")
6982    (set (attr "athlon_decode")
6983      (if_then_else (eq_attr "cpu" "athlon")
6984         (const_string "vector")
6985         (const_string "direct")))
6986    (set_attr "mode" "QI")])
6988 (define_expand "umulqihi3"
6989   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6990                    (mult:HI (zero_extend:HI
6991                               (match_operand:QI 1 "nonimmediate_operand" ""))
6992                             (zero_extend:HI
6993                               (match_operand:QI 2 "register_operand" ""))))
6994               (clobber (reg:CC FLAGS_REG))])]
6995   "TARGET_QIMODE_MATH"
6996   "")
6998 (define_insn "*umulqihi3_1"
6999   [(set (match_operand:HI 0 "register_operand" "=a")
7000         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7001                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "TARGET_QIMODE_MATH
7004    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005   "mul{b}\t%2"
7006   [(set_attr "type" "imul")
7007    (set_attr "length_immediate" "0")
7008    (set (attr "athlon_decode")
7009      (if_then_else (eq_attr "cpu" "athlon")
7010         (const_string "vector")
7011         (const_string "direct")))
7012    (set_attr "mode" "QI")])
7014 (define_expand "mulqihi3"
7015   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7016                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7017                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7018               (clobber (reg:CC FLAGS_REG))])]
7019   "TARGET_QIMODE_MATH"
7020   "")
7022 (define_insn "*mulqihi3_insn"
7023   [(set (match_operand:HI 0 "register_operand" "=a")
7024         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7025                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "TARGET_QIMODE_MATH
7028    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7029   "imul{b}\t%2"
7030   [(set_attr "type" "imul")
7031    (set_attr "length_immediate" "0")
7032    (set (attr "athlon_decode")
7033      (if_then_else (eq_attr "cpu" "athlon")
7034         (const_string "vector")
7035         (const_string "direct")))
7036    (set_attr "mode" "QI")])
7038 (define_expand "umulditi3"
7039   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7040                    (mult:TI (zero_extend:TI
7041                               (match_operand:DI 1 "nonimmediate_operand" ""))
7042                             (zero_extend:TI
7043                               (match_operand:DI 2 "register_operand" ""))))
7044               (clobber (reg:CC FLAGS_REG))])]
7045   "TARGET_64BIT"
7046   "")
7048 (define_insn "*umulditi3_insn"
7049   [(set (match_operand:TI 0 "register_operand" "=A")
7050         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7051                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7052    (clobber (reg:CC FLAGS_REG))]
7053   "TARGET_64BIT
7054    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055   "mul{q}\t%2"
7056   [(set_attr "type" "imul")
7057    (set_attr "length_immediate" "0")
7058    (set (attr "athlon_decode")
7059      (if_then_else (eq_attr "cpu" "athlon")
7060         (const_string "vector")
7061         (const_string "double")))
7062    (set_attr "mode" "DI")])
7064 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7065 (define_expand "umulsidi3"
7066   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7067                    (mult:DI (zero_extend:DI
7068                               (match_operand:SI 1 "nonimmediate_operand" ""))
7069                             (zero_extend:DI
7070                               (match_operand:SI 2 "register_operand" ""))))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   "!TARGET_64BIT"
7073   "")
7075 (define_insn "*umulsidi3_insn"
7076   [(set (match_operand:DI 0 "register_operand" "=A")
7077         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7078                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7079    (clobber (reg:CC FLAGS_REG))]
7080   "!TARGET_64BIT
7081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7082   "mul{l}\t%2"
7083   [(set_attr "type" "imul")
7084    (set_attr "length_immediate" "0")
7085    (set (attr "athlon_decode")
7086      (if_then_else (eq_attr "cpu" "athlon")
7087         (const_string "vector")
7088         (const_string "double")))
7089    (set_attr "mode" "SI")])
7091 (define_expand "mulditi3"
7092   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7093                    (mult:TI (sign_extend:TI
7094                               (match_operand:DI 1 "nonimmediate_operand" ""))
7095                             (sign_extend:TI
7096                               (match_operand:DI 2 "register_operand" ""))))
7097               (clobber (reg:CC FLAGS_REG))])]
7098   "TARGET_64BIT"
7099   "")
7101 (define_insn "*mulditi3_insn"
7102   [(set (match_operand:TI 0 "register_operand" "=A")
7103         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7104                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7105    (clobber (reg:CC FLAGS_REG))]
7106   "TARGET_64BIT
7107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7108   "imul{q}\t%2"
7109   [(set_attr "type" "imul")
7110    (set_attr "length_immediate" "0")
7111    (set (attr "athlon_decode")
7112      (if_then_else (eq_attr "cpu" "athlon")
7113         (const_string "vector")
7114         (const_string "double")))
7115    (set_attr "mode" "DI")])
7117 (define_expand "mulsidi3"
7118   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7119                    (mult:DI (sign_extend:DI
7120                               (match_operand:SI 1 "nonimmediate_operand" ""))
7121                             (sign_extend:DI
7122                               (match_operand:SI 2 "register_operand" ""))))
7123               (clobber (reg:CC FLAGS_REG))])]
7124   "!TARGET_64BIT"
7125   "")
7127 (define_insn "*mulsidi3_insn"
7128   [(set (match_operand:DI 0 "register_operand" "=A")
7129         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7130                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7131    (clobber (reg:CC FLAGS_REG))]
7132   "!TARGET_64BIT
7133    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7134   "imul{l}\t%2"
7135   [(set_attr "type" "imul")
7136    (set_attr "length_immediate" "0")
7137    (set (attr "athlon_decode")
7138      (if_then_else (eq_attr "cpu" "athlon")
7139         (const_string "vector")
7140         (const_string "double")))
7141    (set_attr "mode" "SI")])
7143 (define_expand "umuldi3_highpart"
7144   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7145                    (truncate:DI
7146                      (lshiftrt:TI
7147                        (mult:TI (zero_extend:TI
7148                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7149                                 (zero_extend:TI
7150                                   (match_operand:DI 2 "register_operand" "")))
7151                        (const_int 64))))
7152               (clobber (match_scratch:DI 3 ""))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_64BIT"
7155   "")
7157 (define_insn "*umuldi3_highpart_rex64"
7158   [(set (match_operand:DI 0 "register_operand" "=d")
7159         (truncate:DI
7160           (lshiftrt:TI
7161             (mult:TI (zero_extend:TI
7162                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7163                      (zero_extend:TI
7164                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7165             (const_int 64))))
7166    (clobber (match_scratch:DI 3 "=1"))
7167    (clobber (reg:CC FLAGS_REG))]
7168   "TARGET_64BIT
7169    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7170   "mul{q}\t%2"
7171   [(set_attr "type" "imul")
7172    (set_attr "length_immediate" "0")
7173    (set (attr "athlon_decode")
7174      (if_then_else (eq_attr "cpu" "athlon")
7175         (const_string "vector")
7176         (const_string "double")))
7177    (set_attr "mode" "DI")])
7179 (define_expand "umulsi3_highpart"
7180   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7181                    (truncate:SI
7182                      (lshiftrt:DI
7183                        (mult:DI (zero_extend:DI
7184                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7185                                 (zero_extend:DI
7186                                   (match_operand:SI 2 "register_operand" "")))
7187                        (const_int 32))))
7188               (clobber (match_scratch:SI 3 ""))
7189               (clobber (reg:CC FLAGS_REG))])]
7190   ""
7191   "")
7193 (define_insn "*umulsi3_highpart_insn"
7194   [(set (match_operand:SI 0 "register_operand" "=d")
7195         (truncate:SI
7196           (lshiftrt:DI
7197             (mult:DI (zero_extend:DI
7198                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7199                      (zero_extend:DI
7200                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7201             (const_int 32))))
7202    (clobber (match_scratch:SI 3 "=1"))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7205   "mul{l}\t%2"
7206   [(set_attr "type" "imul")
7207    (set_attr "length_immediate" "0")
7208    (set (attr "athlon_decode")
7209      (if_then_else (eq_attr "cpu" "athlon")
7210         (const_string "vector")
7211         (const_string "double")))
7212    (set_attr "mode" "SI")])
7214 (define_insn "*umulsi3_highpart_zext"
7215   [(set (match_operand:DI 0 "register_operand" "=d")
7216         (zero_extend:DI (truncate:SI
7217           (lshiftrt:DI
7218             (mult:DI (zero_extend:DI
7219                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7220                      (zero_extend:DI
7221                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7222             (const_int 32)))))
7223    (clobber (match_scratch:SI 3 "=1"))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "TARGET_64BIT
7226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227   "mul{l}\t%2"
7228   [(set_attr "type" "imul")
7229    (set_attr "length_immediate" "0")
7230    (set (attr "athlon_decode")
7231      (if_then_else (eq_attr "cpu" "athlon")
7232         (const_string "vector")
7233         (const_string "double")))
7234    (set_attr "mode" "SI")])
7236 (define_expand "smuldi3_highpart"
7237   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7238                    (truncate:DI
7239                      (lshiftrt:TI
7240                        (mult:TI (sign_extend:TI
7241                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7242                                 (sign_extend:TI
7243                                   (match_operand:DI 2 "register_operand" "")))
7244                        (const_int 64))))
7245               (clobber (match_scratch:DI 3 ""))
7246               (clobber (reg:CC FLAGS_REG))])]
7247   "TARGET_64BIT"
7248   "")
7250 (define_insn "*smuldi3_highpart_rex64"
7251   [(set (match_operand:DI 0 "register_operand" "=d")
7252         (truncate:DI
7253           (lshiftrt:TI
7254             (mult:TI (sign_extend:TI
7255                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7256                      (sign_extend:TI
7257                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7258             (const_int 64))))
7259    (clobber (match_scratch:DI 3 "=1"))
7260    (clobber (reg:CC FLAGS_REG))]
7261   "TARGET_64BIT
7262    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7263   "imul{q}\t%2"
7264   [(set_attr "type" "imul")
7265    (set (attr "athlon_decode")
7266      (if_then_else (eq_attr "cpu" "athlon")
7267         (const_string "vector")
7268         (const_string "double")))
7269    (set_attr "mode" "DI")])
7271 (define_expand "smulsi3_highpart"
7272   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7273                    (truncate:SI
7274                      (lshiftrt:DI
7275                        (mult:DI (sign_extend:DI
7276                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7277                                 (sign_extend:DI
7278                                   (match_operand:SI 2 "register_operand" "")))
7279                        (const_int 32))))
7280               (clobber (match_scratch:SI 3 ""))
7281               (clobber (reg:CC FLAGS_REG))])]
7282   ""
7283   "")
7285 (define_insn "*smulsi3_highpart_insn"
7286   [(set (match_operand:SI 0 "register_operand" "=d")
7287         (truncate:SI
7288           (lshiftrt:DI
7289             (mult:DI (sign_extend:DI
7290                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7291                      (sign_extend:DI
7292                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7293             (const_int 32))))
7294    (clobber (match_scratch:SI 3 "=1"))
7295    (clobber (reg:CC FLAGS_REG))]
7296   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7297   "imul{l}\t%2"
7298   [(set_attr "type" "imul")
7299    (set (attr "athlon_decode")
7300      (if_then_else (eq_attr "cpu" "athlon")
7301         (const_string "vector")
7302         (const_string "double")))
7303    (set_attr "mode" "SI")])
7305 (define_insn "*smulsi3_highpart_zext"
7306   [(set (match_operand:DI 0 "register_operand" "=d")
7307         (zero_extend:DI (truncate:SI
7308           (lshiftrt:DI
7309             (mult:DI (sign_extend:DI
7310                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7311                      (sign_extend:DI
7312                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7313             (const_int 32)))))
7314    (clobber (match_scratch:SI 3 "=1"))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT
7317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7318   "imul{l}\t%2"
7319   [(set_attr "type" "imul")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "SI")])
7326 ;; The patterns that match these are at the end of this file.
7328 (define_expand "mulxf3"
7329   [(set (match_operand:XF 0 "register_operand" "")
7330         (mult:XF (match_operand:XF 1 "register_operand" "")
7331                  (match_operand:XF 2 "register_operand" "")))]
7332   "TARGET_80387"
7333   "")
7335 (define_expand "muldf3"
7336   [(set (match_operand:DF 0 "register_operand" "")
7337         (mult:DF (match_operand:DF 1 "register_operand" "")
7338                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7339   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7340   "")
7342 (define_expand "mulsf3"
7343   [(set (match_operand:SF 0 "register_operand" "")
7344         (mult:SF (match_operand:SF 1 "register_operand" "")
7345                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7346   "TARGET_80387 || TARGET_SSE_MATH"
7347   "")
7349 ;; Divide instructions
7351 (define_insn "divqi3"
7352   [(set (match_operand:QI 0 "register_operand" "=a")
7353         (div:QI (match_operand:HI 1 "register_operand" "0")
7354                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7355    (clobber (reg:CC FLAGS_REG))]
7356   "TARGET_QIMODE_MATH"
7357   "idiv{b}\t%2"
7358   [(set_attr "type" "idiv")
7359    (set_attr "mode" "QI")])
7361 (define_insn "udivqi3"
7362   [(set (match_operand:QI 0 "register_operand" "=a")
7363         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7364                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7365    (clobber (reg:CC FLAGS_REG))]
7366   "TARGET_QIMODE_MATH"
7367   "div{b}\t%2"
7368   [(set_attr "type" "idiv")
7369    (set_attr "mode" "QI")])
7371 ;; The patterns that match these are at the end of this file.
7373 (define_expand "divxf3"
7374   [(set (match_operand:XF 0 "register_operand" "")
7375         (div:XF (match_operand:XF 1 "register_operand" "")
7376                 (match_operand:XF 2 "register_operand" "")))]
7377   "TARGET_80387"
7378   "")
7380 (define_expand "divdf3"
7381   [(set (match_operand:DF 0 "register_operand" "")
7382         (div:DF (match_operand:DF 1 "register_operand" "")
7383                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7384    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7385    "")
7387 (define_expand "divsf3"
7388   [(set (match_operand:SF 0 "register_operand" "")
7389         (div:SF (match_operand:SF 1 "register_operand" "")
7390                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7391   "TARGET_80387 || TARGET_SSE_MATH"
7392   "")
7394 ;; Remainder instructions.
7396 (define_expand "divmoddi4"
7397   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7398                    (div:DI (match_operand:DI 1 "register_operand" "")
7399                            (match_operand:DI 2 "nonimmediate_operand" "")))
7400               (set (match_operand:DI 3 "register_operand" "")
7401                    (mod:DI (match_dup 1) (match_dup 2)))
7402               (clobber (reg:CC FLAGS_REG))])]
7403   "TARGET_64BIT"
7404   "")
7406 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7407 ;; Penalize eax case slightly because it results in worse scheduling
7408 ;; of code.
7409 (define_insn "*divmoddi4_nocltd_rex64"
7410   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7411         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7412                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7413    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7414         (mod:DI (match_dup 2) (match_dup 3)))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7417   "#"
7418   [(set_attr "type" "multi")])
7420 (define_insn "*divmoddi4_cltd_rex64"
7421   [(set (match_operand:DI 0 "register_operand" "=a")
7422         (div:DI (match_operand:DI 2 "register_operand" "a")
7423                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7424    (set (match_operand:DI 1 "register_operand" "=&d")
7425         (mod:DI (match_dup 2) (match_dup 3)))
7426    (clobber (reg:CC FLAGS_REG))]
7427   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7428   "#"
7429   [(set_attr "type" "multi")])
7431 (define_insn "*divmoddi_noext_rex64"
7432   [(set (match_operand:DI 0 "register_operand" "=a")
7433         (div:DI (match_operand:DI 1 "register_operand" "0")
7434                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7435    (set (match_operand:DI 3 "register_operand" "=d")
7436         (mod:DI (match_dup 1) (match_dup 2)))
7437    (use (match_operand:DI 4 "register_operand" "3"))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "TARGET_64BIT"
7440   "idiv{q}\t%2"
7441   [(set_attr "type" "idiv")
7442    (set_attr "mode" "DI")])
7444 (define_split
7445   [(set (match_operand:DI 0 "register_operand" "")
7446         (div:DI (match_operand:DI 1 "register_operand" "")
7447                 (match_operand:DI 2 "nonimmediate_operand" "")))
7448    (set (match_operand:DI 3 "register_operand" "")
7449         (mod:DI (match_dup 1) (match_dup 2)))
7450    (clobber (reg:CC FLAGS_REG))]
7451   "TARGET_64BIT && reload_completed"
7452   [(parallel [(set (match_dup 3)
7453                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7454               (clobber (reg:CC FLAGS_REG))])
7455    (parallel [(set (match_dup 0)
7456                    (div:DI (reg:DI 0) (match_dup 2)))
7457               (set (match_dup 3)
7458                    (mod:DI (reg:DI 0) (match_dup 2)))
7459               (use (match_dup 3))
7460               (clobber (reg:CC FLAGS_REG))])]
7462   /* Avoid use of cltd in favor of a mov+shift.  */
7463   if (!TARGET_USE_CLTD && !optimize_size)
7464     {
7465       if (true_regnum (operands[1]))
7466         emit_move_insn (operands[0], operands[1]);
7467       else
7468         emit_move_insn (operands[3], operands[1]);
7469       operands[4] = operands[3];
7470     }
7471   else
7472     {
7473       gcc_assert (!true_regnum (operands[1]));
7474       operands[4] = operands[1];
7475     }
7479 (define_expand "divmodsi4"
7480   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7481                    (div:SI (match_operand:SI 1 "register_operand" "")
7482                            (match_operand:SI 2 "nonimmediate_operand" "")))
7483               (set (match_operand:SI 3 "register_operand" "")
7484                    (mod:SI (match_dup 1) (match_dup 2)))
7485               (clobber (reg:CC FLAGS_REG))])]
7486   ""
7487   "")
7489 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7490 ;; Penalize eax case slightly because it results in worse scheduling
7491 ;; of code.
7492 (define_insn "*divmodsi4_nocltd"
7493   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7494         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7495                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7496    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7497         (mod:SI (match_dup 2) (match_dup 3)))
7498    (clobber (reg:CC FLAGS_REG))]
7499   "!optimize_size && !TARGET_USE_CLTD"
7500   "#"
7501   [(set_attr "type" "multi")])
7503 (define_insn "*divmodsi4_cltd"
7504   [(set (match_operand:SI 0 "register_operand" "=a")
7505         (div:SI (match_operand:SI 2 "register_operand" "a")
7506                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7507    (set (match_operand:SI 1 "register_operand" "=&d")
7508         (mod:SI (match_dup 2) (match_dup 3)))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "optimize_size || TARGET_USE_CLTD"
7511   "#"
7512   [(set_attr "type" "multi")])
7514 (define_insn "*divmodsi_noext"
7515   [(set (match_operand:SI 0 "register_operand" "=a")
7516         (div:SI (match_operand:SI 1 "register_operand" "0")
7517                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7518    (set (match_operand:SI 3 "register_operand" "=d")
7519         (mod:SI (match_dup 1) (match_dup 2)))
7520    (use (match_operand:SI 4 "register_operand" "3"))
7521    (clobber (reg:CC FLAGS_REG))]
7522   ""
7523   "idiv{l}\t%2"
7524   [(set_attr "type" "idiv")
7525    (set_attr "mode" "SI")])
7527 (define_split
7528   [(set (match_operand:SI 0 "register_operand" "")
7529         (div:SI (match_operand:SI 1 "register_operand" "")
7530                 (match_operand:SI 2 "nonimmediate_operand" "")))
7531    (set (match_operand:SI 3 "register_operand" "")
7532         (mod:SI (match_dup 1) (match_dup 2)))
7533    (clobber (reg:CC FLAGS_REG))]
7534   "reload_completed"
7535   [(parallel [(set (match_dup 3)
7536                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7537               (clobber (reg:CC FLAGS_REG))])
7538    (parallel [(set (match_dup 0)
7539                    (div:SI (reg:SI 0) (match_dup 2)))
7540               (set (match_dup 3)
7541                    (mod:SI (reg:SI 0) (match_dup 2)))
7542               (use (match_dup 3))
7543               (clobber (reg:CC FLAGS_REG))])]
7545   /* Avoid use of cltd in favor of a mov+shift.  */
7546   if (!TARGET_USE_CLTD && !optimize_size)
7547     {
7548       if (true_regnum (operands[1]))
7549         emit_move_insn (operands[0], operands[1]);
7550       else
7551         emit_move_insn (operands[3], operands[1]);
7552       operands[4] = operands[3];
7553     }
7554   else
7555     {
7556       gcc_assert (!true_regnum (operands[1]));
7557       operands[4] = operands[1];
7558     }
7560 ;; %%% Split me.
7561 (define_insn "divmodhi4"
7562   [(set (match_operand:HI 0 "register_operand" "=a")
7563         (div:HI (match_operand:HI 1 "register_operand" "0")
7564                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7565    (set (match_operand:HI 3 "register_operand" "=&d")
7566         (mod:HI (match_dup 1) (match_dup 2)))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_HIMODE_MATH"
7569   "cwtd\;idiv{w}\t%2"
7570   [(set_attr "type" "multi")
7571    (set_attr "length_immediate" "0")
7572    (set_attr "mode" "SI")])
7574 (define_insn "udivmoddi4"
7575   [(set (match_operand:DI 0 "register_operand" "=a")
7576         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7577                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7578    (set (match_operand:DI 3 "register_operand" "=&d")
7579         (umod:DI (match_dup 1) (match_dup 2)))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "TARGET_64BIT"
7582   "xor{q}\t%3, %3\;div{q}\t%2"
7583   [(set_attr "type" "multi")
7584    (set_attr "length_immediate" "0")
7585    (set_attr "mode" "DI")])
7587 (define_insn "*udivmoddi4_noext"
7588   [(set (match_operand:DI 0 "register_operand" "=a")
7589         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7590                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7591    (set (match_operand:DI 3 "register_operand" "=d")
7592         (umod:DI (match_dup 1) (match_dup 2)))
7593    (use (match_dup 3))
7594    (clobber (reg:CC FLAGS_REG))]
7595   "TARGET_64BIT"
7596   "div{q}\t%2"
7597   [(set_attr "type" "idiv")
7598    (set_attr "mode" "DI")])
7600 (define_split
7601   [(set (match_operand:DI 0 "register_operand" "")
7602         (udiv:DI (match_operand:DI 1 "register_operand" "")
7603                  (match_operand:DI 2 "nonimmediate_operand" "")))
7604    (set (match_operand:DI 3 "register_operand" "")
7605         (umod:DI (match_dup 1) (match_dup 2)))
7606    (clobber (reg:CC FLAGS_REG))]
7607   "TARGET_64BIT && reload_completed"
7608   [(set (match_dup 3) (const_int 0))
7609    (parallel [(set (match_dup 0)
7610                    (udiv:DI (match_dup 1) (match_dup 2)))
7611               (set (match_dup 3)
7612                    (umod:DI (match_dup 1) (match_dup 2)))
7613               (use (match_dup 3))
7614               (clobber (reg:CC FLAGS_REG))])]
7615   "")
7617 (define_insn "udivmodsi4"
7618   [(set (match_operand:SI 0 "register_operand" "=a")
7619         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7620                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:SI 3 "register_operand" "=&d")
7622         (umod:SI (match_dup 1) (match_dup 2)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   ""
7625   "xor{l}\t%3, %3\;div{l}\t%2"
7626   [(set_attr "type" "multi")
7627    (set_attr "length_immediate" "0")
7628    (set_attr "mode" "SI")])
7630 (define_insn "*udivmodsi4_noext"
7631   [(set (match_operand:SI 0 "register_operand" "=a")
7632         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7633                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7634    (set (match_operand:SI 3 "register_operand" "=d")
7635         (umod:SI (match_dup 1) (match_dup 2)))
7636    (use (match_dup 3))
7637    (clobber (reg:CC FLAGS_REG))]
7638   ""
7639   "div{l}\t%2"
7640   [(set_attr "type" "idiv")
7641    (set_attr "mode" "SI")])
7643 (define_split
7644   [(set (match_operand:SI 0 "register_operand" "")
7645         (udiv:SI (match_operand:SI 1 "register_operand" "")
7646                  (match_operand:SI 2 "nonimmediate_operand" "")))
7647    (set (match_operand:SI 3 "register_operand" "")
7648         (umod:SI (match_dup 1) (match_dup 2)))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "reload_completed"
7651   [(set (match_dup 3) (const_int 0))
7652    (parallel [(set (match_dup 0)
7653                    (udiv:SI (match_dup 1) (match_dup 2)))
7654               (set (match_dup 3)
7655                    (umod:SI (match_dup 1) (match_dup 2)))
7656               (use (match_dup 3))
7657               (clobber (reg:CC FLAGS_REG))])]
7658   "")
7660 (define_expand "udivmodhi4"
7661   [(set (match_dup 4) (const_int 0))
7662    (parallel [(set (match_operand:HI 0 "register_operand" "")
7663                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7664                             (match_operand:HI 2 "nonimmediate_operand" "")))
7665               (set (match_operand:HI 3 "register_operand" "")
7666                    (umod:HI (match_dup 1) (match_dup 2)))
7667               (use (match_dup 4))
7668               (clobber (reg:CC FLAGS_REG))])]
7669   "TARGET_HIMODE_MATH"
7670   "operands[4] = gen_reg_rtx (HImode);")
7672 (define_insn "*udivmodhi_noext"
7673   [(set (match_operand:HI 0 "register_operand" "=a")
7674         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7675                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7676    (set (match_operand:HI 3 "register_operand" "=d")
7677         (umod:HI (match_dup 1) (match_dup 2)))
7678    (use (match_operand:HI 4 "register_operand" "3"))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "div{w}\t%2"
7682   [(set_attr "type" "idiv")
7683    (set_attr "mode" "HI")])
7685 ;; We cannot use div/idiv for double division, because it causes
7686 ;; "division by zero" on the overflow and that's not what we expect
7687 ;; from truncate.  Because true (non truncating) double division is
7688 ;; never generated, we can't create this insn anyway.
7690 ;(define_insn ""
7691 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7692 ;       (truncate:SI
7693 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7694 ;                  (zero_extend:DI
7695 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7696 ;   (set (match_operand:SI 3 "register_operand" "=d")
7697 ;       (truncate:SI
7698 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7699 ;   (clobber (reg:CC FLAGS_REG))]
7700 ;  ""
7701 ;  "div{l}\t{%2, %0|%0, %2}"
7702 ;  [(set_attr "type" "idiv")])
7704 ;;- Logical AND instructions
7706 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7707 ;; Note that this excludes ah.
7709 (define_insn "*testdi_1_rex64"
7710   [(set (reg FLAGS_REG)
7711         (compare
7712           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7713                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7714           (const_int 0)))]
7715   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7716    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7717   "@
7718    test{l}\t{%k1, %k0|%k0, %k1}
7719    test{l}\t{%k1, %k0|%k0, %k1}
7720    test{q}\t{%1, %0|%0, %1}
7721    test{q}\t{%1, %0|%0, %1}
7722    test{q}\t{%1, %0|%0, %1}"
7723   [(set_attr "type" "test")
7724    (set_attr "modrm" "0,1,0,1,1")
7725    (set_attr "mode" "SI,SI,DI,DI,DI")
7726    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7728 (define_insn "testsi_1"
7729   [(set (reg FLAGS_REG)
7730         (compare
7731           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7732                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7733           (const_int 0)))]
7734   "ix86_match_ccmode (insn, CCNOmode)
7735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7736   "test{l}\t{%1, %0|%0, %1}"
7737   [(set_attr "type" "test")
7738    (set_attr "modrm" "0,1,1")
7739    (set_attr "mode" "SI")
7740    (set_attr "pent_pair" "uv,np,uv")])
7742 (define_expand "testsi_ccno_1"
7743   [(set (reg:CCNO FLAGS_REG)
7744         (compare:CCNO
7745           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7746                   (match_operand:SI 1 "nonmemory_operand" ""))
7747           (const_int 0)))]
7748   ""
7749   "")
7751 (define_insn "*testhi_1"
7752   [(set (reg FLAGS_REG)
7753         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7754                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7755                  (const_int 0)))]
7756   "ix86_match_ccmode (insn, CCNOmode)
7757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7758   "test{w}\t{%1, %0|%0, %1}"
7759   [(set_attr "type" "test")
7760    (set_attr "modrm" "0,1,1")
7761    (set_attr "mode" "HI")
7762    (set_attr "pent_pair" "uv,np,uv")])
7764 (define_expand "testqi_ccz_1"
7765   [(set (reg:CCZ FLAGS_REG)
7766         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7767                              (match_operand:QI 1 "nonmemory_operand" ""))
7768                  (const_int 0)))]
7769   ""
7770   "")
7772 (define_insn "*testqi_1_maybe_si"
7773   [(set (reg FLAGS_REG)
7774         (compare
7775           (and:QI
7776             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7777             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7778           (const_int 0)))]
7779    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7780     && ix86_match_ccmode (insn,
7781                          GET_CODE (operands[1]) == CONST_INT
7782                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7784   if (which_alternative == 3)
7785     {
7786       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7787         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7788       return "test{l}\t{%1, %k0|%k0, %1}";
7789     }
7790   return "test{b}\t{%1, %0|%0, %1}";
7792   [(set_attr "type" "test")
7793    (set_attr "modrm" "0,1,1,1")
7794    (set_attr "mode" "QI,QI,QI,SI")
7795    (set_attr "pent_pair" "uv,np,uv,np")])
7797 (define_insn "*testqi_1"
7798   [(set (reg FLAGS_REG)
7799         (compare
7800           (and:QI
7801             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7802             (match_operand:QI 1 "general_operand" "n,n,qn"))
7803           (const_int 0)))]
7804   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7805    && ix86_match_ccmode (insn, CCNOmode)"
7806   "test{b}\t{%1, %0|%0, %1}"
7807   [(set_attr "type" "test")
7808    (set_attr "modrm" "0,1,1")
7809    (set_attr "mode" "QI")
7810    (set_attr "pent_pair" "uv,np,uv")])
7812 (define_expand "testqi_ext_ccno_0"
7813   [(set (reg:CCNO FLAGS_REG)
7814         (compare:CCNO
7815           (and:SI
7816             (zero_extract:SI
7817               (match_operand 0 "ext_register_operand" "")
7818               (const_int 8)
7819               (const_int 8))
7820             (match_operand 1 "const_int_operand" ""))
7821           (const_int 0)))]
7822   ""
7823   "")
7825 (define_insn "*testqi_ext_0"
7826   [(set (reg FLAGS_REG)
7827         (compare
7828           (and:SI
7829             (zero_extract:SI
7830               (match_operand 0 "ext_register_operand" "Q")
7831               (const_int 8)
7832               (const_int 8))
7833             (match_operand 1 "const_int_operand" "n"))
7834           (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)"
7836   "test{b}\t{%1, %h0|%h0, %1}"
7837   [(set_attr "type" "test")
7838    (set_attr "mode" "QI")
7839    (set_attr "length_immediate" "1")
7840    (set_attr "pent_pair" "np")])
7842 (define_insn "*testqi_ext_1"
7843   [(set (reg FLAGS_REG)
7844         (compare
7845           (and:SI
7846             (zero_extract:SI
7847               (match_operand 0 "ext_register_operand" "Q")
7848               (const_int 8)
7849               (const_int 8))
7850             (zero_extend:SI
7851               (match_operand:QI 1 "general_operand" "Qm")))
7852           (const_int 0)))]
7853   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7854    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7855   "test{b}\t{%1, %h0|%h0, %1}"
7856   [(set_attr "type" "test")
7857    (set_attr "mode" "QI")])
7859 (define_insn "*testqi_ext_1_rex64"
7860   [(set (reg FLAGS_REG)
7861         (compare
7862           (and:SI
7863             (zero_extract:SI
7864               (match_operand 0 "ext_register_operand" "Q")
7865               (const_int 8)
7866               (const_int 8))
7867             (zero_extend:SI
7868               (match_operand:QI 1 "register_operand" "Q")))
7869           (const_int 0)))]
7870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7871   "test{b}\t{%1, %h0|%h0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "mode" "QI")])
7875 (define_insn "*testqi_ext_2"
7876   [(set (reg FLAGS_REG)
7877         (compare
7878           (and:SI
7879             (zero_extract:SI
7880               (match_operand 0 "ext_register_operand" "Q")
7881               (const_int 8)
7882               (const_int 8))
7883             (zero_extract:SI
7884               (match_operand 1 "ext_register_operand" "Q")
7885               (const_int 8)
7886               (const_int 8)))
7887           (const_int 0)))]
7888   "ix86_match_ccmode (insn, CCNOmode)"
7889   "test{b}\t{%h1, %h0|%h0, %h1}"
7890   [(set_attr "type" "test")
7891    (set_attr "mode" "QI")])
7893 ;; Combine likes to form bit extractions for some tests.  Humor it.
7894 (define_insn "*testqi_ext_3"
7895   [(set (reg FLAGS_REG)
7896         (compare (zero_extract:SI
7897                    (match_operand 0 "nonimmediate_operand" "rm")
7898                    (match_operand:SI 1 "const_int_operand" "")
7899                    (match_operand:SI 2 "const_int_operand" ""))
7900                  (const_int 0)))]
7901   "ix86_match_ccmode (insn, CCNOmode)
7902    && INTVAL (operands[1]) > 0
7903    && INTVAL (operands[2]) >= 0
7904    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7905    && (GET_MODE (operands[0]) == SImode
7906        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7907        || GET_MODE (operands[0]) == HImode
7908        || GET_MODE (operands[0]) == QImode)"
7909   "#")
7911 (define_insn "*testqi_ext_3_rex64"
7912   [(set (reg FLAGS_REG)
7913         (compare (zero_extract:DI
7914                    (match_operand 0 "nonimmediate_operand" "rm")
7915                    (match_operand:DI 1 "const_int_operand" "")
7916                    (match_operand:DI 2 "const_int_operand" ""))
7917                  (const_int 0)))]
7918   "TARGET_64BIT
7919    && ix86_match_ccmode (insn, CCNOmode)
7920    && INTVAL (operands[1]) > 0
7921    && INTVAL (operands[2]) >= 0
7922    /* Ensure that resulting mask is zero or sign extended operand.  */
7923    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7924        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7925            && INTVAL (operands[1]) > 32))
7926    && (GET_MODE (operands[0]) == SImode
7927        || GET_MODE (operands[0]) == DImode
7928        || GET_MODE (operands[0]) == HImode
7929        || GET_MODE (operands[0]) == QImode)"
7930   "#")
7932 (define_split
7933   [(set (match_operand 0 "flags_reg_operand" "")
7934         (match_operator 1 "compare_operator"
7935           [(zero_extract
7936              (match_operand 2 "nonimmediate_operand" "")
7937              (match_operand 3 "const_int_operand" "")
7938              (match_operand 4 "const_int_operand" ""))
7939            (const_int 0)]))]
7940   "ix86_match_ccmode (insn, CCNOmode)"
7941   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7943   rtx val = operands[2];
7944   HOST_WIDE_INT len = INTVAL (operands[3]);
7945   HOST_WIDE_INT pos = INTVAL (operands[4]);
7946   HOST_WIDE_INT mask;
7947   enum machine_mode mode, submode;
7949   mode = GET_MODE (val);
7950   if (GET_CODE (val) == MEM)
7951     {
7952       /* ??? Combine likes to put non-volatile mem extractions in QImode
7953          no matter the size of the test.  So find a mode that works.  */
7954       if (! MEM_VOLATILE_P (val))
7955         {
7956           mode = smallest_mode_for_size (pos + len, MODE_INT);
7957           val = adjust_address (val, mode, 0);
7958         }
7959     }
7960   else if (GET_CODE (val) == SUBREG
7961            && (submode = GET_MODE (SUBREG_REG (val)),
7962                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7963            && pos + len <= GET_MODE_BITSIZE (submode))
7964     {
7965       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7966       mode = submode;
7967       val = SUBREG_REG (val);
7968     }
7969   else if (mode == HImode && pos + len <= 8)
7970     {
7971       /* Small HImode tests can be converted to QImode.  */
7972       mode = QImode;
7973       val = gen_lowpart (QImode, val);
7974     }
7976   if (len == HOST_BITS_PER_WIDE_INT)
7977     mask = -1;
7978   else
7979     mask = ((HOST_WIDE_INT)1 << len) - 1;
7980   mask <<= pos;
7982   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7985 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7986 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7987 ;; this is relatively important trick.
7988 ;; Do the conversion only post-reload to avoid limiting of the register class
7989 ;; to QI regs.
7990 (define_split
7991   [(set (match_operand 0 "flags_reg_operand" "")
7992         (match_operator 1 "compare_operator"
7993           [(and (match_operand 2 "register_operand" "")
7994                 (match_operand 3 "const_int_operand" ""))
7995            (const_int 0)]))]
7996    "reload_completed
7997     && QI_REG_P (operands[2])
7998     && GET_MODE (operands[2]) != QImode
7999     && ((ix86_match_ccmode (insn, CCZmode)
8000          && !(INTVAL (operands[3]) & ~(255 << 8)))
8001         || (ix86_match_ccmode (insn, CCNOmode)
8002             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8003   [(set (match_dup 0)
8004         (match_op_dup 1
8005           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8006                    (match_dup 3))
8007            (const_int 0)]))]
8008   "operands[2] = gen_lowpart (SImode, operands[2]);
8009    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8011 (define_split
8012   [(set (match_operand 0 "flags_reg_operand" "")
8013         (match_operator 1 "compare_operator"
8014           [(and (match_operand 2 "nonimmediate_operand" "")
8015                 (match_operand 3 "const_int_operand" ""))
8016            (const_int 0)]))]
8017    "reload_completed
8018     && GET_MODE (operands[2]) != QImode
8019     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8020     && ((ix86_match_ccmode (insn, CCZmode)
8021          && !(INTVAL (operands[3]) & ~255))
8022         || (ix86_match_ccmode (insn, CCNOmode)
8023             && !(INTVAL (operands[3]) & ~127)))"
8024   [(set (match_dup 0)
8025         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8026                          (const_int 0)]))]
8027   "operands[2] = gen_lowpart (QImode, operands[2]);
8028    operands[3] = gen_lowpart (QImode, operands[3]);")
8031 ;; %%% This used to optimize known byte-wide and operations to memory,
8032 ;; and sometimes to QImode registers.  If this is considered useful,
8033 ;; it should be done with splitters.
8035 (define_expand "anddi3"
8036   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8037         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8038                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "TARGET_64BIT"
8041   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8043 (define_insn "*anddi_1_rex64"
8044   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8045         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8046                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8050   switch (get_attr_type (insn))
8051     {
8052     case TYPE_IMOVX:
8053       {
8054         enum machine_mode mode;
8056         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8057         if (INTVAL (operands[2]) == 0xff)
8058           mode = QImode;
8059         else
8060           {
8061             gcc_assert (INTVAL (operands[2]) == 0xffff);
8062             mode = HImode;
8063           }
8064         
8065         operands[1] = gen_lowpart (mode, operands[1]);
8066         if (mode == QImode)
8067           return "movz{bq|x}\t{%1,%0|%0, %1}";
8068         else
8069           return "movz{wq|x}\t{%1,%0|%0, %1}";
8070       }
8072     default:
8073       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8074       if (get_attr_mode (insn) == MODE_SI)
8075         return "and{l}\t{%k2, %k0|%k0, %k2}";
8076       else
8077         return "and{q}\t{%2, %0|%0, %2}";
8078     }
8080   [(set_attr "type" "alu,alu,alu,imovx")
8081    (set_attr "length_immediate" "*,*,*,0")
8082    (set_attr "mode" "SI,DI,DI,DI")])
8084 (define_insn "*anddi_2"
8085   [(set (reg FLAGS_REG)
8086         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8087                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8088                  (const_int 0)))
8089    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8090         (and:DI (match_dup 1) (match_dup 2)))]
8091   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092    && ix86_binary_operator_ok (AND, DImode, operands)"
8093   "@
8094    and{l}\t{%k2, %k0|%k0, %k2}
8095    and{q}\t{%2, %0|%0, %2}
8096    and{q}\t{%2, %0|%0, %2}"
8097   [(set_attr "type" "alu")
8098    (set_attr "mode" "SI,DI,DI")])
8100 (define_expand "andsi3"
8101   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8102         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8103                 (match_operand:SI 2 "general_operand" "")))
8104    (clobber (reg:CC FLAGS_REG))]
8105   ""
8106   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8108 (define_insn "*andsi_1"
8109   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8110         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8111                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "ix86_binary_operator_ok (AND, SImode, operands)"
8115   switch (get_attr_type (insn))
8116     {
8117     case TYPE_IMOVX:
8118       {
8119         enum machine_mode mode;
8121         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8122         if (INTVAL (operands[2]) == 0xff)
8123           mode = QImode;
8124         else
8125           {
8126             gcc_assert (INTVAL (operands[2]) == 0xffff);
8127             mode = HImode;
8128           }
8129         
8130         operands[1] = gen_lowpart (mode, operands[1]);
8131         if (mode == QImode)
8132           return "movz{bl|x}\t{%1,%0|%0, %1}";
8133         else
8134           return "movz{wl|x}\t{%1,%0|%0, %1}";
8135       }
8137     default:
8138       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8139       return "and{l}\t{%2, %0|%0, %2}";
8140     }
8142   [(set_attr "type" "alu,alu,imovx")
8143    (set_attr "length_immediate" "*,*,0")
8144    (set_attr "mode" "SI")])
8146 (define_split
8147   [(set (match_operand 0 "register_operand" "")
8148         (and (match_dup 0)
8149              (const_int -65536)))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8152   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8153   "operands[1] = gen_lowpart (HImode, operands[0]);")
8155 (define_split
8156   [(set (match_operand 0 "ext_register_operand" "")
8157         (and (match_dup 0)
8158              (const_int -256)))
8159    (clobber (reg:CC FLAGS_REG))]
8160   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8161   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8162   "operands[1] = gen_lowpart (QImode, operands[0]);")
8164 (define_split
8165   [(set (match_operand 0 "ext_register_operand" "")
8166         (and (match_dup 0)
8167              (const_int -65281)))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8170   [(parallel [(set (zero_extract:SI (match_dup 0)
8171                                     (const_int 8)
8172                                     (const_int 8))
8173                    (xor:SI 
8174                      (zero_extract:SI (match_dup 0)
8175                                       (const_int 8)
8176                                       (const_int 8))
8177                      (zero_extract:SI (match_dup 0)
8178                                       (const_int 8)
8179                                       (const_int 8))))
8180               (clobber (reg:CC FLAGS_REG))])]
8181   "operands[0] = gen_lowpart (SImode, operands[0]);")
8183 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8184 (define_insn "*andsi_1_zext"
8185   [(set (match_operand:DI 0 "register_operand" "=r")
8186         (zero_extend:DI
8187           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8188                   (match_operand:SI 2 "general_operand" "rim"))))
8189    (clobber (reg:CC FLAGS_REG))]
8190   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8191   "and{l}\t{%2, %k0|%k0, %2}"
8192   [(set_attr "type" "alu")
8193    (set_attr "mode" "SI")])
8195 (define_insn "*andsi_2"
8196   [(set (reg FLAGS_REG)
8197         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8198                          (match_operand:SI 2 "general_operand" "rim,ri"))
8199                  (const_int 0)))
8200    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8201         (and:SI (match_dup 1) (match_dup 2)))]
8202   "ix86_match_ccmode (insn, CCNOmode)
8203    && ix86_binary_operator_ok (AND, SImode, operands)"
8204   "and{l}\t{%2, %0|%0, %2}"
8205   [(set_attr "type" "alu")
8206    (set_attr "mode" "SI")])
8208 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8209 (define_insn "*andsi_2_zext"
8210   [(set (reg FLAGS_REG)
8211         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8212                          (match_operand:SI 2 "general_operand" "rim"))
8213                  (const_int 0)))
8214    (set (match_operand:DI 0 "register_operand" "=r")
8215         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8216   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8217    && ix86_binary_operator_ok (AND, SImode, operands)"
8218   "and{l}\t{%2, %k0|%k0, %2}"
8219   [(set_attr "type" "alu")
8220    (set_attr "mode" "SI")])
8222 (define_expand "andhi3"
8223   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8224         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8225                 (match_operand:HI 2 "general_operand" "")))
8226    (clobber (reg:CC FLAGS_REG))]
8227   "TARGET_HIMODE_MATH"
8228   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8230 (define_insn "*andhi_1"
8231   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8232         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8233                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "ix86_binary_operator_ok (AND, HImode, operands)"
8237   switch (get_attr_type (insn))
8238     {
8239     case TYPE_IMOVX:
8240       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8241       gcc_assert (INTVAL (operands[2]) == 0xff);
8242       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8244     default:
8245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8247       return "and{w}\t{%2, %0|%0, %2}";
8248     }
8250   [(set_attr "type" "alu,alu,imovx")
8251    (set_attr "length_immediate" "*,*,0")
8252    (set_attr "mode" "HI,HI,SI")])
8254 (define_insn "*andhi_2"
8255   [(set (reg FLAGS_REG)
8256         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8257                          (match_operand:HI 2 "general_operand" "rim,ri"))
8258                  (const_int 0)))
8259    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8260         (and:HI (match_dup 1) (match_dup 2)))]
8261   "ix86_match_ccmode (insn, CCNOmode)
8262    && ix86_binary_operator_ok (AND, HImode, operands)"
8263   "and{w}\t{%2, %0|%0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "mode" "HI")])
8267 (define_expand "andqi3"
8268   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8269         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8270                 (match_operand:QI 2 "general_operand" "")))
8271    (clobber (reg:CC FLAGS_REG))]
8272   "TARGET_QIMODE_MATH"
8273   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8275 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8276 (define_insn "*andqi_1"
8277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8278         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8279                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "ix86_binary_operator_ok (AND, QImode, operands)"
8282   "@
8283    and{b}\t{%2, %0|%0, %2}
8284    and{b}\t{%2, %0|%0, %2}
8285    and{l}\t{%k2, %k0|%k0, %k2}"
8286   [(set_attr "type" "alu")
8287    (set_attr "mode" "QI,QI,SI")])
8289 (define_insn "*andqi_1_slp"
8290   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8291         (and:QI (match_dup 0)
8292                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8293    (clobber (reg:CC FLAGS_REG))]
8294   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8295    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8296   "and{b}\t{%1, %0|%0, %1}"
8297   [(set_attr "type" "alu1")
8298    (set_attr "mode" "QI")])
8300 (define_insn "*andqi_2_maybe_si"
8301   [(set (reg FLAGS_REG)
8302         (compare (and:QI
8303                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8304                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8305                  (const_int 0)))
8306    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8307         (and:QI (match_dup 1) (match_dup 2)))]
8308   "ix86_binary_operator_ok (AND, QImode, operands)
8309    && ix86_match_ccmode (insn,
8310                          GET_CODE (operands[2]) == CONST_INT
8311                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8313   if (which_alternative == 2)
8314     {
8315       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8316         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8317       return "and{l}\t{%2, %k0|%k0, %2}";
8318     }
8319   return "and{b}\t{%2, %0|%0, %2}";
8321   [(set_attr "type" "alu")
8322    (set_attr "mode" "QI,QI,SI")])
8324 (define_insn "*andqi_2"
8325   [(set (reg FLAGS_REG)
8326         (compare (and:QI
8327                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8328                    (match_operand:QI 2 "general_operand" "qim,qi"))
8329                  (const_int 0)))
8330    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8331         (and:QI (match_dup 1) (match_dup 2)))]
8332   "ix86_match_ccmode (insn, CCNOmode)
8333    && ix86_binary_operator_ok (AND, QImode, operands)"
8334   "and{b}\t{%2, %0|%0, %2}"
8335   [(set_attr "type" "alu")
8336    (set_attr "mode" "QI")])
8338 (define_insn "*andqi_2_slp"
8339   [(set (reg FLAGS_REG)
8340         (compare (and:QI
8341                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8342                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8343                  (const_int 0)))
8344    (set (strict_low_part (match_dup 0))
8345         (and:QI (match_dup 0) (match_dup 1)))]
8346   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8347    && ix86_match_ccmode (insn, CCNOmode)
8348    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8349   "and{b}\t{%1, %0|%0, %1}"
8350   [(set_attr "type" "alu1")
8351    (set_attr "mode" "QI")])
8353 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8354 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8355 ;; for a QImode operand, which of course failed.
8357 (define_insn "andqi_ext_0"
8358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359                          (const_int 8)
8360                          (const_int 8))
8361         (and:SI 
8362           (zero_extract:SI
8363             (match_operand 1 "ext_register_operand" "0")
8364             (const_int 8)
8365             (const_int 8))
8366           (match_operand 2 "const_int_operand" "n")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   ""
8369   "and{b}\t{%2, %h0|%h0, %2}"
8370   [(set_attr "type" "alu")
8371    (set_attr "length_immediate" "1")
8372    (set_attr "mode" "QI")])
8374 ;; Generated by peephole translating test to and.  This shows up
8375 ;; often in fp comparisons.
8377 (define_insn "*andqi_ext_0_cc"
8378   [(set (reg FLAGS_REG)
8379         (compare
8380           (and:SI
8381             (zero_extract:SI
8382               (match_operand 1 "ext_register_operand" "0")
8383               (const_int 8)
8384               (const_int 8))
8385             (match_operand 2 "const_int_operand" "n"))
8386           (const_int 0)))
8387    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388                          (const_int 8)
8389                          (const_int 8))
8390         (and:SI 
8391           (zero_extract:SI
8392             (match_dup 1)
8393             (const_int 8)
8394             (const_int 8))
8395           (match_dup 2)))]
8396   "ix86_match_ccmode (insn, CCNOmode)"
8397   "and{b}\t{%2, %h0|%h0, %2}"
8398   [(set_attr "type" "alu")
8399    (set_attr "length_immediate" "1")
8400    (set_attr "mode" "QI")])
8402 (define_insn "*andqi_ext_1"
8403   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404                          (const_int 8)
8405                          (const_int 8))
8406         (and:SI 
8407           (zero_extract:SI
8408             (match_operand 1 "ext_register_operand" "0")
8409             (const_int 8)
8410             (const_int 8))
8411           (zero_extend:SI
8412             (match_operand:QI 2 "general_operand" "Qm"))))
8413    (clobber (reg:CC FLAGS_REG))]
8414   "!TARGET_64BIT"
8415   "and{b}\t{%2, %h0|%h0, %2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8420 (define_insn "*andqi_ext_1_rex64"
8421   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422                          (const_int 8)
8423                          (const_int 8))
8424         (and:SI 
8425           (zero_extract:SI
8426             (match_operand 1 "ext_register_operand" "0")
8427             (const_int 8)
8428             (const_int 8))
8429           (zero_extend:SI
8430             (match_operand 2 "ext_register_operand" "Q"))))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "TARGET_64BIT"
8433   "and{b}\t{%2, %h0|%h0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "length_immediate" "0")
8436    (set_attr "mode" "QI")])
8438 (define_insn "*andqi_ext_2"
8439   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8440                          (const_int 8)
8441                          (const_int 8))
8442         (and:SI
8443           (zero_extract:SI
8444             (match_operand 1 "ext_register_operand" "%0")
8445             (const_int 8)
8446             (const_int 8))
8447           (zero_extract:SI
8448             (match_operand 2 "ext_register_operand" "Q")
8449             (const_int 8)
8450             (const_int 8))))
8451    (clobber (reg:CC FLAGS_REG))]
8452   ""
8453   "and{b}\t{%h2, %h0|%h0, %h2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "0")
8456    (set_attr "mode" "QI")])
8458 ;; Convert wide AND instructions with immediate operand to shorter QImode
8459 ;; equivalents when possible.
8460 ;; Don't do the splitting with memory operands, since it introduces risk
8461 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8462 ;; for size, but that can (should?) be handled by generic code instead.
8463 (define_split
8464   [(set (match_operand 0 "register_operand" "")
8465         (and (match_operand 1 "register_operand" "")
8466              (match_operand 2 "const_int_operand" "")))
8467    (clobber (reg:CC FLAGS_REG))]
8468    "reload_completed
8469     && QI_REG_P (operands[0])
8470     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8471     && !(~INTVAL (operands[2]) & ~(255 << 8))
8472     && GET_MODE (operands[0]) != QImode"
8473   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8474                    (and:SI (zero_extract:SI (match_dup 1)
8475                                             (const_int 8) (const_int 8))
8476                            (match_dup 2)))
8477               (clobber (reg:CC FLAGS_REG))])]
8478   "operands[0] = gen_lowpart (SImode, operands[0]);
8479    operands[1] = gen_lowpart (SImode, operands[1]);
8480    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8482 ;; Since AND can be encoded with sign extended immediate, this is only
8483 ;; profitable when 7th bit is not set.
8484 (define_split
8485   [(set (match_operand 0 "register_operand" "")
8486         (and (match_operand 1 "general_operand" "")
8487              (match_operand 2 "const_int_operand" "")))
8488    (clobber (reg:CC FLAGS_REG))]
8489    "reload_completed
8490     && ANY_QI_REG_P (operands[0])
8491     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8492     && !(~INTVAL (operands[2]) & ~255)
8493     && !(INTVAL (operands[2]) & 128)
8494     && GET_MODE (operands[0]) != QImode"
8495   [(parallel [(set (strict_low_part (match_dup 0))
8496                    (and:QI (match_dup 1)
8497                            (match_dup 2)))
8498               (clobber (reg:CC FLAGS_REG))])]
8499   "operands[0] = gen_lowpart (QImode, operands[0]);
8500    operands[1] = gen_lowpart (QImode, operands[1]);
8501    operands[2] = gen_lowpart (QImode, operands[2]);")
8503 ;; Logical inclusive OR instructions
8505 ;; %%% This used to optimize known byte-wide and operations to memory.
8506 ;; If this is considered useful, it should be done with splitters.
8508 (define_expand "iordi3"
8509   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8510         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8511                 (match_operand:DI 2 "x86_64_general_operand" "")))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "TARGET_64BIT"
8514   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8516 (define_insn "*iordi_1_rex64"
8517   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8518         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8519                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT
8522    && ix86_binary_operator_ok (IOR, DImode, operands)"
8523   "or{q}\t{%2, %0|%0, %2}"
8524   [(set_attr "type" "alu")
8525    (set_attr "mode" "DI")])
8527 (define_insn "*iordi_2_rex64"
8528   [(set (reg FLAGS_REG)
8529         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8530                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8531                  (const_int 0)))
8532    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8533         (ior:DI (match_dup 1) (match_dup 2)))]
8534   "TARGET_64BIT
8535    && ix86_match_ccmode (insn, CCNOmode)
8536    && ix86_binary_operator_ok (IOR, DImode, operands)"
8537   "or{q}\t{%2, %0|%0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "DI")])
8541 (define_insn "*iordi_3_rex64"
8542   [(set (reg FLAGS_REG)
8543         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8544                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8545                  (const_int 0)))
8546    (clobber (match_scratch:DI 0 "=r"))]
8547   "TARGET_64BIT
8548    && ix86_match_ccmode (insn, CCNOmode)
8549    && ix86_binary_operator_ok (IOR, DImode, operands)"
8550   "or{q}\t{%2, %0|%0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "DI")])
8555 (define_expand "iorsi3"
8556   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8557         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8558                 (match_operand:SI 2 "general_operand" "")))
8559    (clobber (reg:CC FLAGS_REG))]
8560   ""
8561   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8563 (define_insn "*iorsi_1"
8564   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8565         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8566                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "ix86_binary_operator_ok (IOR, SImode, operands)"
8569   "or{l}\t{%2, %0|%0, %2}"
8570   [(set_attr "type" "alu")
8571    (set_attr "mode" "SI")])
8573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8574 (define_insn "*iorsi_1_zext"
8575   [(set (match_operand:DI 0 "register_operand" "=rm")
8576         (zero_extend:DI
8577           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8578                   (match_operand:SI 2 "general_operand" "rim"))))
8579    (clobber (reg:CC FLAGS_REG))]
8580   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8581   "or{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8585 (define_insn "*iorsi_1_zext_imm"
8586   [(set (match_operand:DI 0 "register_operand" "=rm")
8587         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8588                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8589    (clobber (reg:CC FLAGS_REG))]
8590   "TARGET_64BIT"
8591   "or{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8595 (define_insn "*iorsi_2"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8598                          (match_operand:SI 2 "general_operand" "rim,ri"))
8599                  (const_int 0)))
8600    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8601         (ior:SI (match_dup 1) (match_dup 2)))]
8602   "ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, SImode, operands)"
8604   "or{l}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "SI")])
8608 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8609 ;; ??? Special case for immediate operand is missing - it is tricky.
8610 (define_insn "*iorsi_2_zext"
8611   [(set (reg FLAGS_REG)
8612         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8613                          (match_operand:SI 2 "general_operand" "rim"))
8614                  (const_int 0)))
8615    (set (match_operand:DI 0 "register_operand" "=r")
8616         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8617   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8618    && ix86_binary_operator_ok (IOR, SImode, operands)"
8619   "or{l}\t{%2, %k0|%k0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "SI")])
8623 (define_insn "*iorsi_2_zext_imm"
8624   [(set (reg FLAGS_REG)
8625         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8626                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8627                  (const_int 0)))
8628    (set (match_operand:DI 0 "register_operand" "=r")
8629         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8630   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8631    && ix86_binary_operator_ok (IOR, SImode, operands)"
8632   "or{l}\t{%2, %k0|%k0, %2}"
8633   [(set_attr "type" "alu")
8634    (set_attr "mode" "SI")])
8636 (define_insn "*iorsi_3"
8637   [(set (reg FLAGS_REG)
8638         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8639                          (match_operand:SI 2 "general_operand" "rim"))
8640                  (const_int 0)))
8641    (clobber (match_scratch:SI 0 "=r"))]
8642   "ix86_match_ccmode (insn, CCNOmode)
8643    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8644   "or{l}\t{%2, %0|%0, %2}"
8645   [(set_attr "type" "alu")
8646    (set_attr "mode" "SI")])
8648 (define_expand "iorhi3"
8649   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8650         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8651                 (match_operand:HI 2 "general_operand" "")))
8652    (clobber (reg:CC FLAGS_REG))]
8653   "TARGET_HIMODE_MATH"
8654   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8656 (define_insn "*iorhi_1"
8657   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8658         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8659                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8660    (clobber (reg:CC FLAGS_REG))]
8661   "ix86_binary_operator_ok (IOR, HImode, operands)"
8662   "or{w}\t{%2, %0|%0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "mode" "HI")])
8666 (define_insn "*iorhi_2"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8669                          (match_operand:HI 2 "general_operand" "rim,ri"))
8670                  (const_int 0)))
8671    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8672         (ior:HI (match_dup 1) (match_dup 2)))]
8673   "ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, HImode, operands)"
8675   "or{w}\t{%2, %0|%0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "HI")])
8679 (define_insn "*iorhi_3"
8680   [(set (reg FLAGS_REG)
8681         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8682                          (match_operand:HI 2 "general_operand" "rim"))
8683                  (const_int 0)))
8684    (clobber (match_scratch:HI 0 "=r"))]
8685   "ix86_match_ccmode (insn, CCNOmode)
8686    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8687   "or{w}\t{%2, %0|%0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "HI")])
8691 (define_expand "iorqi3"
8692   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8693         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8694                 (match_operand:QI 2 "general_operand" "")))
8695    (clobber (reg:CC FLAGS_REG))]
8696   "TARGET_QIMODE_MATH"
8697   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8699 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8700 (define_insn "*iorqi_1"
8701   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8702         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8703                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "ix86_binary_operator_ok (IOR, QImode, operands)"
8706   "@
8707    or{b}\t{%2, %0|%0, %2}
8708    or{b}\t{%2, %0|%0, %2}
8709    or{l}\t{%k2, %k0|%k0, %k2}"
8710   [(set_attr "type" "alu")
8711    (set_attr "mode" "QI,QI,SI")])
8713 (define_insn "*iorqi_1_slp"
8714   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8715         (ior:QI (match_dup 0)
8716                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8719    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8720   "or{b}\t{%1, %0|%0, %1}"
8721   [(set_attr "type" "alu1")
8722    (set_attr "mode" "QI")])
8724 (define_insn "*iorqi_2"
8725   [(set (reg FLAGS_REG)
8726         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8727                          (match_operand:QI 2 "general_operand" "qim,qi"))
8728                  (const_int 0)))
8729    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8730         (ior:QI (match_dup 1) (match_dup 2)))]
8731   "ix86_match_ccmode (insn, CCNOmode)
8732    && ix86_binary_operator_ok (IOR, QImode, operands)"
8733   "or{b}\t{%2, %0|%0, %2}"
8734   [(set_attr "type" "alu")
8735    (set_attr "mode" "QI")])
8737 (define_insn "*iorqi_2_slp"
8738   [(set (reg FLAGS_REG)
8739         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8740                          (match_operand:QI 1 "general_operand" "qim,qi"))
8741                  (const_int 0)))
8742    (set (strict_low_part (match_dup 0))
8743         (ior:QI (match_dup 0) (match_dup 1)))]
8744   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8745    && ix86_match_ccmode (insn, CCNOmode)
8746    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8747   "or{b}\t{%1, %0|%0, %1}"
8748   [(set_attr "type" "alu1")
8749    (set_attr "mode" "QI")])
8751 (define_insn "*iorqi_3"
8752   [(set (reg FLAGS_REG)
8753         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8754                          (match_operand:QI 2 "general_operand" "qim"))
8755                  (const_int 0)))
8756    (clobber (match_scratch:QI 0 "=q"))]
8757   "ix86_match_ccmode (insn, CCNOmode)
8758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8759   "or{b}\t{%2, %0|%0, %2}"
8760   [(set_attr "type" "alu")
8761    (set_attr "mode" "QI")])
8763 (define_insn "iorqi_ext_0"
8764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765                          (const_int 8)
8766                          (const_int 8))
8767         (ior:SI 
8768           (zero_extract:SI
8769             (match_operand 1 "ext_register_operand" "0")
8770             (const_int 8)
8771             (const_int 8))
8772           (match_operand 2 "const_int_operand" "n")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775   "or{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "1")
8778    (set_attr "mode" "QI")])
8780 (define_insn "*iorqi_ext_1"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (ior:SI 
8785           (zero_extract:SI
8786             (match_operand 1 "ext_register_operand" "0")
8787             (const_int 8)
8788             (const_int 8))
8789           (zero_extend:SI
8790             (match_operand:QI 2 "general_operand" "Qm"))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "!TARGET_64BIT
8793    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8794   "or{b}\t{%2, %h0|%h0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "length_immediate" "0")
8797    (set_attr "mode" "QI")])
8799 (define_insn "*iorqi_ext_1_rex64"
8800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801                          (const_int 8)
8802                          (const_int 8))
8803         (ior:SI 
8804           (zero_extract:SI
8805             (match_operand 1 "ext_register_operand" "0")
8806             (const_int 8)
8807             (const_int 8))
8808           (zero_extend:SI
8809             (match_operand 2 "ext_register_operand" "Q"))))
8810    (clobber (reg:CC FLAGS_REG))]
8811   "TARGET_64BIT
8812    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813   "or{b}\t{%2, %h0|%h0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "length_immediate" "0")
8816    (set_attr "mode" "QI")])
8818 (define_insn "*iorqi_ext_2"
8819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820                          (const_int 8)
8821                          (const_int 8))
8822         (ior:SI 
8823           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8824                            (const_int 8)
8825                            (const_int 8))
8826           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8827                            (const_int 8)
8828                            (const_int 8))))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "ior{b}\t{%h2, %h0|%h0, %h2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "0")
8834    (set_attr "mode" "QI")])
8836 (define_split
8837   [(set (match_operand 0 "register_operand" "")
8838         (ior (match_operand 1 "register_operand" "")
8839              (match_operand 2 "const_int_operand" "")))
8840    (clobber (reg:CC FLAGS_REG))]
8841    "reload_completed
8842     && QI_REG_P (operands[0])
8843     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844     && !(INTVAL (operands[2]) & ~(255 << 8))
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847                    (ior:SI (zero_extract:SI (match_dup 1)
8848                                             (const_int 8) (const_int 8))
8849                            (match_dup 2)))
8850               (clobber (reg:CC FLAGS_REG))])]
8851   "operands[0] = gen_lowpart (SImode, operands[0]);
8852    operands[1] = gen_lowpart (SImode, operands[1]);
8853    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8855 ;; Since OR can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is set.
8857 (define_split
8858   [(set (match_operand 0 "register_operand" "")
8859         (ior (match_operand 1 "general_operand" "")
8860              (match_operand 2 "const_int_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862    "reload_completed
8863     && ANY_QI_REG_P (operands[0])
8864     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865     && !(INTVAL (operands[2]) & ~255)
8866     && (INTVAL (operands[2]) & 128)
8867     && GET_MODE (operands[0]) != QImode"
8868   [(parallel [(set (strict_low_part (match_dup 0))
8869                    (ior:QI (match_dup 1)
8870                            (match_dup 2)))
8871               (clobber (reg:CC FLAGS_REG))])]
8872   "operands[0] = gen_lowpart (QImode, operands[0]);
8873    operands[1] = gen_lowpart (QImode, operands[1]);
8874    operands[2] = gen_lowpart (QImode, operands[2]);")
8876 ;; Logical XOR instructions
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8881 (define_expand "xordi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8889 (define_insn "*xordi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (XOR, DImode, operands)"
8896   "@
8897    xor{q}\t{%2, %0|%0, %2}
8898    xor{q}\t{%2, %0|%0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "mode" "DI,DI")])
8902 (define_insn "*xordi_2_rex64"
8903   [(set (reg FLAGS_REG)
8904         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8905                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8906                  (const_int 0)))
8907    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8908         (xor:DI (match_dup 1) (match_dup 2)))]
8909   "TARGET_64BIT
8910    && ix86_match_ccmode (insn, CCNOmode)
8911    && ix86_binary_operator_ok (XOR, DImode, operands)"
8912   "@
8913    xor{q}\t{%2, %0|%0, %2}
8914    xor{q}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "DI,DI")])
8918 (define_insn "*xordi_3_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8921                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8922                  (const_int 0)))
8923    (clobber (match_scratch:DI 0 "=r"))]
8924   "TARGET_64BIT
8925    && ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_binary_operator_ok (XOR, DImode, operands)"
8927   "xor{q}\t{%2, %0|%0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "DI")])
8931 (define_expand "xorsi3"
8932   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8933         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8934                 (match_operand:SI 2 "general_operand" "")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   ""
8937   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8939 (define_insn "*xorsi_1"
8940   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8941         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942                 (match_operand:SI 2 "general_operand" "ri,rm")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "ix86_binary_operator_ok (XOR, SImode, operands)"
8945   "xor{l}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "SI")])
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 ;; Add speccase for immediates
8951 (define_insn "*xorsi_1_zext"
8952   [(set (match_operand:DI 0 "register_operand" "=r")
8953         (zero_extend:DI
8954           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955                   (match_operand:SI 2 "general_operand" "rim"))))
8956    (clobber (reg:CC FLAGS_REG))]
8957   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8958   "xor{l}\t{%2, %k0|%k0, %2}"
8959   [(set_attr "type" "alu")
8960    (set_attr "mode" "SI")])
8962 (define_insn "*xorsi_1_zext_imm"
8963   [(set (match_operand:DI 0 "register_operand" "=r")
8964         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8965                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8966    (clobber (reg:CC FLAGS_REG))]
8967   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8968   "xor{l}\t{%2, %k0|%k0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "SI")])
8972 (define_insn "*xorsi_2"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8975                          (match_operand:SI 2 "general_operand" "rim,ri"))
8976                  (const_int 0)))
8977    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8978         (xor:SI (match_dup 1) (match_dup 2)))]
8979   "ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, SImode, operands)"
8981   "xor{l}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "SI")])
8985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8986 ;; ??? Special case for immediate operand is missing - it is tricky.
8987 (define_insn "*xorsi_2_zext"
8988   [(set (reg FLAGS_REG)
8989         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990                          (match_operand:SI 2 "general_operand" "rim"))
8991                  (const_int 0)))
8992    (set (match_operand:DI 0 "register_operand" "=r")
8993         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8994   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8995    && ix86_binary_operator_ok (XOR, SImode, operands)"
8996   "xor{l}\t{%2, %k0|%k0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "mode" "SI")])
9000 (define_insn "*xorsi_2_zext_imm"
9001   [(set (reg FLAGS_REG)
9002         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9003                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9004                  (const_int 0)))
9005    (set (match_operand:DI 0 "register_operand" "=r")
9006         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9007   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9008    && ix86_binary_operator_ok (XOR, SImode, operands)"
9009   "xor{l}\t{%2, %k0|%k0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "SI")])
9013 (define_insn "*xorsi_3"
9014   [(set (reg FLAGS_REG)
9015         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9016                          (match_operand:SI 2 "general_operand" "rim"))
9017                  (const_int 0)))
9018    (clobber (match_scratch:SI 0 "=r"))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9021   "xor{l}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "SI")])
9025 (define_expand "xorhi3"
9026   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9027         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9028                 (match_operand:HI 2 "general_operand" "")))
9029    (clobber (reg:CC FLAGS_REG))]
9030   "TARGET_HIMODE_MATH"
9031   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9033 (define_insn "*xorhi_1"
9034   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9035         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9036                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "ix86_binary_operator_ok (XOR, HImode, operands)"
9039   "xor{w}\t{%2, %0|%0, %2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "mode" "HI")])
9043 (define_insn "*xorhi_2"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9046                          (match_operand:HI 2 "general_operand" "rim,ri"))
9047                  (const_int 0)))
9048    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9049         (xor:HI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, HImode, operands)"
9052   "xor{w}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "HI")])
9056 (define_insn "*xorhi_3"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9059                          (match_operand:HI 2 "general_operand" "rim"))
9060                  (const_int 0)))
9061    (clobber (match_scratch:HI 0 "=r"))]
9062   "ix86_match_ccmode (insn, CCNOmode)
9063    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9064   "xor{w}\t{%2, %0|%0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "HI")])
9068 (define_expand "xorqi3"
9069   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9070         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9071                 (match_operand:QI 2 "general_operand" "")))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "TARGET_QIMODE_MATH"
9074   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9076 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9077 (define_insn "*xorqi_1"
9078   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9079         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9080                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9081    (clobber (reg:CC FLAGS_REG))]
9082   "ix86_binary_operator_ok (XOR, QImode, operands)"
9083   "@
9084    xor{b}\t{%2, %0|%0, %2}
9085    xor{b}\t{%2, %0|%0, %2}
9086    xor{l}\t{%k2, %k0|%k0, %k2}"
9087   [(set_attr "type" "alu")
9088    (set_attr "mode" "QI,QI,SI")])
9090 (define_insn "*xorqi_1_slp"
9091   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9092         (xor:QI (match_dup 0)
9093                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9096    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9097   "xor{b}\t{%1, %0|%0, %1}"
9098   [(set_attr "type" "alu1")
9099    (set_attr "mode" "QI")])
9101 (define_insn "xorqi_ext_0"
9102   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9103                          (const_int 8)
9104                          (const_int 8))
9105         (xor:SI 
9106           (zero_extract:SI
9107             (match_operand 1 "ext_register_operand" "0")
9108             (const_int 8)
9109             (const_int 8))
9110           (match_operand 2 "const_int_operand" "n")))
9111    (clobber (reg:CC FLAGS_REG))]
9112   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113   "xor{b}\t{%2, %h0|%h0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "length_immediate" "1")
9116    (set_attr "mode" "QI")])
9118 (define_insn "*xorqi_ext_1"
9119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120                          (const_int 8)
9121                          (const_int 8))
9122         (xor:SI 
9123           (zero_extract:SI
9124             (match_operand 1 "ext_register_operand" "0")
9125             (const_int 8)
9126             (const_int 8))
9127           (zero_extend:SI
9128             (match_operand:QI 2 "general_operand" "Qm"))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "!TARGET_64BIT
9131    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9132   "xor{b}\t{%2, %h0|%h0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "length_immediate" "0")
9135    (set_attr "mode" "QI")])
9137 (define_insn "*xorqi_ext_1_rex64"
9138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9139                          (const_int 8)
9140                          (const_int 8))
9141         (xor:SI 
9142           (zero_extract:SI
9143             (match_operand 1 "ext_register_operand" "0")
9144             (const_int 8)
9145             (const_int 8))
9146           (zero_extend:SI
9147             (match_operand 2 "ext_register_operand" "Q"))))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "TARGET_64BIT
9150    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151   "xor{b}\t{%2, %h0|%h0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "length_immediate" "0")
9154    (set_attr "mode" "QI")])
9156 (define_insn "*xorqi_ext_2"
9157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158                          (const_int 8)
9159                          (const_int 8))
9160         (xor:SI 
9161           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9162                            (const_int 8)
9163                            (const_int 8))
9164           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9165                            (const_int 8)
9166                            (const_int 8))))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%h2, %h0|%h0, %h2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "0")
9172    (set_attr "mode" "QI")])
9174 (define_insn "*xorqi_cc_1"
9175   [(set (reg FLAGS_REG)
9176         (compare
9177           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9178                   (match_operand:QI 2 "general_operand" "qim,qi"))
9179           (const_int 0)))
9180    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9181         (xor:QI (match_dup 1) (match_dup 2)))]
9182   "ix86_match_ccmode (insn, CCNOmode)
9183    && ix86_binary_operator_ok (XOR, QImode, operands)"
9184   "xor{b}\t{%2, %0|%0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "QI")])
9188 (define_insn "*xorqi_2_slp"
9189   [(set (reg FLAGS_REG)
9190         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9191                          (match_operand:QI 1 "general_operand" "qim,qi"))
9192                  (const_int 0)))
9193    (set (strict_low_part (match_dup 0))
9194         (xor:QI (match_dup 0) (match_dup 1)))]
9195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196    && ix86_match_ccmode (insn, CCNOmode)
9197    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9198   "xor{b}\t{%1, %0|%0, %1}"
9199   [(set_attr "type" "alu1")
9200    (set_attr "mode" "QI")])
9202 (define_insn "*xorqi_cc_2"
9203   [(set (reg FLAGS_REG)
9204         (compare
9205           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9206                   (match_operand:QI 2 "general_operand" "qim"))
9207           (const_int 0)))
9208    (clobber (match_scratch:QI 0 "=q"))]
9209   "ix86_match_ccmode (insn, CCNOmode)
9210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9211   "xor{b}\t{%2, %0|%0, %2}"
9212   [(set_attr "type" "alu")
9213    (set_attr "mode" "QI")])
9215 (define_insn "*xorqi_cc_ext_1"
9216   [(set (reg FLAGS_REG)
9217         (compare
9218           (xor:SI
9219             (zero_extract:SI
9220               (match_operand 1 "ext_register_operand" "0")
9221               (const_int 8)
9222               (const_int 8))
9223             (match_operand:QI 2 "general_operand" "qmn"))
9224           (const_int 0)))
9225    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9226                          (const_int 8)
9227                          (const_int 8))
9228         (xor:SI 
9229           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9230           (match_dup 2)))]
9231   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9232   "xor{b}\t{%2, %h0|%h0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "mode" "QI")])
9236 (define_insn "*xorqi_cc_ext_1_rex64"
9237   [(set (reg FLAGS_REG)
9238         (compare
9239           (xor:SI
9240             (zero_extract:SI
9241               (match_operand 1 "ext_register_operand" "0")
9242               (const_int 8)
9243               (const_int 8))
9244             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9245           (const_int 0)))
9246    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9247                          (const_int 8)
9248                          (const_int 8))
9249         (xor:SI 
9250           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9251           (match_dup 2)))]
9252   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9253   "xor{b}\t{%2, %h0|%h0, %2}"
9254   [(set_attr "type" "alu")
9255    (set_attr "mode" "QI")])
9257 (define_expand "xorqi_cc_ext_1"
9258   [(parallel [
9259      (set (reg:CCNO FLAGS_REG)
9260           (compare:CCNO
9261             (xor:SI
9262               (zero_extract:SI
9263                 (match_operand 1 "ext_register_operand" "")
9264                 (const_int 8)
9265                 (const_int 8))
9266               (match_operand:QI 2 "general_operand" ""))
9267             (const_int 0)))
9268      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9269                            (const_int 8)
9270                            (const_int 8))
9271           (xor:SI 
9272             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9273             (match_dup 2)))])]
9274   ""
9275   "")
9277 (define_split
9278   [(set (match_operand 0 "register_operand" "")
9279         (xor (match_operand 1 "register_operand" "")
9280              (match_operand 2 "const_int_operand" "")))
9281    (clobber (reg:CC FLAGS_REG))]
9282    "reload_completed
9283     && QI_REG_P (operands[0])
9284     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285     && !(INTVAL (operands[2]) & ~(255 << 8))
9286     && GET_MODE (operands[0]) != QImode"
9287   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288                    (xor:SI (zero_extract:SI (match_dup 1)
9289                                             (const_int 8) (const_int 8))
9290                            (match_dup 2)))
9291               (clobber (reg:CC FLAGS_REG))])]
9292   "operands[0] = gen_lowpart (SImode, operands[0]);
9293    operands[1] = gen_lowpart (SImode, operands[1]);
9294    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296 ;; Since XOR can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is set.
9298 (define_split
9299   [(set (match_operand 0 "register_operand" "")
9300         (xor (match_operand 1 "general_operand" "")
9301              (match_operand 2 "const_int_operand" "")))
9302    (clobber (reg:CC FLAGS_REG))]
9303    "reload_completed
9304     && ANY_QI_REG_P (operands[0])
9305     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306     && !(INTVAL (operands[2]) & ~255)
9307     && (INTVAL (operands[2]) & 128)
9308     && GET_MODE (operands[0]) != QImode"
9309   [(parallel [(set (strict_low_part (match_dup 0))
9310                    (xor:QI (match_dup 1)
9311                            (match_dup 2)))
9312               (clobber (reg:CC FLAGS_REG))])]
9313   "operands[0] = gen_lowpart (QImode, operands[0]);
9314    operands[1] = gen_lowpart (QImode, operands[1]);
9315    operands[2] = gen_lowpart (QImode, operands[2]);")
9317 ;; Negation instructions
9319 (define_expand "negti2"
9320   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9321                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9322               (clobber (reg:CC FLAGS_REG))])]
9323   "TARGET_64BIT"
9324   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9326 (define_insn "*negti2_1"
9327   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9328         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT
9331    && ix86_unary_operator_ok (NEG, TImode, operands)"
9332   "#")
9334 (define_split
9335   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9336         (neg:TI (match_operand:TI 1 "general_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "TARGET_64BIT && reload_completed"
9339   [(parallel
9340     [(set (reg:CCZ FLAGS_REG)
9341           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9342      (set (match_dup 0) (neg:DI (match_dup 2)))])
9343    (parallel
9344     [(set (match_dup 1)
9345           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9346                             (match_dup 3))
9347                    (const_int 0)))
9348      (clobber (reg:CC FLAGS_REG))])
9349    (parallel
9350     [(set (match_dup 1)
9351           (neg:DI (match_dup 1)))
9352      (clobber (reg:CC FLAGS_REG))])]
9353   "split_ti (operands+1, 1, operands+2, operands+3);
9354    split_ti (operands+0, 1, operands+0, operands+1);")
9356 (define_expand "negdi2"
9357   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9359               (clobber (reg:CC FLAGS_REG))])]
9360   ""
9361   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9363 (define_insn "*negdi2_1"
9364   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9365         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "!TARGET_64BIT
9368    && ix86_unary_operator_ok (NEG, DImode, operands)"
9369   "#")
9371 (define_split
9372   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9373         (neg:DI (match_operand:DI 1 "general_operand" "")))
9374    (clobber (reg:CC FLAGS_REG))]
9375   "!TARGET_64BIT && reload_completed"
9376   [(parallel
9377     [(set (reg:CCZ FLAGS_REG)
9378           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9379      (set (match_dup 0) (neg:SI (match_dup 2)))])
9380    (parallel
9381     [(set (match_dup 1)
9382           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9383                             (match_dup 3))
9384                    (const_int 0)))
9385      (clobber (reg:CC FLAGS_REG))])
9386    (parallel
9387     [(set (match_dup 1)
9388           (neg:SI (match_dup 1)))
9389      (clobber (reg:CC FLAGS_REG))])]
9390   "split_di (operands+1, 1, operands+2, operands+3);
9391    split_di (operands+0, 1, operands+0, operands+1);")
9393 (define_insn "*negdi2_1_rex64"
9394   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9395         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9396    (clobber (reg:CC FLAGS_REG))]
9397   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9398   "neg{q}\t%0"
9399   [(set_attr "type" "negnot")
9400    (set_attr "mode" "DI")])
9402 ;; The problem with neg is that it does not perform (compare x 0),
9403 ;; it really performs (compare 0 x), which leaves us with the zero
9404 ;; flag being the only useful item.
9406 (define_insn "*negdi2_cmpz_rex64"
9407   [(set (reg:CCZ FLAGS_REG)
9408         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9409                      (const_int 0)))
9410    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411         (neg:DI (match_dup 1)))]
9412   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9413   "neg{q}\t%0"
9414   [(set_attr "type" "negnot")
9415    (set_attr "mode" "DI")])
9418 (define_expand "negsi2"
9419   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9420                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9421               (clobber (reg:CC FLAGS_REG))])]
9422   ""
9423   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9425 (define_insn "*negsi2_1"
9426   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "ix86_unary_operator_ok (NEG, SImode, operands)"
9430   "neg{l}\t%0"
9431   [(set_attr "type" "negnot")
9432    (set_attr "mode" "SI")])
9434 ;; Combine is quite creative about this pattern.
9435 (define_insn "*negsi2_1_zext"
9436   [(set (match_operand:DI 0 "register_operand" "=r")
9437         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9438                                         (const_int 32)))
9439                      (const_int 32)))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9442   "neg{l}\t%k0"
9443   [(set_attr "type" "negnot")
9444    (set_attr "mode" "SI")])
9446 ;; The problem with neg is that it does not perform (compare x 0),
9447 ;; it really performs (compare 0 x), which leaves us with the zero
9448 ;; flag being the only useful item.
9450 (define_insn "*negsi2_cmpz"
9451   [(set (reg:CCZ FLAGS_REG)
9452         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9453                      (const_int 0)))
9454    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9455         (neg:SI (match_dup 1)))]
9456   "ix86_unary_operator_ok (NEG, SImode, operands)"
9457   "neg{l}\t%0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "SI")])
9461 (define_insn "*negsi2_cmpz_zext"
9462   [(set (reg:CCZ FLAGS_REG)
9463         (compare:CCZ (lshiftrt:DI
9464                        (neg:DI (ashift:DI
9465                                  (match_operand:DI 1 "register_operand" "0")
9466                                  (const_int 32)))
9467                        (const_int 32))
9468                      (const_int 0)))
9469    (set (match_operand:DI 0 "register_operand" "=r")
9470         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9471                                         (const_int 32)))
9472                      (const_int 32)))]
9473   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9474   "neg{l}\t%k0"
9475   [(set_attr "type" "negnot")
9476    (set_attr "mode" "SI")])
9478 (define_expand "neghi2"
9479   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9480                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9481               (clobber (reg:CC FLAGS_REG))])]
9482   "TARGET_HIMODE_MATH"
9483   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9485 (define_insn "*neghi2_1"
9486   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9487         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "ix86_unary_operator_ok (NEG, HImode, operands)"
9490   "neg{w}\t%0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "HI")])
9494 (define_insn "*neghi2_cmpz"
9495   [(set (reg:CCZ FLAGS_REG)
9496         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9497                      (const_int 0)))
9498    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9499         (neg:HI (match_dup 1)))]
9500   "ix86_unary_operator_ok (NEG, HImode, operands)"
9501   "neg{w}\t%0"
9502   [(set_attr "type" "negnot")
9503    (set_attr "mode" "HI")])
9505 (define_expand "negqi2"
9506   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9508               (clobber (reg:CC FLAGS_REG))])]
9509   "TARGET_QIMODE_MATH"
9510   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9512 (define_insn "*negqi2_1"
9513   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9514         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9515    (clobber (reg:CC FLAGS_REG))]
9516   "ix86_unary_operator_ok (NEG, QImode, operands)"
9517   "neg{b}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "QI")])
9521 (define_insn "*negqi2_cmpz"
9522   [(set (reg:CCZ FLAGS_REG)
9523         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9524                      (const_int 0)))
9525    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9526         (neg:QI (match_dup 1)))]
9527   "ix86_unary_operator_ok (NEG, QImode, operands)"
9528   "neg{b}\t%0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "QI")])
9532 ;; Changing of sign for FP values is doable using integer unit too.
9534 (define_expand "negsf2"
9535   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9536         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9537   "TARGET_80387 || TARGET_SSE_MATH"
9538   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9540 (define_expand "abssf2"
9541   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9542         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9543   "TARGET_80387 || TARGET_SSE_MATH"
9544   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9546 (define_insn "*absnegsf2_mixed"
9547   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9548         (match_operator:SF 3 "absneg_operator"
9549           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9550    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9553    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9554   "#")
9556 (define_insn "*absnegsf2_sse"
9557   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9558         (match_operator:SF 3 "absneg_operator"
9559           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9560    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9561    (clobber (reg:CC FLAGS_REG))]
9562   "TARGET_SSE_MATH
9563    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9564   "#")
9566 (define_insn "*absnegsf2_i387"
9567   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9568         (match_operator:SF 3 "absneg_operator"
9569           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9570    (use (match_operand 2 "" ""))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "TARGET_80387 && !TARGET_SSE_MATH
9573    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9574   "#")
9576 (define_expand "copysignsf3"
9577   [(match_operand:SF 0 "register_operand" "")
9578    (match_operand:SF 1 "nonmemory_operand" "")
9579    (match_operand:SF 2 "register_operand" "")]
9580   "TARGET_SSE_MATH"
9582   ix86_expand_copysign (operands);
9583   DONE;
9586 (define_insn_and_split "copysignsf3_const"
9587   [(set (match_operand:SF 0 "register_operand"          "=x")
9588         (unspec:SF
9589           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9590            (match_operand:SF 2 "register_operand"       "0")
9591            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9592           UNSPEC_COPYSIGN))]
9593   "TARGET_SSE_MATH"
9594   "#"
9595   "&& reload_completed"
9596   [(const_int 0)]
9598   ix86_split_copysign_const (operands);
9599   DONE;
9602 (define_insn "copysignsf3_var"
9603   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9604         (unspec:SF
9605           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9606            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9607            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9608            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9609           UNSPEC_COPYSIGN))
9610    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9611   "TARGET_SSE_MATH"
9612   "#")
9614 (define_split
9615   [(set (match_operand:SF 0 "register_operand" "")
9616         (unspec:SF
9617           [(match_operand:SF 2 "register_operand" "")
9618            (match_operand:SF 3 "register_operand" "")
9619            (match_operand:V4SF 4 "" "")
9620            (match_operand:V4SF 5 "" "")]
9621           UNSPEC_COPYSIGN))
9622    (clobber (match_scratch:V4SF 1 ""))]
9623   "TARGET_SSE_MATH && reload_completed"
9624   [(const_int 0)]
9626   ix86_split_copysign_var (operands);
9627   DONE;
9630 (define_expand "negdf2"
9631   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9632         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9633   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9634   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9636 (define_expand "absdf2"
9637   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9638         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9639   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9640   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9642 (define_insn "*absnegdf2_mixed"
9643   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9644         (match_operator:DF 3 "absneg_operator"
9645           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9646    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9647    (clobber (reg:CC FLAGS_REG))]
9648   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9649    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9650   "#")
9652 (define_insn "*absnegdf2_sse"
9653   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9654         (match_operator:DF 3 "absneg_operator"
9655           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9656    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "TARGET_SSE2 && TARGET_SSE_MATH
9659    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9660   "#")
9662 (define_insn "*absnegdf2_i387"
9663   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9664         (match_operator:DF 3 "absneg_operator"
9665           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9666    (use (match_operand 2 "" ""))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9669    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9670   "#")
9672 (define_expand "copysigndf3"
9673   [(match_operand:DF 0 "register_operand" "")
9674    (match_operand:DF 1 "nonmemory_operand" "")
9675    (match_operand:DF 2 "register_operand" "")]
9676   "TARGET_SSE2 && TARGET_SSE_MATH"
9678   ix86_expand_copysign (operands);
9679   DONE;
9682 (define_insn_and_split "copysigndf3_const"
9683   [(set (match_operand:DF 0 "register_operand"          "=x")
9684         (unspec:DF
9685           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9686            (match_operand:DF 2 "register_operand"       "0")
9687            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9688           UNSPEC_COPYSIGN))]
9689   "TARGET_SSE2 && TARGET_SSE_MATH"
9690   "#"
9691   "&& reload_completed"
9692   [(const_int 0)]
9694   ix86_split_copysign_const (operands);
9695   DONE;
9698 (define_insn "copysigndf3_var"
9699   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9700         (unspec:DF
9701           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9702            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9703            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9704            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9705           UNSPEC_COPYSIGN))
9706    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9707   "TARGET_SSE2 && TARGET_SSE_MATH"
9708   "#")
9710 (define_split
9711   [(set (match_operand:DF 0 "register_operand" "")
9712         (unspec:DF
9713           [(match_operand:DF 2 "register_operand" "")
9714            (match_operand:DF 3 "register_operand" "")
9715            (match_operand:V2DF 4 "" "")
9716            (match_operand:V2DF 5 "" "")]
9717           UNSPEC_COPYSIGN))
9718    (clobber (match_scratch:V2DF 1 ""))]
9719   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9720   [(const_int 0)]
9722   ix86_split_copysign_var (operands);
9723   DONE;
9726 (define_expand "negxf2"
9727   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9728         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9729   "TARGET_80387"
9730   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9732 (define_expand "absxf2"
9733   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9734         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9735   "TARGET_80387"
9736   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9738 (define_insn "*absnegxf2_i387"
9739   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9740         (match_operator:XF 3 "absneg_operator"
9741           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9742    (use (match_operand 2 "" ""))
9743    (clobber (reg:CC FLAGS_REG))]
9744   "TARGET_80387
9745    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9746   "#")
9748 ;; Splitters for fp abs and neg.
9750 (define_split
9751   [(set (match_operand 0 "fp_register_operand" "")
9752         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9753    (use (match_operand 2 "" ""))
9754    (clobber (reg:CC FLAGS_REG))]
9755   "reload_completed"
9756   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9758 (define_split
9759   [(set (match_operand 0 "register_operand" "")
9760         (match_operator 3 "absneg_operator"
9761           [(match_operand 1 "register_operand" "")]))
9762    (use (match_operand 2 "nonimmediate_operand" ""))
9763    (clobber (reg:CC FLAGS_REG))]
9764   "reload_completed && SSE_REG_P (operands[0])"
9765   [(set (match_dup 0) (match_dup 3))]
9767   enum machine_mode mode = GET_MODE (operands[0]);
9768   enum machine_mode vmode = GET_MODE (operands[2]);
9769   rtx tmp;
9770   
9771   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9772   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9773   if (operands_match_p (operands[0], operands[2]))
9774     {
9775       tmp = operands[1];
9776       operands[1] = operands[2];
9777       operands[2] = tmp;
9778     }
9779   if (GET_CODE (operands[3]) == ABS)
9780     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9781   else
9782     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9783   operands[3] = tmp;
9786 (define_split
9787   [(set (match_operand:SF 0 "register_operand" "")
9788         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9789    (use (match_operand:V4SF 2 "" ""))
9790    (clobber (reg:CC FLAGS_REG))]
9791   "reload_completed"
9792   [(parallel [(set (match_dup 0) (match_dup 1))
9793               (clobber (reg:CC FLAGS_REG))])]
9795   rtx tmp;
9796   operands[0] = gen_lowpart (SImode, operands[0]);
9797   if (GET_CODE (operands[1]) == ABS)
9798     {
9799       tmp = gen_int_mode (0x7fffffff, SImode);
9800       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9801     }
9802   else
9803     {
9804       tmp = gen_int_mode (0x80000000, SImode);
9805       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9806     }
9807   operands[1] = tmp;
9810 (define_split
9811   [(set (match_operand:DF 0 "register_operand" "")
9812         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9813    (use (match_operand 2 "" ""))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "reload_completed"
9816   [(parallel [(set (match_dup 0) (match_dup 1))
9817               (clobber (reg:CC FLAGS_REG))])]
9819   rtx tmp;
9820   if (TARGET_64BIT)
9821     {
9822       tmp = gen_lowpart (DImode, operands[0]);
9823       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9824       operands[0] = tmp;
9826       if (GET_CODE (operands[1]) == ABS)
9827         tmp = const0_rtx;
9828       else
9829         tmp = gen_rtx_NOT (DImode, tmp);
9830     }
9831   else
9832     {
9833       operands[0] = gen_highpart (SImode, operands[0]);
9834       if (GET_CODE (operands[1]) == ABS)
9835         {
9836           tmp = gen_int_mode (0x7fffffff, SImode);
9837           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9838         }
9839       else
9840         {
9841           tmp = gen_int_mode (0x80000000, SImode);
9842           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9843         }
9844     }
9845   operands[1] = tmp;
9848 (define_split
9849   [(set (match_operand:XF 0 "register_operand" "")
9850         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9851    (use (match_operand 2 "" ""))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "reload_completed"
9854   [(parallel [(set (match_dup 0) (match_dup 1))
9855               (clobber (reg:CC FLAGS_REG))])]
9857   rtx tmp;
9858   operands[0] = gen_rtx_REG (SImode,
9859                              true_regnum (operands[0])
9860                              + (TARGET_64BIT ? 1 : 2));
9861   if (GET_CODE (operands[1]) == ABS)
9862     {
9863       tmp = GEN_INT (0x7fff);
9864       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9865     }
9866   else
9867     {
9868       tmp = GEN_INT (0x8000);
9869       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9870     }
9871   operands[1] = tmp;
9874 (define_split
9875   [(set (match_operand 0 "memory_operand" "")
9876         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9877    (use (match_operand 2 "" ""))
9878    (clobber (reg:CC FLAGS_REG))]
9879   "reload_completed"
9880   [(parallel [(set (match_dup 0) (match_dup 1))
9881               (clobber (reg:CC FLAGS_REG))])]
9883   enum machine_mode mode = GET_MODE (operands[0]);
9884   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9885   rtx tmp;
9887   operands[0] = adjust_address (operands[0], QImode, size - 1);
9888   if (GET_CODE (operands[1]) == ABS)
9889     {
9890       tmp = gen_int_mode (0x7f, QImode);
9891       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9892     }
9893   else
9894     {
9895       tmp = gen_int_mode (0x80, QImode);
9896       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9897     }
9898   operands[1] = tmp;
9901 ;; Conditionalize these after reload. If they match before reload, we 
9902 ;; lose the clobber and ability to use integer instructions.
9904 (define_insn "*negsf2_1"
9905   [(set (match_operand:SF 0 "register_operand" "=f")
9906         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9907   "TARGET_80387 && reload_completed"
9908   "fchs"
9909   [(set_attr "type" "fsgn")
9910    (set_attr "mode" "SF")])
9912 (define_insn "*negdf2_1"
9913   [(set (match_operand:DF 0 "register_operand" "=f")
9914         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9915   "TARGET_80387 && reload_completed"
9916   "fchs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "DF")])
9920 (define_insn "*negxf2_1"
9921   [(set (match_operand:XF 0 "register_operand" "=f")
9922         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9923   "TARGET_80387 && reload_completed"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "XF")])
9928 (define_insn "*abssf2_1"
9929   [(set (match_operand:SF 0 "register_operand" "=f")
9930         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9931   "TARGET_80387 && reload_completed"
9932   "fabs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "SF")])
9936 (define_insn "*absdf2_1"
9937   [(set (match_operand:DF 0 "register_operand" "=f")
9938         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9939   "TARGET_80387 && reload_completed"
9940   "fabs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "DF")])
9944 (define_insn "*absxf2_1"
9945   [(set (match_operand:XF 0 "register_operand" "=f")
9946         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9947   "TARGET_80387 && reload_completed"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "DF")])
9952 (define_insn "*negextendsfdf2"
9953   [(set (match_operand:DF 0 "register_operand" "=f")
9954         (neg:DF (float_extend:DF
9955                   (match_operand:SF 1 "register_operand" "0"))))]
9956   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9957   "fchs"
9958   [(set_attr "type" "fsgn")
9959    (set_attr "mode" "DF")])
9961 (define_insn "*negextenddfxf2"
9962   [(set (match_operand:XF 0 "register_operand" "=f")
9963         (neg:XF (float_extend:XF
9964                   (match_operand:DF 1 "register_operand" "0"))))]
9965   "TARGET_80387"
9966   "fchs"
9967   [(set_attr "type" "fsgn")
9968    (set_attr "mode" "XF")])
9970 (define_insn "*negextendsfxf2"
9971   [(set (match_operand:XF 0 "register_operand" "=f")
9972         (neg:XF (float_extend:XF
9973                   (match_operand:SF 1 "register_operand" "0"))))]
9974   "TARGET_80387"
9975   "fchs"
9976   [(set_attr "type" "fsgn")
9977    (set_attr "mode" "XF")])
9979 (define_insn "*absextendsfdf2"
9980   [(set (match_operand:DF 0 "register_operand" "=f")
9981         (abs:DF (float_extend:DF
9982                   (match_operand:SF 1 "register_operand" "0"))))]
9983   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9984   "fabs"
9985   [(set_attr "type" "fsgn")
9986    (set_attr "mode" "DF")])
9988 (define_insn "*absextenddfxf2"
9989   [(set (match_operand:XF 0 "register_operand" "=f")
9990         (abs:XF (float_extend:XF
9991           (match_operand:DF 1 "register_operand" "0"))))]
9992   "TARGET_80387"
9993   "fabs"
9994   [(set_attr "type" "fsgn")
9995    (set_attr "mode" "XF")])
9997 (define_insn "*absextendsfxf2"
9998   [(set (match_operand:XF 0 "register_operand" "=f")
9999         (abs:XF (float_extend:XF
10000           (match_operand:SF 1 "register_operand" "0"))))]
10001   "TARGET_80387"
10002   "fabs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "XF")])
10006 ;; One complement instructions
10008 (define_expand "one_cmpldi2"
10009   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10010         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10011   "TARGET_64BIT"
10012   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10014 (define_insn "*one_cmpldi2_1_rex64"
10015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10016         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10017   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10018   "not{q}\t%0"
10019   [(set_attr "type" "negnot")
10020    (set_attr "mode" "DI")])
10022 (define_insn "*one_cmpldi2_2_rex64"
10023   [(set (reg FLAGS_REG)
10024         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10025                  (const_int 0)))
10026    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10027         (not:DI (match_dup 1)))]
10028   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10029    && ix86_unary_operator_ok (NOT, DImode, operands)"
10030   "#"
10031   [(set_attr "type" "alu1")
10032    (set_attr "mode" "DI")])
10034 (define_split
10035   [(set (match_operand 0 "flags_reg_operand" "")
10036         (match_operator 2 "compare_operator"
10037           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10038            (const_int 0)]))
10039    (set (match_operand:DI 1 "nonimmediate_operand" "")
10040         (not:DI (match_dup 3)))]
10041   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042   [(parallel [(set (match_dup 0)
10043                    (match_op_dup 2
10044                      [(xor:DI (match_dup 3) (const_int -1))
10045                       (const_int 0)]))
10046               (set (match_dup 1)
10047                    (xor:DI (match_dup 3) (const_int -1)))])]
10048   "")
10050 (define_expand "one_cmplsi2"
10051   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10052         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10053   ""
10054   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10056 (define_insn "*one_cmplsi2_1"
10057   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10058         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10059   "ix86_unary_operator_ok (NOT, SImode, operands)"
10060   "not{l}\t%0"
10061   [(set_attr "type" "negnot")
10062    (set_attr "mode" "SI")])
10064 ;; ??? Currently never generated - xor is used instead.
10065 (define_insn "*one_cmplsi2_1_zext"
10066   [(set (match_operand:DI 0 "register_operand" "=r")
10067         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10068   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10069   "not{l}\t%k0"
10070   [(set_attr "type" "negnot")
10071    (set_attr "mode" "SI")])
10073 (define_insn "*one_cmplsi2_2"
10074   [(set (reg FLAGS_REG)
10075         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10076                  (const_int 0)))
10077    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10078         (not:SI (match_dup 1)))]
10079   "ix86_match_ccmode (insn, CCNOmode)
10080    && ix86_unary_operator_ok (NOT, SImode, operands)"
10081   "#"
10082   [(set_attr "type" "alu1")
10083    (set_attr "mode" "SI")])
10085 (define_split
10086   [(set (match_operand 0 "flags_reg_operand" "")
10087         (match_operator 2 "compare_operator"
10088           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10089            (const_int 0)]))
10090    (set (match_operand:SI 1 "nonimmediate_operand" "")
10091         (not:SI (match_dup 3)))]
10092   "ix86_match_ccmode (insn, CCNOmode)"
10093   [(parallel [(set (match_dup 0)
10094                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095                                     (const_int 0)]))
10096               (set (match_dup 1)
10097                    (xor:SI (match_dup 3) (const_int -1)))])]
10098   "")
10100 ;; ??? Currently never generated - xor is used instead.
10101 (define_insn "*one_cmplsi2_2_zext"
10102   [(set (reg FLAGS_REG)
10103         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10104                  (const_int 0)))
10105    (set (match_operand:DI 0 "register_operand" "=r")
10106         (zero_extend:DI (not:SI (match_dup 1))))]
10107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10108    && ix86_unary_operator_ok (NOT, SImode, operands)"
10109   "#"
10110   [(set_attr "type" "alu1")
10111    (set_attr "mode" "SI")])
10113 (define_split
10114   [(set (match_operand 0 "flags_reg_operand" "")
10115         (match_operator 2 "compare_operator"
10116           [(not:SI (match_operand:SI 3 "register_operand" ""))
10117            (const_int 0)]))
10118    (set (match_operand:DI 1 "register_operand" "")
10119         (zero_extend:DI (not:SI (match_dup 3))))]
10120   "ix86_match_ccmode (insn, CCNOmode)"
10121   [(parallel [(set (match_dup 0)
10122                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10123                                     (const_int 0)]))
10124               (set (match_dup 1)
10125                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10126   "")
10128 (define_expand "one_cmplhi2"
10129   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10130         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10131   "TARGET_HIMODE_MATH"
10132   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10134 (define_insn "*one_cmplhi2_1"
10135   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10136         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10137   "ix86_unary_operator_ok (NOT, HImode, operands)"
10138   "not{w}\t%0"
10139   [(set_attr "type" "negnot")
10140    (set_attr "mode" "HI")])
10142 (define_insn "*one_cmplhi2_2"
10143   [(set (reg FLAGS_REG)
10144         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10145                  (const_int 0)))
10146    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10147         (not:HI (match_dup 1)))]
10148   "ix86_match_ccmode (insn, CCNOmode)
10149    && ix86_unary_operator_ok (NEG, HImode, operands)"
10150   "#"
10151   [(set_attr "type" "alu1")
10152    (set_attr "mode" "HI")])
10154 (define_split
10155   [(set (match_operand 0 "flags_reg_operand" "")
10156         (match_operator 2 "compare_operator"
10157           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10158            (const_int 0)]))
10159    (set (match_operand:HI 1 "nonimmediate_operand" "")
10160         (not:HI (match_dup 3)))]
10161   "ix86_match_ccmode (insn, CCNOmode)"
10162   [(parallel [(set (match_dup 0)
10163                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10164                                     (const_int 0)]))
10165               (set (match_dup 1)
10166                    (xor:HI (match_dup 3) (const_int -1)))])]
10167   "")
10169 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10170 (define_expand "one_cmplqi2"
10171   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10172         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10173   "TARGET_QIMODE_MATH"
10174   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10176 (define_insn "*one_cmplqi2_1"
10177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10178         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10179   "ix86_unary_operator_ok (NOT, QImode, operands)"
10180   "@
10181    not{b}\t%0
10182    not{l}\t%k0"
10183   [(set_attr "type" "negnot")
10184    (set_attr "mode" "QI,SI")])
10186 (define_insn "*one_cmplqi2_2"
10187   [(set (reg FLAGS_REG)
10188         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10189                  (const_int 0)))
10190    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10191         (not:QI (match_dup 1)))]
10192   "ix86_match_ccmode (insn, CCNOmode)
10193    && ix86_unary_operator_ok (NOT, QImode, operands)"
10194   "#"
10195   [(set_attr "type" "alu1")
10196    (set_attr "mode" "QI")])
10198 (define_split
10199   [(set (match_operand 0 "flags_reg_operand" "")
10200         (match_operator 2 "compare_operator"
10201           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10202            (const_int 0)]))
10203    (set (match_operand:QI 1 "nonimmediate_operand" "")
10204         (not:QI (match_dup 3)))]
10205   "ix86_match_ccmode (insn, CCNOmode)"
10206   [(parallel [(set (match_dup 0)
10207                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10208                                     (const_int 0)]))
10209               (set (match_dup 1)
10210                    (xor:QI (match_dup 3) (const_int -1)))])]
10211   "")
10213 ;; Arithmetic shift instructions
10215 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10216 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10217 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10218 ;; from the assembler input.
10220 ;; This instruction shifts the target reg/mem as usual, but instead of
10221 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10222 ;; is a left shift double, bits are taken from the high order bits of
10223 ;; reg, else if the insn is a shift right double, bits are taken from the
10224 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10225 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10227 ;; Since sh[lr]d does not change the `reg' operand, that is done
10228 ;; separately, making all shifts emit pairs of shift double and normal
10229 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10230 ;; support a 63 bit shift, each shift where the count is in a reg expands
10231 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10233 ;; If the shift count is a constant, we need never emit more than one
10234 ;; shift pair, instead using moves and sign extension for counts greater
10235 ;; than 31.
10237 (define_expand "ashlti3"
10238   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10239                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10240                               (match_operand:QI 2 "nonmemory_operand" "")))
10241               (clobber (reg:CC FLAGS_REG))])]
10242   "TARGET_64BIT"
10244   if (! immediate_operand (operands[2], QImode))
10245     {
10246       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10247       DONE;
10248     }
10249   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10250   DONE;
10253 (define_insn "ashlti3_1"
10254   [(set (match_operand:TI 0 "register_operand" "=r")
10255         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10256                    (match_operand:QI 2 "register_operand" "c")))
10257    (clobber (match_scratch:DI 3 "=&r"))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "TARGET_64BIT"
10260   "#"
10261   [(set_attr "type" "multi")])
10263 (define_insn "*ashlti3_2"
10264   [(set (match_operand:TI 0 "register_operand" "=r")
10265         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10266                    (match_operand:QI 2 "immediate_operand" "O")))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "TARGET_64BIT"
10269   "#"
10270   [(set_attr "type" "multi")])
10272 (define_split
10273   [(set (match_operand:TI 0 "register_operand" "")
10274         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10275                    (match_operand:QI 2 "register_operand" "")))
10276    (clobber (match_scratch:DI 3 ""))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_64BIT && reload_completed"
10279   [(const_int 0)]
10280   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10282 (define_split
10283   [(set (match_operand:TI 0 "register_operand" "")
10284         (ashift:TI (match_operand:TI 1 "register_operand" "")
10285                    (match_operand:QI 2 "immediate_operand" "")))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "TARGET_64BIT && reload_completed"
10288   [(const_int 0)]
10289   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10291 (define_insn "x86_64_shld"
10292   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10293         (ior:DI (ashift:DI (match_dup 0)
10294                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10295                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10296                   (minus:QI (const_int 64) (match_dup 2)))))
10297    (clobber (reg:CC FLAGS_REG))]
10298   "TARGET_64BIT"
10299   "@
10300    shld{q}\t{%2, %1, %0|%0, %1, %2}
10301    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10302   [(set_attr "type" "ishift")
10303    (set_attr "prefix_0f" "1")
10304    (set_attr "mode" "DI")
10305    (set_attr "athlon_decode" "vector")])
10307 (define_expand "x86_64_shift_adj"
10308   [(set (reg:CCZ FLAGS_REG)
10309         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10310                              (const_int 64))
10311                      (const_int 0)))
10312    (set (match_operand:DI 0 "register_operand" "")
10313         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10314                          (match_operand:DI 1 "register_operand" "")
10315                          (match_dup 0)))
10316    (set (match_dup 1)
10317         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10318                          (match_operand:DI 3 "register_operand" "r")
10319                          (match_dup 1)))]
10320   "TARGET_64BIT"
10321   "")
10323 (define_expand "ashldi3"
10324   [(set (match_operand:DI 0 "shiftdi_operand" "")
10325         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10326                    (match_operand:QI 2 "nonmemory_operand" "")))]
10327   ""
10328   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10330 (define_insn "*ashldi3_1_rex64"
10331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10332         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10333                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10334    (clobber (reg:CC FLAGS_REG))]
10335   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10337   switch (get_attr_type (insn))
10338     {
10339     case TYPE_ALU:
10340       gcc_assert (operands[2] == const1_rtx);
10341       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10342       return "add{q}\t{%0, %0|%0, %0}";
10344     case TYPE_LEA:
10345       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10346       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10347       operands[1] = gen_rtx_MULT (DImode, operands[1],
10348                                   GEN_INT (1 << INTVAL (operands[2])));
10349       return "lea{q}\t{%a1, %0|%0, %a1}";
10351     default:
10352       if (REG_P (operands[2]))
10353         return "sal{q}\t{%b2, %0|%0, %b2}";
10354       else if (operands[2] == const1_rtx
10355                && (TARGET_SHIFT1 || optimize_size))
10356         return "sal{q}\t%0";
10357       else
10358         return "sal{q}\t{%2, %0|%0, %2}";
10359     }
10361   [(set (attr "type")
10362      (cond [(eq_attr "alternative" "1")
10363               (const_string "lea")
10364             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10365                           (const_int 0))
10366                       (match_operand 0 "register_operand" ""))
10367                  (match_operand 2 "const1_operand" ""))
10368               (const_string "alu")
10369            ]
10370            (const_string "ishift")))
10371    (set_attr "mode" "DI")])
10373 ;; Convert lea to the lea pattern to avoid flags dependency.
10374 (define_split
10375   [(set (match_operand:DI 0 "register_operand" "")
10376         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10377                    (match_operand:QI 2 "immediate_operand" "")))
10378    (clobber (reg:CC FLAGS_REG))]
10379   "TARGET_64BIT && reload_completed
10380    && true_regnum (operands[0]) != true_regnum (operands[1])"
10381   [(set (match_dup 0)
10382         (mult:DI (match_dup 1)
10383                  (match_dup 2)))]
10384   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10386 ;; This pattern can't accept a variable shift count, since shifts by
10387 ;; zero don't affect the flags.  We assume that shifts by constant
10388 ;; zero are optimized away.
10389 (define_insn "*ashldi3_cmp_rex64"
10390   [(set (reg FLAGS_REG)
10391         (compare
10392           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10393                      (match_operand:QI 2 "immediate_operand" "e"))
10394           (const_int 0)))
10395    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10396         (ashift:DI (match_dup 1) (match_dup 2)))]
10397   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10398    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10400   switch (get_attr_type (insn))
10401     {
10402     case TYPE_ALU:
10403       gcc_assert (operands[2] == const1_rtx);
10404       return "add{q}\t{%0, %0|%0, %0}";
10406     default:
10407       if (REG_P (operands[2]))
10408         return "sal{q}\t{%b2, %0|%0, %b2}";
10409       else if (operands[2] == const1_rtx
10410                && (TARGET_SHIFT1 || optimize_size))
10411         return "sal{q}\t%0";
10412       else
10413         return "sal{q}\t{%2, %0|%0, %2}";
10414     }
10416   [(set (attr "type")
10417      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10418                           (const_int 0))
10419                       (match_operand 0 "register_operand" ""))
10420                  (match_operand 2 "const1_operand" ""))
10421               (const_string "alu")
10422            ]
10423            (const_string "ishift")))
10424    (set_attr "mode" "DI")])
10426 (define_insn "*ashldi3_1"
10427   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10428         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10429                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10430    (clobber (reg:CC FLAGS_REG))]
10431   "!TARGET_64BIT"
10432   "#"
10433   [(set_attr "type" "multi")])
10435 ;; By default we don't ask for a scratch register, because when DImode
10436 ;; values are manipulated, registers are already at a premium.  But if
10437 ;; we have one handy, we won't turn it away.
10438 (define_peephole2
10439   [(match_scratch:SI 3 "r")
10440    (parallel [(set (match_operand:DI 0 "register_operand" "")
10441                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10442                               (match_operand:QI 2 "nonmemory_operand" "")))
10443               (clobber (reg:CC FLAGS_REG))])
10444    (match_dup 3)]
10445   "!TARGET_64BIT && TARGET_CMOVE"
10446   [(const_int 0)]
10447   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10449 (define_split
10450   [(set (match_operand:DI 0 "register_operand" "")
10451         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10452                    (match_operand:QI 2 "nonmemory_operand" "")))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10455                      ? flow2_completed : reload_completed)"
10456   [(const_int 0)]
10457   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10459 (define_insn "x86_shld_1"
10460   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10461         (ior:SI (ashift:SI (match_dup 0)
10462                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10463                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10464                   (minus:QI (const_int 32) (match_dup 2)))))
10465    (clobber (reg:CC FLAGS_REG))]
10466   ""
10467   "@
10468    shld{l}\t{%2, %1, %0|%0, %1, %2}
10469    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10470   [(set_attr "type" "ishift")
10471    (set_attr "prefix_0f" "1")
10472    (set_attr "mode" "SI")
10473    (set_attr "pent_pair" "np")
10474    (set_attr "athlon_decode" "vector")])
10476 (define_expand "x86_shift_adj_1"
10477   [(set (reg:CCZ FLAGS_REG)
10478         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10479                              (const_int 32))
10480                      (const_int 0)))
10481    (set (match_operand:SI 0 "register_operand" "")
10482         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10483                          (match_operand:SI 1 "register_operand" "")
10484                          (match_dup 0)))
10485    (set (match_dup 1)
10486         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10487                          (match_operand:SI 3 "register_operand" "r")
10488                          (match_dup 1)))]
10489   "TARGET_CMOVE"
10490   "")
10492 (define_expand "x86_shift_adj_2"
10493   [(use (match_operand:SI 0 "register_operand" ""))
10494    (use (match_operand:SI 1 "register_operand" ""))
10495    (use (match_operand:QI 2 "register_operand" ""))]
10496   ""
10498   rtx label = gen_label_rtx ();
10499   rtx tmp;
10501   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10503   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10504   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10505   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10506                               gen_rtx_LABEL_REF (VOIDmode, label),
10507                               pc_rtx);
10508   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10509   JUMP_LABEL (tmp) = label;
10511   emit_move_insn (operands[0], operands[1]);
10512   ix86_expand_clear (operands[1]);
10514   emit_label (label);
10515   LABEL_NUSES (label) = 1;
10517   DONE;
10520 (define_expand "ashlsi3"
10521   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10522         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10523                    (match_operand:QI 2 "nonmemory_operand" "")))
10524    (clobber (reg:CC FLAGS_REG))]
10525   ""
10526   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10528 (define_insn "*ashlsi3_1"
10529   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10530         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10531                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10535   switch (get_attr_type (insn))
10536     {
10537     case TYPE_ALU:
10538       gcc_assert (operands[2] == const1_rtx);
10539       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10540       return "add{l}\t{%0, %0|%0, %0}";
10542     case TYPE_LEA:
10543       return "#";
10545     default:
10546       if (REG_P (operands[2]))
10547         return "sal{l}\t{%b2, %0|%0, %b2}";
10548       else if (operands[2] == const1_rtx
10549                && (TARGET_SHIFT1 || optimize_size))
10550         return "sal{l}\t%0";
10551       else
10552         return "sal{l}\t{%2, %0|%0, %2}";
10553     }
10555   [(set (attr "type")
10556      (cond [(eq_attr "alternative" "1")
10557               (const_string "lea")
10558             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10559                           (const_int 0))
10560                       (match_operand 0 "register_operand" ""))
10561                  (match_operand 2 "const1_operand" ""))
10562               (const_string "alu")
10563            ]
10564            (const_string "ishift")))
10565    (set_attr "mode" "SI")])
10567 ;; Convert lea to the lea pattern to avoid flags dependency.
10568 (define_split
10569   [(set (match_operand 0 "register_operand" "")
10570         (ashift (match_operand 1 "index_register_operand" "")
10571                 (match_operand:QI 2 "const_int_operand" "")))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "reload_completed
10574    && true_regnum (operands[0]) != true_regnum (operands[1])
10575    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10576   [(const_int 0)]
10578   rtx pat;
10579   enum machine_mode mode = GET_MODE (operands[0]);
10581   if (GET_MODE_SIZE (mode) < 4)
10582     operands[0] = gen_lowpart (SImode, operands[0]);
10583   if (mode != Pmode)
10584     operands[1] = gen_lowpart (Pmode, operands[1]);
10585   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10587   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10588   if (Pmode != SImode)
10589     pat = gen_rtx_SUBREG (SImode, pat, 0);
10590   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10591   DONE;
10594 ;; Rare case of shifting RSP is handled by generating move and shift
10595 (define_split
10596   [(set (match_operand 0 "register_operand" "")
10597         (ashift (match_operand 1 "register_operand" "")
10598                 (match_operand:QI 2 "const_int_operand" "")))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "reload_completed
10601    && true_regnum (operands[0]) != true_regnum (operands[1])"
10602   [(const_int 0)]
10604   rtx pat, clob;
10605   emit_move_insn (operands[0], operands[1]);
10606   pat = gen_rtx_SET (VOIDmode, operands[0],
10607                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10608                                      operands[0], operands[2]));
10609   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10610   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10611   DONE;
10614 (define_insn "*ashlsi3_1_zext"
10615   [(set (match_operand:DI 0 "register_operand" "=r,r")
10616         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10617                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10618    (clobber (reg:CC FLAGS_REG))]
10619   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10621   switch (get_attr_type (insn))
10622     {
10623     case TYPE_ALU:
10624       gcc_assert (operands[2] == const1_rtx);
10625       return "add{l}\t{%k0, %k0|%k0, %k0}";
10627     case TYPE_LEA:
10628       return "#";
10630     default:
10631       if (REG_P (operands[2]))
10632         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10633       else if (operands[2] == const1_rtx
10634                && (TARGET_SHIFT1 || optimize_size))
10635         return "sal{l}\t%k0";
10636       else
10637         return "sal{l}\t{%2, %k0|%k0, %2}";
10638     }
10640   [(set (attr "type")
10641      (cond [(eq_attr "alternative" "1")
10642               (const_string "lea")
10643             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10644                      (const_int 0))
10645                  (match_operand 2 "const1_operand" ""))
10646               (const_string "alu")
10647            ]
10648            (const_string "ishift")))
10649    (set_attr "mode" "SI")])
10651 ;; Convert lea to the lea pattern to avoid flags dependency.
10652 (define_split
10653   [(set (match_operand:DI 0 "register_operand" "")
10654         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10655                                 (match_operand:QI 2 "const_int_operand" ""))))
10656    (clobber (reg:CC FLAGS_REG))]
10657   "TARGET_64BIT && reload_completed
10658    && true_regnum (operands[0]) != true_regnum (operands[1])"
10659   [(set (match_dup 0) (zero_extend:DI
10660                         (subreg:SI (mult:SI (match_dup 1)
10661                                             (match_dup 2)) 0)))]
10663   operands[1] = gen_lowpart (Pmode, operands[1]);
10664   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10667 ;; This pattern can't accept a variable shift count, since shifts by
10668 ;; zero don't affect the flags.  We assume that shifts by constant
10669 ;; zero are optimized away.
10670 (define_insn "*ashlsi3_cmp"
10671   [(set (reg FLAGS_REG)
10672         (compare
10673           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10674                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10675           (const_int 0)))
10676    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10677         (ashift:SI (match_dup 1) (match_dup 2)))]
10678   "ix86_match_ccmode (insn, CCGOCmode)
10679    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10681   switch (get_attr_type (insn))
10682     {
10683     case TYPE_ALU:
10684       gcc_assert (operands[2] == const1_rtx);
10685       return "add{l}\t{%0, %0|%0, %0}";
10687     default:
10688       if (REG_P (operands[2]))
10689         return "sal{l}\t{%b2, %0|%0, %b2}";
10690       else if (operands[2] == const1_rtx
10691                && (TARGET_SHIFT1 || optimize_size))
10692         return "sal{l}\t%0";
10693       else
10694         return "sal{l}\t{%2, %0|%0, %2}";
10695     }
10697   [(set (attr "type")
10698      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10699                           (const_int 0))
10700                       (match_operand 0 "register_operand" ""))
10701                  (match_operand 2 "const1_operand" ""))
10702               (const_string "alu")
10703            ]
10704            (const_string "ishift")))
10705    (set_attr "mode" "SI")])
10707 (define_insn "*ashlsi3_cmp_zext"
10708   [(set (reg FLAGS_REG)
10709         (compare
10710           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10711                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10712           (const_int 0)))
10713    (set (match_operand:DI 0 "register_operand" "=r")
10714         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10715   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10716    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10718   switch (get_attr_type (insn))
10719     {
10720     case TYPE_ALU:
10721       gcc_assert (operands[2] == const1_rtx);
10722       return "add{l}\t{%k0, %k0|%k0, %k0}";
10724     default:
10725       if (REG_P (operands[2]))
10726         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10727       else if (operands[2] == const1_rtx
10728                && (TARGET_SHIFT1 || optimize_size))
10729         return "sal{l}\t%k0";
10730       else
10731         return "sal{l}\t{%2, %k0|%k0, %2}";
10732     }
10734   [(set (attr "type")
10735      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10736                      (const_int 0))
10737                  (match_operand 2 "const1_operand" ""))
10738               (const_string "alu")
10739            ]
10740            (const_string "ishift")))
10741    (set_attr "mode" "SI")])
10743 (define_expand "ashlhi3"
10744   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10745         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10746                    (match_operand:QI 2 "nonmemory_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_HIMODE_MATH"
10749   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10751 (define_insn "*ashlhi3_1_lea"
10752   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10753         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10754                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "!TARGET_PARTIAL_REG_STALL
10757    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10759   switch (get_attr_type (insn))
10760     {
10761     case TYPE_LEA:
10762       return "#";
10763     case TYPE_ALU:
10764       gcc_assert (operands[2] == const1_rtx);
10765       return "add{w}\t{%0, %0|%0, %0}";
10767     default:
10768       if (REG_P (operands[2]))
10769         return "sal{w}\t{%b2, %0|%0, %b2}";
10770       else if (operands[2] == const1_rtx
10771                && (TARGET_SHIFT1 || optimize_size))
10772         return "sal{w}\t%0";
10773       else
10774         return "sal{w}\t{%2, %0|%0, %2}";
10775     }
10777   [(set (attr "type")
10778      (cond [(eq_attr "alternative" "1")
10779               (const_string "lea")
10780             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10781                           (const_int 0))
10782                       (match_operand 0 "register_operand" ""))
10783                  (match_operand 2 "const1_operand" ""))
10784               (const_string "alu")
10785            ]
10786            (const_string "ishift")))
10787    (set_attr "mode" "HI,SI")])
10789 (define_insn "*ashlhi3_1"
10790   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10791         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10792                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10793    (clobber (reg:CC FLAGS_REG))]
10794   "TARGET_PARTIAL_REG_STALL
10795    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797   switch (get_attr_type (insn))
10798     {
10799     case TYPE_ALU:
10800       gcc_assert (operands[2] == const1_rtx);
10801       return "add{w}\t{%0, %0|%0, %0}";
10803     default:
10804       if (REG_P (operands[2]))
10805         return "sal{w}\t{%b2, %0|%0, %b2}";
10806       else if (operands[2] == const1_rtx
10807                && (TARGET_SHIFT1 || optimize_size))
10808         return "sal{w}\t%0";
10809       else
10810         return "sal{w}\t{%2, %0|%0, %2}";
10811     }
10813   [(set (attr "type")
10814      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10815                           (const_int 0))
10816                       (match_operand 0 "register_operand" ""))
10817                  (match_operand 2 "const1_operand" ""))
10818               (const_string "alu")
10819            ]
10820            (const_string "ishift")))
10821    (set_attr "mode" "HI")])
10823 ;; This pattern can't accept a variable shift count, since shifts by
10824 ;; zero don't affect the flags.  We assume that shifts by constant
10825 ;; zero are optimized away.
10826 (define_insn "*ashlhi3_cmp"
10827   [(set (reg FLAGS_REG)
10828         (compare
10829           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10830                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10831           (const_int 0)))
10832    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10833         (ashift:HI (match_dup 1) (match_dup 2)))]
10834   "ix86_match_ccmode (insn, CCGOCmode)
10835    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10837   switch (get_attr_type (insn))
10838     {
10839     case TYPE_ALU:
10840       gcc_assert (operands[2] == const1_rtx);
10841       return "add{w}\t{%0, %0|%0, %0}";
10843     default:
10844       if (REG_P (operands[2]))
10845         return "sal{w}\t{%b2, %0|%0, %b2}";
10846       else if (operands[2] == const1_rtx
10847                && (TARGET_SHIFT1 || optimize_size))
10848         return "sal{w}\t%0";
10849       else
10850         return "sal{w}\t{%2, %0|%0, %2}";
10851     }
10853   [(set (attr "type")
10854      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10855                           (const_int 0))
10856                       (match_operand 0 "register_operand" ""))
10857                  (match_operand 2 "const1_operand" ""))
10858               (const_string "alu")
10859            ]
10860            (const_string "ishift")))
10861    (set_attr "mode" "HI")])
10863 (define_expand "ashlqi3"
10864   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10865         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10866                    (match_operand:QI 2 "nonmemory_operand" "")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "TARGET_QIMODE_MATH"
10869   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10871 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10873 (define_insn "*ashlqi3_1_lea"
10874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10875         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10876                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10877    (clobber (reg:CC FLAGS_REG))]
10878   "!TARGET_PARTIAL_REG_STALL
10879    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10881   switch (get_attr_type (insn))
10882     {
10883     case TYPE_LEA:
10884       return "#";
10885     case TYPE_ALU:
10886       gcc_assert (operands[2] == const1_rtx);
10887       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10888         return "add{l}\t{%k0, %k0|%k0, %k0}";
10889       else
10890         return "add{b}\t{%0, %0|%0, %0}";
10892     default:
10893       if (REG_P (operands[2]))
10894         {
10895           if (get_attr_mode (insn) == MODE_SI)
10896             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897           else
10898             return "sal{b}\t{%b2, %0|%0, %b2}";
10899         }
10900       else if (operands[2] == const1_rtx
10901                && (TARGET_SHIFT1 || optimize_size))
10902         {
10903           if (get_attr_mode (insn) == MODE_SI)
10904             return "sal{l}\t%0";
10905           else
10906             return "sal{b}\t%0";
10907         }
10908       else
10909         {
10910           if (get_attr_mode (insn) == MODE_SI)
10911             return "sal{l}\t{%2, %k0|%k0, %2}";
10912           else
10913             return "sal{b}\t{%2, %0|%0, %2}";
10914         }
10915     }
10917   [(set (attr "type")
10918      (cond [(eq_attr "alternative" "2")
10919               (const_string "lea")
10920             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10921                           (const_int 0))
10922                       (match_operand 0 "register_operand" ""))
10923                  (match_operand 2 "const1_operand" ""))
10924               (const_string "alu")
10925            ]
10926            (const_string "ishift")))
10927    (set_attr "mode" "QI,SI,SI")])
10929 (define_insn "*ashlqi3_1"
10930   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10931         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10932                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10933    (clobber (reg:CC FLAGS_REG))]
10934   "TARGET_PARTIAL_REG_STALL
10935    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10937   switch (get_attr_type (insn))
10938     {
10939     case TYPE_ALU:
10940       gcc_assert (operands[2] == const1_rtx);
10941       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10942         return "add{l}\t{%k0, %k0|%k0, %k0}";
10943       else
10944         return "add{b}\t{%0, %0|%0, %0}";
10946     default:
10947       if (REG_P (operands[2]))
10948         {
10949           if (get_attr_mode (insn) == MODE_SI)
10950             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10951           else
10952             return "sal{b}\t{%b2, %0|%0, %b2}";
10953         }
10954       else if (operands[2] == const1_rtx
10955                && (TARGET_SHIFT1 || optimize_size))
10956         {
10957           if (get_attr_mode (insn) == MODE_SI)
10958             return "sal{l}\t%0";
10959           else
10960             return "sal{b}\t%0";
10961         }
10962       else
10963         {
10964           if (get_attr_mode (insn) == MODE_SI)
10965             return "sal{l}\t{%2, %k0|%k0, %2}";
10966           else
10967             return "sal{b}\t{%2, %0|%0, %2}";
10968         }
10969     }
10971   [(set (attr "type")
10972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973                           (const_int 0))
10974                       (match_operand 0 "register_operand" ""))
10975                  (match_operand 2 "const1_operand" ""))
10976               (const_string "alu")
10977            ]
10978            (const_string "ishift")))
10979    (set_attr "mode" "QI,SI")])
10981 ;; This pattern can't accept a variable shift count, since shifts by
10982 ;; zero don't affect the flags.  We assume that shifts by constant
10983 ;; zero are optimized away.
10984 (define_insn "*ashlqi3_cmp"
10985   [(set (reg FLAGS_REG)
10986         (compare
10987           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10988                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10989           (const_int 0)))
10990    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10991         (ashift:QI (match_dup 1) (match_dup 2)))]
10992   "ix86_match_ccmode (insn, CCGOCmode)
10993    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{b}\t{%0, %0|%0, %0}";
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{b}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_size))
11006         return "sal{b}\t%0";
11007       else
11008         return "sal{b}\t{%2, %0|%0, %2}";
11009     }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set_attr "mode" "QI")])
11021 ;; See comment above `ashldi3' about how this works.
11023 (define_expand "ashrti3"
11024   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11025                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11026                                 (match_operand:QI 2 "nonmemory_operand" "")))
11027               (clobber (reg:CC FLAGS_REG))])]
11028   "TARGET_64BIT"
11030   if (! immediate_operand (operands[2], QImode))
11031     {
11032       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11033       DONE;
11034     }
11035   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11036   DONE;
11039 (define_insn "ashrti3_1"
11040   [(set (match_operand:TI 0 "register_operand" "=r")
11041         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11042                      (match_operand:QI 2 "register_operand" "c")))
11043    (clobber (match_scratch:DI 3 "=&r"))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT"
11046   "#"
11047   [(set_attr "type" "multi")])
11049 (define_insn "*ashrti3_2"
11050   [(set (match_operand:TI 0 "register_operand" "=r")
11051         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11052                      (match_operand:QI 2 "immediate_operand" "O")))
11053    (clobber (reg:CC FLAGS_REG))]
11054   "TARGET_64BIT"
11055   "#"
11056   [(set_attr "type" "multi")])
11058 (define_split
11059   [(set (match_operand:TI 0 "register_operand" "")
11060         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11061                      (match_operand:QI 2 "register_operand" "")))
11062    (clobber (match_scratch:DI 3 ""))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "TARGET_64BIT && reload_completed"
11065   [(const_int 0)]
11066   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11068 (define_split
11069   [(set (match_operand:TI 0 "register_operand" "")
11070         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11071                      (match_operand:QI 2 "immediate_operand" "")))
11072    (clobber (reg:CC FLAGS_REG))]
11073   "TARGET_64BIT && reload_completed"
11074   [(const_int 0)]
11075   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11077 (define_insn "x86_64_shrd"
11078   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11079         (ior:DI (ashiftrt:DI (match_dup 0)
11080                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11081                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11082                   (minus:QI (const_int 64) (match_dup 2)))))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "TARGET_64BIT"
11085   "@
11086    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11087    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11088   [(set_attr "type" "ishift")
11089    (set_attr "prefix_0f" "1")
11090    (set_attr "mode" "DI")
11091    (set_attr "athlon_decode" "vector")])
11093 (define_expand "ashrdi3"
11094   [(set (match_operand:DI 0 "shiftdi_operand" "")
11095         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11096                      (match_operand:QI 2 "nonmemory_operand" "")))]
11097   ""
11098   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11100 (define_insn "*ashrdi3_63_rex64"
11101   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11102         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11103                      (match_operand:DI 2 "const_int_operand" "i,i")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT && INTVAL (operands[2]) == 63
11106    && (TARGET_USE_CLTD || optimize_size)
11107    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11108   "@
11109    {cqto|cqo}
11110    sar{q}\t{%2, %0|%0, %2}"
11111   [(set_attr "type" "imovx,ishift")
11112    (set_attr "prefix_0f" "0,*")
11113    (set_attr "length_immediate" "0,*")
11114    (set_attr "modrm" "0,1")
11115    (set_attr "mode" "DI")])
11117 (define_insn "*ashrdi3_1_one_bit_rex64"
11118   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11120                      (match_operand:QI 2 "const1_operand" "")))
11121    (clobber (reg:CC FLAGS_REG))]
11122   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11123    && (TARGET_SHIFT1 || optimize_size)"
11124   "sar{q}\t%0"
11125   [(set_attr "type" "ishift")
11126    (set (attr "length") 
11127      (if_then_else (match_operand:DI 0 "register_operand" "") 
11128         (const_string "2")
11129         (const_string "*")))])
11131 (define_insn "*ashrdi3_1_rex64"
11132   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11133         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11134                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11137   "@
11138    sar{q}\t{%2, %0|%0, %2}
11139    sar{q}\t{%b2, %0|%0, %b2}"
11140   [(set_attr "type" "ishift")
11141    (set_attr "mode" "DI")])
11143 ;; This pattern can't accept a variable shift count, since shifts by
11144 ;; zero don't affect the flags.  We assume that shifts by constant
11145 ;; zero are optimized away.
11146 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11147   [(set (reg FLAGS_REG)
11148         (compare
11149           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11150                        (match_operand:QI 2 "const1_operand" ""))
11151           (const_int 0)))
11152    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11153         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11154   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11155    && (TARGET_SHIFT1 || optimize_size)
11156    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11157   "sar{q}\t%0"
11158   [(set_attr "type" "ishift")
11159    (set (attr "length") 
11160      (if_then_else (match_operand:DI 0 "register_operand" "") 
11161         (const_string "2")
11162         (const_string "*")))])
11164 ;; This pattern can't accept a variable shift count, since shifts by
11165 ;; zero don't affect the flags.  We assume that shifts by constant
11166 ;; zero are optimized away.
11167 (define_insn "*ashrdi3_cmp_rex64"
11168   [(set (reg FLAGS_REG)
11169         (compare
11170           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11171                        (match_operand:QI 2 "const_int_operand" "n"))
11172           (const_int 0)))
11173    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11174         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11175   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11176    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11177   "sar{q}\t{%2, %0|%0, %2}"
11178   [(set_attr "type" "ishift")
11179    (set_attr "mode" "DI")])
11181 (define_insn "*ashrdi3_1"
11182   [(set (match_operand:DI 0 "register_operand" "=r")
11183         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11184                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11185    (clobber (reg:CC FLAGS_REG))]
11186   "!TARGET_64BIT"
11187   "#"
11188   [(set_attr "type" "multi")])
11190 ;; By default we don't ask for a scratch register, because when DImode
11191 ;; values are manipulated, registers are already at a premium.  But if
11192 ;; we have one handy, we won't turn it away.
11193 (define_peephole2
11194   [(match_scratch:SI 3 "r")
11195    (parallel [(set (match_operand:DI 0 "register_operand" "")
11196                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11197                                 (match_operand:QI 2 "nonmemory_operand" "")))
11198               (clobber (reg:CC FLAGS_REG))])
11199    (match_dup 3)]
11200   "!TARGET_64BIT && TARGET_CMOVE"
11201   [(const_int 0)]
11202   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11204 (define_split
11205   [(set (match_operand:DI 0 "register_operand" "")
11206         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11207                      (match_operand:QI 2 "nonmemory_operand" "")))
11208    (clobber (reg:CC FLAGS_REG))]
11209   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11210                      ? flow2_completed : reload_completed)"
11211   [(const_int 0)]
11212   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11214 (define_insn "x86_shrd_1"
11215   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11216         (ior:SI (ashiftrt:SI (match_dup 0)
11217                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11218                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11219                   (minus:QI (const_int 32) (match_dup 2)))))
11220    (clobber (reg:CC FLAGS_REG))]
11221   ""
11222   "@
11223    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11224    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11225   [(set_attr "type" "ishift")
11226    (set_attr "prefix_0f" "1")
11227    (set_attr "pent_pair" "np")
11228    (set_attr "mode" "SI")])
11230 (define_expand "x86_shift_adj_3"
11231   [(use (match_operand:SI 0 "register_operand" ""))
11232    (use (match_operand:SI 1 "register_operand" ""))
11233    (use (match_operand:QI 2 "register_operand" ""))]
11234   ""
11236   rtx label = gen_label_rtx ();
11237   rtx tmp;
11239   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11241   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11242   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11243   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11244                               gen_rtx_LABEL_REF (VOIDmode, label),
11245                               pc_rtx);
11246   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11247   JUMP_LABEL (tmp) = label;
11249   emit_move_insn (operands[0], operands[1]);
11250   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11252   emit_label (label);
11253   LABEL_NUSES (label) = 1;
11255   DONE;
11258 (define_insn "ashrsi3_31"
11259   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11260         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11261                      (match_operand:SI 2 "const_int_operand" "i,i")))
11262    (clobber (reg:CC FLAGS_REG))]
11263   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11264    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11265   "@
11266    {cltd|cdq}
11267    sar{l}\t{%2, %0|%0, %2}"
11268   [(set_attr "type" "imovx,ishift")
11269    (set_attr "prefix_0f" "0,*")
11270    (set_attr "length_immediate" "0,*")
11271    (set_attr "modrm" "0,1")
11272    (set_attr "mode" "SI")])
11274 (define_insn "*ashrsi3_31_zext"
11275   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11276         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11277                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11278    (clobber (reg:CC FLAGS_REG))]
11279   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11280    && INTVAL (operands[2]) == 31
11281    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11282   "@
11283    {cltd|cdq}
11284    sar{l}\t{%2, %k0|%k0, %2}"
11285   [(set_attr "type" "imovx,ishift")
11286    (set_attr "prefix_0f" "0,*")
11287    (set_attr "length_immediate" "0,*")
11288    (set_attr "modrm" "0,1")
11289    (set_attr "mode" "SI")])
11291 (define_expand "ashrsi3"
11292   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11293         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11294                      (match_operand:QI 2 "nonmemory_operand" "")))
11295    (clobber (reg:CC FLAGS_REG))]
11296   ""
11297   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11299 (define_insn "*ashrsi3_1_one_bit"
11300   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11301         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const1_operand" "")))
11303    (clobber (reg:CC FLAGS_REG))]
11304   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11305    && (TARGET_SHIFT1 || optimize_size)"
11306   "sar{l}\t%0"
11307   [(set_attr "type" "ishift")
11308    (set (attr "length") 
11309      (if_then_else (match_operand:SI 0 "register_operand" "") 
11310         (const_string "2")
11311         (const_string "*")))])
11313 (define_insn "*ashrsi3_1_one_bit_zext"
11314   [(set (match_operand:DI 0 "register_operand" "=r")
11315         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11316                                      (match_operand:QI 2 "const1_operand" ""))))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11319    && (TARGET_SHIFT1 || optimize_size)"
11320   "sar{l}\t%k0"
11321   [(set_attr "type" "ishift")
11322    (set_attr "length" "2")])
11324 (define_insn "*ashrsi3_1"
11325   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11326         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11327                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11330   "@
11331    sar{l}\t{%2, %0|%0, %2}
11332    sar{l}\t{%b2, %0|%0, %b2}"
11333   [(set_attr "type" "ishift")
11334    (set_attr "mode" "SI")])
11336 (define_insn "*ashrsi3_1_zext"
11337   [(set (match_operand:DI 0 "register_operand" "=r,r")
11338         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11339                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11340    (clobber (reg:CC FLAGS_REG))]
11341   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11342   "@
11343    sar{l}\t{%2, %k0|%k0, %2}
11344    sar{l}\t{%b2, %k0|%k0, %b2}"
11345   [(set_attr "type" "ishift")
11346    (set_attr "mode" "SI")])
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrsi3_one_bit_cmp"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355                        (match_operand:QI 2 "const1_operand" ""))
11356           (const_int 0)))
11357    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11359   "ix86_match_ccmode (insn, CCGOCmode)
11360    && (TARGET_SHIFT1 || optimize_size)
11361    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11362   "sar{l}\t%0"
11363   [(set_attr "type" "ishift")
11364    (set (attr "length") 
11365      (if_then_else (match_operand:SI 0 "register_operand" "") 
11366         (const_string "2")
11367         (const_string "*")))])
11369 (define_insn "*ashrsi3_one_bit_cmp_zext"
11370   [(set (reg FLAGS_REG)
11371         (compare
11372           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11373                        (match_operand:QI 2 "const1_operand" ""))
11374           (const_int 0)))
11375    (set (match_operand:DI 0 "register_operand" "=r")
11376         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11377   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11378    && (TARGET_SHIFT1 || optimize_size)
11379    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11380   "sar{l}\t%k0"
11381   [(set_attr "type" "ishift")
11382    (set_attr "length" "2")])
11384 ;; This pattern can't accept a variable shift count, since shifts by
11385 ;; zero don't affect the flags.  We assume that shifts by constant
11386 ;; zero are optimized away.
11387 (define_insn "*ashrsi3_cmp"
11388   [(set (reg FLAGS_REG)
11389         (compare
11390           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11391                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11392           (const_int 0)))
11393    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11394         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11395   "ix86_match_ccmode (insn, CCGOCmode)
11396    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11397   "sar{l}\t{%2, %0|%0, %2}"
11398   [(set_attr "type" "ishift")
11399    (set_attr "mode" "SI")])
11401 (define_insn "*ashrsi3_cmp_zext"
11402   [(set (reg FLAGS_REG)
11403         (compare
11404           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11405                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11406           (const_int 0)))
11407    (set (match_operand:DI 0 "register_operand" "=r")
11408         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11409   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11411   "sar{l}\t{%2, %k0|%k0, %2}"
11412   [(set_attr "type" "ishift")
11413    (set_attr "mode" "SI")])
11415 (define_expand "ashrhi3"
11416   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11417         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11418                      (match_operand:QI 2 "nonmemory_operand" "")))
11419    (clobber (reg:CC FLAGS_REG))]
11420   "TARGET_HIMODE_MATH"
11421   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11423 (define_insn "*ashrhi3_1_one_bit"
11424   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11426                      (match_operand:QI 2 "const1_operand" "")))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11429    && (TARGET_SHIFT1 || optimize_size)"
11430   "sar{w}\t%0"
11431   [(set_attr "type" "ishift")
11432    (set (attr "length") 
11433      (if_then_else (match_operand 0 "register_operand" "") 
11434         (const_string "2")
11435         (const_string "*")))])
11437 (define_insn "*ashrhi3_1"
11438   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11439         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11440                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11441    (clobber (reg:CC FLAGS_REG))]
11442   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "@
11444    sar{w}\t{%2, %0|%0, %2}
11445    sar{w}\t{%b2, %0|%0, %b2}"
11446   [(set_attr "type" "ishift")
11447    (set_attr "mode" "HI")])
11449 ;; This pattern can't accept a variable shift count, since shifts by
11450 ;; zero don't affect the flags.  We assume that shifts by constant
11451 ;; zero are optimized away.
11452 (define_insn "*ashrhi3_one_bit_cmp"
11453   [(set (reg FLAGS_REG)
11454         (compare
11455           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11456                        (match_operand:QI 2 "const1_operand" ""))
11457           (const_int 0)))
11458    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11459         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11460   "ix86_match_ccmode (insn, CCGOCmode)
11461    && (TARGET_SHIFT1 || optimize_size)
11462    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11463   "sar{w}\t%0"
11464   [(set_attr "type" "ishift")
11465    (set (attr "length") 
11466      (if_then_else (match_operand 0 "register_operand" "") 
11467         (const_string "2")
11468         (const_string "*")))])
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags.  We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashrhi3_cmp"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11478           (const_int 0)))
11479    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11480         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11481   "ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11483   "sar{w}\t{%2, %0|%0, %2}"
11484   [(set_attr "type" "ishift")
11485    (set_attr "mode" "HI")])
11487 (define_expand "ashrqi3"
11488   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11489         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11490                      (match_operand:QI 2 "nonmemory_operand" "")))
11491    (clobber (reg:CC FLAGS_REG))]
11492   "TARGET_QIMODE_MATH"
11493   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11495 (define_insn "*ashrqi3_1_one_bit"
11496   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11497         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11498                      (match_operand:QI 2 "const1_operand" "")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11501    && (TARGET_SHIFT1 || optimize_size)"
11502   "sar{b}\t%0"
11503   [(set_attr "type" "ishift")
11504    (set (attr "length") 
11505      (if_then_else (match_operand 0 "register_operand" "") 
11506         (const_string "2")
11507         (const_string "*")))])
11509 (define_insn "*ashrqi3_1_one_bit_slp"
11510   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11511         (ashiftrt:QI (match_dup 0)
11512                      (match_operand:QI 1 "const1_operand" "")))
11513    (clobber (reg:CC FLAGS_REG))]
11514   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11515    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11516    && (TARGET_SHIFT1 || optimize_size)"
11517   "sar{b}\t%0"
11518   [(set_attr "type" "ishift1")
11519    (set (attr "length") 
11520      (if_then_else (match_operand 0 "register_operand" "") 
11521         (const_string "2")
11522         (const_string "*")))])
11524 (define_insn "*ashrqi3_1"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11526         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11527                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11530   "@
11531    sar{b}\t{%2, %0|%0, %2}
11532    sar{b}\t{%b2, %0|%0, %b2}"
11533   [(set_attr "type" "ishift")
11534    (set_attr "mode" "QI")])
11536 (define_insn "*ashrqi3_1_slp"
11537   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11538         (ashiftrt:QI (match_dup 0)
11539                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11540    (clobber (reg:CC FLAGS_REG))]
11541   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11543   "@
11544    sar{b}\t{%1, %0|%0, %1}
11545    sar{b}\t{%b1, %0|%0, %b1}"
11546   [(set_attr "type" "ishift1")
11547    (set_attr "mode" "QI")])
11549 ;; This pattern can't accept a variable shift count, since shifts by
11550 ;; zero don't affect the flags.  We assume that shifts by constant
11551 ;; zero are optimized away.
11552 (define_insn "*ashrqi3_one_bit_cmp"
11553   [(set (reg FLAGS_REG)
11554         (compare
11555           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11556                        (match_operand:QI 2 "const1_operand" "I"))
11557           (const_int 0)))
11558    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11559         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11560   "ix86_match_ccmode (insn, CCGOCmode)
11561    && (TARGET_SHIFT1 || optimize_size)
11562    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11563   "sar{b}\t%0"
11564   [(set_attr "type" "ishift")
11565    (set (attr "length") 
11566      (if_then_else (match_operand 0 "register_operand" "") 
11567         (const_string "2")
11568         (const_string "*")))])
11570 ;; This pattern can't accept a variable shift count, since shifts by
11571 ;; zero don't affect the flags.  We assume that shifts by constant
11572 ;; zero are optimized away.
11573 (define_insn "*ashrqi3_cmp"
11574   [(set (reg FLAGS_REG)
11575         (compare
11576           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11577                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11578           (const_int 0)))
11579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11580         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11581   "ix86_match_ccmode (insn, CCGOCmode)
11582    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11583   "sar{b}\t{%2, %0|%0, %2}"
11584   [(set_attr "type" "ishift")
11585    (set_attr "mode" "QI")])
11587 ;; Logical shift instructions
11589 ;; See comment above `ashldi3' about how this works.
11591 (define_expand "lshrti3"
11592   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11593                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11594                                 (match_operand:QI 2 "nonmemory_operand" "")))
11595               (clobber (reg:CC FLAGS_REG))])]
11596   "TARGET_64BIT"
11598   if (! immediate_operand (operands[2], QImode))
11599     {
11600       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11601       DONE;
11602     }
11603   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11604   DONE;
11607 (define_insn "lshrti3_1"
11608   [(set (match_operand:TI 0 "register_operand" "=r")
11609         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11610                      (match_operand:QI 2 "register_operand" "c")))
11611    (clobber (match_scratch:DI 3 "=&r"))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "TARGET_64BIT"
11614   "#"
11615   [(set_attr "type" "multi")])
11617 (define_insn "*lshrti3_2"
11618   [(set (match_operand:TI 0 "register_operand" "=r")
11619         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11620                      (match_operand:QI 2 "immediate_operand" "O")))
11621    (clobber (reg:CC FLAGS_REG))]
11622   "TARGET_64BIT"
11623   "#"
11624   [(set_attr "type" "multi")])
11626 (define_split 
11627   [(set (match_operand:TI 0 "register_operand" "")
11628         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11629                      (match_operand:QI 2 "register_operand" "")))
11630    (clobber (match_scratch:DI 3 ""))
11631    (clobber (reg:CC FLAGS_REG))]
11632   "TARGET_64BIT && reload_completed"
11633   [(const_int 0)]
11634   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11636 (define_split 
11637   [(set (match_operand:TI 0 "register_operand" "")
11638         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11639                      (match_operand:QI 2 "immediate_operand" "")))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "TARGET_64BIT && reload_completed"
11642   [(const_int 0)]
11643   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11645 (define_expand "lshrdi3"
11646   [(set (match_operand:DI 0 "shiftdi_operand" "")
11647         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11648                      (match_operand:QI 2 "nonmemory_operand" "")))]
11649   ""
11650   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11652 (define_insn "*lshrdi3_1_one_bit_rex64"
11653   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11655                      (match_operand:QI 2 "const1_operand" "")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11658    && (TARGET_SHIFT1 || optimize_size)"
11659   "shr{q}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length") 
11662      (if_then_else (match_operand:DI 0 "register_operand" "") 
11663         (const_string "2")
11664         (const_string "*")))])
11666 (define_insn "*lshrdi3_1_rex64"
11667   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11668         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11669                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11670    (clobber (reg:CC FLAGS_REG))]
11671   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "@
11673    shr{q}\t{%2, %0|%0, %2}
11674    shr{q}\t{%b2, %0|%0, %b2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "DI")])
11678 ;; This pattern can't accept a variable shift count, since shifts by
11679 ;; zero don't affect the flags.  We assume that shifts by constant
11680 ;; zero are optimized away.
11681 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11682   [(set (reg FLAGS_REG)
11683         (compare
11684           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685                        (match_operand:QI 2 "const1_operand" ""))
11686           (const_int 0)))
11687    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11688         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11689   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11690    && (TARGET_SHIFT1 || optimize_size)
11691    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11692   "shr{q}\t%0"
11693   [(set_attr "type" "ishift")
11694    (set (attr "length") 
11695      (if_then_else (match_operand:DI 0 "register_operand" "") 
11696         (const_string "2")
11697         (const_string "*")))])
11699 ;; This pattern can't accept a variable shift count, since shifts by
11700 ;; zero don't affect the flags.  We assume that shifts by constant
11701 ;; zero are optimized away.
11702 (define_insn "*lshrdi3_cmp_rex64"
11703   [(set (reg FLAGS_REG)
11704         (compare
11705           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706                        (match_operand:QI 2 "const_int_operand" "e"))
11707           (const_int 0)))
11708    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11709         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11710   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11712   "shr{q}\t{%2, %0|%0, %2}"
11713   [(set_attr "type" "ishift")
11714    (set_attr "mode" "DI")])
11716 (define_insn "*lshrdi3_1"
11717   [(set (match_operand:DI 0 "register_operand" "=r")
11718         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11719                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "!TARGET_64BIT"
11722   "#"
11723   [(set_attr "type" "multi")])
11725 ;; By default we don't ask for a scratch register, because when DImode
11726 ;; values are manipulated, registers are already at a premium.  But if
11727 ;; we have one handy, we won't turn it away.
11728 (define_peephole2
11729   [(match_scratch:SI 3 "r")
11730    (parallel [(set (match_operand:DI 0 "register_operand" "")
11731                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11732                                 (match_operand:QI 2 "nonmemory_operand" "")))
11733               (clobber (reg:CC FLAGS_REG))])
11734    (match_dup 3)]
11735   "!TARGET_64BIT && TARGET_CMOVE"
11736   [(const_int 0)]
11737   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11739 (define_split 
11740   [(set (match_operand:DI 0 "register_operand" "")
11741         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11742                      (match_operand:QI 2 "nonmemory_operand" "")))
11743    (clobber (reg:CC FLAGS_REG))]
11744   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11745                      ? flow2_completed : reload_completed)"
11746   [(const_int 0)]
11747   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11749 (define_expand "lshrsi3"
11750   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11751         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11752                      (match_operand:QI 2 "nonmemory_operand" "")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   ""
11755   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757 (define_insn "*lshrsi3_1_one_bit"
11758   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11759         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11760                      (match_operand:QI 2 "const1_operand" "")))
11761    (clobber (reg:CC FLAGS_REG))]
11762   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11763    && (TARGET_SHIFT1 || optimize_size)"
11764   "shr{l}\t%0"
11765   [(set_attr "type" "ishift")
11766    (set (attr "length") 
11767      (if_then_else (match_operand:SI 0 "register_operand" "") 
11768         (const_string "2")
11769         (const_string "*")))])
11771 (define_insn "*lshrsi3_1_one_bit_zext"
11772   [(set (match_operand:DI 0 "register_operand" "=r")
11773         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11774                      (match_operand:QI 2 "const1_operand" "")))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11777    && (TARGET_SHIFT1 || optimize_size)"
11778   "shr{l}\t%k0"
11779   [(set_attr "type" "ishift")
11780    (set_attr "length" "2")])
11782 (define_insn "*lshrsi3_1"
11783   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11784         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11785                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11786    (clobber (reg:CC FLAGS_REG))]
11787   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11788   "@
11789    shr{l}\t{%2, %0|%0, %2}
11790    shr{l}\t{%b2, %0|%0, %b2}"
11791   [(set_attr "type" "ishift")
11792    (set_attr "mode" "SI")])
11794 (define_insn "*lshrsi3_1_zext"
11795   [(set (match_operand:DI 0 "register_operand" "=r,r")
11796         (zero_extend:DI
11797           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11798                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11801   "@
11802    shr{l}\t{%2, %k0|%k0, %2}
11803    shr{l}\t{%b2, %k0|%k0, %b2}"
11804   [(set_attr "type" "ishift")
11805    (set_attr "mode" "SI")])
11807 ;; This pattern can't accept a variable shift count, since shifts by
11808 ;; zero don't affect the flags.  We assume that shifts by constant
11809 ;; zero are optimized away.
11810 (define_insn "*lshrsi3_one_bit_cmp"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                        (match_operand:QI 2 "const1_operand" ""))
11815           (const_int 0)))
11816    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11817         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11818   "ix86_match_ccmode (insn, CCGOCmode)
11819    && (TARGET_SHIFT1 || optimize_size)
11820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11821   "shr{l}\t%0"
11822   [(set_attr "type" "ishift")
11823    (set (attr "length") 
11824      (if_then_else (match_operand:SI 0 "register_operand" "") 
11825         (const_string "2")
11826         (const_string "*")))])
11828 (define_insn "*lshrsi3_cmp_one_bit_zext"
11829   [(set (reg FLAGS_REG)
11830         (compare
11831           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11832                        (match_operand:QI 2 "const1_operand" ""))
11833           (const_int 0)))
11834    (set (match_operand:DI 0 "register_operand" "=r")
11835         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11837    && (TARGET_SHIFT1 || optimize_size)
11838    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11839   "shr{l}\t%k0"
11840   [(set_attr "type" "ishift")
11841    (set_attr "length" "2")])
11843 ;; This pattern can't accept a variable shift count, since shifts by
11844 ;; zero don't affect the flags.  We assume that shifts by constant
11845 ;; zero are optimized away.
11846 (define_insn "*lshrsi3_cmp"
11847   [(set (reg FLAGS_REG)
11848         (compare
11849           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11850                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11851           (const_int 0)))
11852    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11853         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11854   "ix86_match_ccmode (insn, CCGOCmode)
11855    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11856   "shr{l}\t{%2, %0|%0, %2}"
11857   [(set_attr "type" "ishift")
11858    (set_attr "mode" "SI")])
11860 (define_insn "*lshrsi3_cmp_zext"
11861   [(set (reg FLAGS_REG)
11862         (compare
11863           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11864                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11865           (const_int 0)))
11866    (set (match_operand:DI 0 "register_operand" "=r")
11867         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11868   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870   "shr{l}\t{%2, %k0|%k0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "SI")])
11874 (define_expand "lshrhi3"
11875   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11876         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11877                      (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_HIMODE_MATH"
11880   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882 (define_insn "*lshrhi3_1_one_bit"
11883   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11885                      (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "shr{w}\t%0"
11890   [(set_attr "type" "ishift")
11891    (set (attr "length") 
11892      (if_then_else (match_operand 0 "register_operand" "") 
11893         (const_string "2")
11894         (const_string "*")))])
11896 (define_insn "*lshrhi3_1"
11897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11898         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11899                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11902   "@
11903    shr{w}\t{%2, %0|%0, %2}
11904    shr{w}\t{%b2, %0|%0, %b2}"
11905   [(set_attr "type" "ishift")
11906    (set_attr "mode" "HI")])
11908 ;; This pattern can't accept a variable shift count, since shifts by
11909 ;; zero don't affect the flags.  We assume that shifts by constant
11910 ;; zero are optimized away.
11911 (define_insn "*lshrhi3_one_bit_cmp"
11912   [(set (reg FLAGS_REG)
11913         (compare
11914           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11915                        (match_operand:QI 2 "const1_operand" ""))
11916           (const_int 0)))
11917    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11918         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11919   "ix86_match_ccmode (insn, CCGOCmode)
11920    && (TARGET_SHIFT1 || optimize_size)
11921    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11922   "shr{w}\t%0"
11923   [(set_attr "type" "ishift")
11924    (set (attr "length") 
11925      (if_then_else (match_operand:SI 0 "register_operand" "") 
11926         (const_string "2")
11927         (const_string "*")))])
11929 ;; This pattern can't accept a variable shift count, since shifts by
11930 ;; zero don't affect the flags.  We assume that shifts by constant
11931 ;; zero are optimized away.
11932 (define_insn "*lshrhi3_cmp"
11933   [(set (reg FLAGS_REG)
11934         (compare
11935           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11936                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11937           (const_int 0)))
11938    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11939         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11940   "ix86_match_ccmode (insn, CCGOCmode)
11941    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11942   "shr{w}\t{%2, %0|%0, %2}"
11943   [(set_attr "type" "ishift")
11944    (set_attr "mode" "HI")])
11946 (define_expand "lshrqi3"
11947   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11948         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11949                      (match_operand:QI 2 "nonmemory_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "TARGET_QIMODE_MATH"
11952   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954 (define_insn "*lshrqi3_1_one_bit"
11955   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11956         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11957                      (match_operand:QI 2 "const1_operand" "")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11960    && (TARGET_SHIFT1 || optimize_size)"
11961   "shr{b}\t%0"
11962   [(set_attr "type" "ishift")
11963    (set (attr "length") 
11964      (if_then_else (match_operand 0 "register_operand" "") 
11965         (const_string "2")
11966         (const_string "*")))])
11968 (define_insn "*lshrqi3_1_one_bit_slp"
11969   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11970         (lshiftrt:QI (match_dup 0)
11971                      (match_operand:QI 1 "const1_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11974    && (TARGET_SHIFT1 || optimize_size)"
11975   "shr{b}\t%0"
11976   [(set_attr "type" "ishift1")
11977    (set (attr "length") 
11978      (if_then_else (match_operand 0 "register_operand" "") 
11979         (const_string "2")
11980         (const_string "*")))])
11982 (define_insn "*lshrqi3_1"
11983   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11984         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11985                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988   "@
11989    shr{b}\t{%2, %0|%0, %2}
11990    shr{b}\t{%b2, %0|%0, %b2}"
11991   [(set_attr "type" "ishift")
11992    (set_attr "mode" "QI")])
11994 (define_insn "*lshrqi3_1_slp"
11995   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11996         (lshiftrt:QI (match_dup 0)
11997                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11998    (clobber (reg:CC FLAGS_REG))]
11999   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12000    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12001   "@
12002    shr{b}\t{%1, %0|%0, %1}
12003    shr{b}\t{%b1, %0|%0, %b1}"
12004   [(set_attr "type" "ishift1")
12005    (set_attr "mode" "QI")])
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags.  We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*lshrqi2_one_bit_cmp"
12011   [(set (reg FLAGS_REG)
12012         (compare
12013           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12014                        (match_operand:QI 2 "const1_operand" ""))
12015           (const_int 0)))
12016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12017         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12018   "ix86_match_ccmode (insn, CCGOCmode)
12019    && (TARGET_SHIFT1 || optimize_size)
12020    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12021   "shr{b}\t%0"
12022   [(set_attr "type" "ishift")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:SI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12028 ;; This pattern can't accept a variable shift count, since shifts by
12029 ;; zero don't affect the flags.  We assume that shifts by constant
12030 ;; zero are optimized away.
12031 (define_insn "*lshrqi2_cmp"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12038         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12039   "ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12041   "shr{b}\t{%2, %0|%0, %2}"
12042   [(set_attr "type" "ishift")
12043    (set_attr "mode" "QI")])
12045 ;; Rotate instructions
12047 (define_expand "rotldi3"
12048   [(set (match_operand:DI 0 "shiftdi_operand" "")
12049         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12050                    (match_operand:QI 2 "nonmemory_operand" "")))
12051    (clobber (reg:CC FLAGS_REG))]
12052  ""
12054   if (TARGET_64BIT)
12055     {
12056       ix86_expand_binary_operator (ROTATE, DImode, operands);
12057       DONE;
12058     }
12059   if (!const_1_to_31_operand (operands[2], VOIDmode))
12060     FAIL;
12061   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12062   DONE;
12065 ;; Implement rotation using two double-precision shift instructions
12066 ;; and a scratch register.   
12067 (define_insn_and_split "ix86_rotldi3"
12068  [(set (match_operand:DI 0 "register_operand" "=r")
12069        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12070                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12071   (clobber (reg:CC FLAGS_REG))
12072   (clobber (match_scratch:SI 3 "=&r"))]
12073  "!TARGET_64BIT"
12074  "" 
12075  "&& reload_completed"
12076  [(set (match_dup 3) (match_dup 4))
12077   (parallel
12078    [(set (match_dup 4)
12079          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12080                  (lshiftrt:SI (match_dup 5)
12081                               (minus:QI (const_int 32) (match_dup 2)))))
12082     (clobber (reg:CC FLAGS_REG))])
12083   (parallel
12084    [(set (match_dup 5)
12085          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12086                  (lshiftrt:SI (match_dup 3)
12087                               (minus:QI (const_int 32) (match_dup 2)))))
12088     (clobber (reg:CC FLAGS_REG))])]
12089  "split_di (operands, 1, operands + 4, operands + 5);")
12091 (define_insn "*rotlsi3_1_one_bit_rex64"
12092   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12093         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12094                    (match_operand:QI 2 "const1_operand" "")))
12095    (clobber (reg:CC FLAGS_REG))]
12096   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12097    && (TARGET_SHIFT1 || optimize_size)"
12098   "rol{q}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set (attr "length") 
12101      (if_then_else (match_operand:DI 0 "register_operand" "") 
12102         (const_string "2")
12103         (const_string "*")))])
12105 (define_insn "*rotldi3_1_rex64"
12106   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12107         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12108                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12111   "@
12112    rol{q}\t{%2, %0|%0, %2}
12113    rol{q}\t{%b2, %0|%0, %b2}"
12114   [(set_attr "type" "rotate")
12115    (set_attr "mode" "DI")])
12117 (define_expand "rotlsi3"
12118   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12119         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12120                    (match_operand:QI 2 "nonmemory_operand" "")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   ""
12123   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12125 (define_insn "*rotlsi3_1_one_bit"
12126   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12127         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12128                    (match_operand:QI 2 "const1_operand" "")))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12131    && (TARGET_SHIFT1 || optimize_size)"
12132   "rol{l}\t%0"
12133   [(set_attr "type" "rotate")
12134    (set (attr "length") 
12135      (if_then_else (match_operand:SI 0 "register_operand" "") 
12136         (const_string "2")
12137         (const_string "*")))])
12139 (define_insn "*rotlsi3_1_one_bit_zext"
12140   [(set (match_operand:DI 0 "register_operand" "=r")
12141         (zero_extend:DI
12142           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12143                      (match_operand:QI 2 "const1_operand" ""))))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12146    && (TARGET_SHIFT1 || optimize_size)"
12147   "rol{l}\t%k0"
12148   [(set_attr "type" "rotate")
12149    (set_attr "length" "2")])
12151 (define_insn "*rotlsi3_1"
12152   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12153         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12154                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12157   "@
12158    rol{l}\t{%2, %0|%0, %2}
12159    rol{l}\t{%b2, %0|%0, %b2}"
12160   [(set_attr "type" "rotate")
12161    (set_attr "mode" "SI")])
12163 (define_insn "*rotlsi3_1_zext"
12164   [(set (match_operand:DI 0 "register_operand" "=r,r")
12165         (zero_extend:DI
12166           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12167                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12170   "@
12171    rol{l}\t{%2, %k0|%k0, %2}
12172    rol{l}\t{%b2, %k0|%k0, %b2}"
12173   [(set_attr "type" "rotate")
12174    (set_attr "mode" "SI")])
12176 (define_expand "rotlhi3"
12177   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12178         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12179                    (match_operand:QI 2 "nonmemory_operand" "")))
12180    (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_HIMODE_MATH"
12182   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12184 (define_insn "*rotlhi3_1_one_bit"
12185   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12186         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187                    (match_operand:QI 2 "const1_operand" "")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12190    && (TARGET_SHIFT1 || optimize_size)"
12191   "rol{w}\t%0"
12192   [(set_attr "type" "rotate")
12193    (set (attr "length") 
12194      (if_then_else (match_operand 0 "register_operand" "") 
12195         (const_string "2")
12196         (const_string "*")))])
12198 (define_insn "*rotlhi3_1"
12199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12200         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12201                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12204   "@
12205    rol{w}\t{%2, %0|%0, %2}
12206    rol{w}\t{%b2, %0|%0, %b2}"
12207   [(set_attr "type" "rotate")
12208    (set_attr "mode" "HI")])
12210 (define_expand "rotlqi3"
12211   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12212         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12213                    (match_operand:QI 2 "nonmemory_operand" "")))
12214    (clobber (reg:CC FLAGS_REG))]
12215   "TARGET_QIMODE_MATH"
12216   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12218 (define_insn "*rotlqi3_1_one_bit_slp"
12219   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12220         (rotate:QI (match_dup 0)
12221                    (match_operand:QI 1 "const1_operand" "")))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12224    && (TARGET_SHIFT1 || optimize_size)"
12225   "rol{b}\t%0"
12226   [(set_attr "type" "rotate1")
12227    (set (attr "length") 
12228      (if_then_else (match_operand 0 "register_operand" "") 
12229         (const_string "2")
12230         (const_string "*")))])
12232 (define_insn "*rotlqi3_1_one_bit"
12233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235                    (match_operand:QI 2 "const1_operand" "")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12238    && (TARGET_SHIFT1 || optimize_size)"
12239   "rol{b}\t%0"
12240   [(set_attr "type" "rotate")
12241    (set (attr "length") 
12242      (if_then_else (match_operand 0 "register_operand" "") 
12243         (const_string "2")
12244         (const_string "*")))])
12246 (define_insn "*rotlqi3_1_slp"
12247   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12248         (rotate:QI (match_dup 0)
12249                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12250    (clobber (reg:CC FLAGS_REG))]
12251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12252    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12253   "@
12254    rol{b}\t{%1, %0|%0, %1}
12255    rol{b}\t{%b1, %0|%0, %b1}"
12256   [(set_attr "type" "rotate1")
12257    (set_attr "mode" "QI")])
12259 (define_insn "*rotlqi3_1"
12260   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12261         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12262                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12263    (clobber (reg:CC FLAGS_REG))]
12264   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12265   "@
12266    rol{b}\t{%2, %0|%0, %2}
12267    rol{b}\t{%b2, %0|%0, %b2}"
12268   [(set_attr "type" "rotate")
12269    (set_attr "mode" "QI")])
12271 (define_expand "rotrdi3"
12272   [(set (match_operand:DI 0 "shiftdi_operand" "")
12273         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12274                    (match_operand:QI 2 "nonmemory_operand" "")))
12275    (clobber (reg:CC FLAGS_REG))]
12276  ""
12278   if (TARGET_64BIT)
12279     {
12280       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12281       DONE;
12282     }
12283   if (!const_1_to_31_operand (operands[2], VOIDmode))
12284     FAIL;
12285   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12286   DONE;
12288   
12289 ;; Implement rotation using two double-precision shift instructions
12290 ;; and a scratch register.   
12291 (define_insn_and_split "ix86_rotrdi3"
12292  [(set (match_operand:DI 0 "register_operand" "=r")
12293        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12294                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12295   (clobber (reg:CC FLAGS_REG))
12296   (clobber (match_scratch:SI 3 "=&r"))]
12297  "!TARGET_64BIT"
12298  ""
12299  "&& reload_completed"
12300  [(set (match_dup 3) (match_dup 4))
12301   (parallel
12302    [(set (match_dup 4)
12303          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12304                  (ashift:SI (match_dup 5)
12305                             (minus:QI (const_int 32) (match_dup 2)))))
12306     (clobber (reg:CC FLAGS_REG))])
12307   (parallel
12308    [(set (match_dup 5)
12309          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12310                  (ashift:SI (match_dup 3)
12311                             (minus:QI (const_int 32) (match_dup 2)))))
12312     (clobber (reg:CC FLAGS_REG))])]
12313  "split_di (operands, 1, operands + 4, operands + 5);")
12315 (define_insn "*rotrdi3_1_one_bit_rex64"
12316   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12317         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12318                      (match_operand:QI 2 "const1_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12321    && (TARGET_SHIFT1 || optimize_size)"
12322   "ror{q}\t%0"
12323   [(set_attr "type" "rotate")
12324    (set (attr "length") 
12325      (if_then_else (match_operand:DI 0 "register_operand" "") 
12326         (const_string "2")
12327         (const_string "*")))])
12329 (define_insn "*rotrdi3_1_rex64"
12330   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12331         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12332                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12333    (clobber (reg:CC FLAGS_REG))]
12334   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12335   "@
12336    ror{q}\t{%2, %0|%0, %2}
12337    ror{q}\t{%b2, %0|%0, %b2}"
12338   [(set_attr "type" "rotate")
12339    (set_attr "mode" "DI")])
12341 (define_expand "rotrsi3"
12342   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12343         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12344                      (match_operand:QI 2 "nonmemory_operand" "")))
12345    (clobber (reg:CC FLAGS_REG))]
12346   ""
12347   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12349 (define_insn "*rotrsi3_1_one_bit"
12350   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12351         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12352                      (match_operand:QI 2 "const1_operand" "")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12355    && (TARGET_SHIFT1 || optimize_size)"
12356   "ror{l}\t%0"
12357   [(set_attr "type" "rotate")
12358    (set (attr "length") 
12359      (if_then_else (match_operand:SI 0 "register_operand" "") 
12360         (const_string "2")
12361         (const_string "*")))])
12363 (define_insn "*rotrsi3_1_one_bit_zext"
12364   [(set (match_operand:DI 0 "register_operand" "=r")
12365         (zero_extend:DI
12366           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12367                        (match_operand:QI 2 "const1_operand" ""))))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12370    && (TARGET_SHIFT1 || optimize_size)"
12371   "ror{l}\t%k0"
12372   [(set_attr "type" "rotate")
12373    (set (attr "length") 
12374      (if_then_else (match_operand:SI 0 "register_operand" "") 
12375         (const_string "2")
12376         (const_string "*")))])
12378 (define_insn "*rotrsi3_1"
12379   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12380         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12381                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12384   "@
12385    ror{l}\t{%2, %0|%0, %2}
12386    ror{l}\t{%b2, %0|%0, %b2}"
12387   [(set_attr "type" "rotate")
12388    (set_attr "mode" "SI")])
12390 (define_insn "*rotrsi3_1_zext"
12391   [(set (match_operand:DI 0 "register_operand" "=r,r")
12392         (zero_extend:DI
12393           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12394                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12397   "@
12398    ror{l}\t{%2, %k0|%k0, %2}
12399    ror{l}\t{%b2, %k0|%k0, %b2}"
12400   [(set_attr "type" "rotate")
12401    (set_attr "mode" "SI")])
12403 (define_expand "rotrhi3"
12404   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12405         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12406                      (match_operand:QI 2 "nonmemory_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_HIMODE_MATH"
12409   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12411 (define_insn "*rotrhi3_one_bit"
12412   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12413         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12414                      (match_operand:QI 2 "const1_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12417    && (TARGET_SHIFT1 || optimize_size)"
12418   "ror{w}\t%0"
12419   [(set_attr "type" "rotate")
12420    (set (attr "length") 
12421      (if_then_else (match_operand 0 "register_operand" "") 
12422         (const_string "2")
12423         (const_string "*")))])
12425 (define_insn "*rotrhi3"
12426   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12427         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12428                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12431   "@
12432    ror{w}\t{%2, %0|%0, %2}
12433    ror{w}\t{%b2, %0|%0, %b2}"
12434   [(set_attr "type" "rotate")
12435    (set_attr "mode" "HI")])
12437 (define_expand "rotrqi3"
12438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12439         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12440                      (match_operand:QI 2 "nonmemory_operand" "")))
12441    (clobber (reg:CC FLAGS_REG))]
12442   "TARGET_QIMODE_MATH"
12443   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12445 (define_insn "*rotrqi3_1_one_bit"
12446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12447         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12448                      (match_operand:QI 2 "const1_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12451    && (TARGET_SHIFT1 || optimize_size)"
12452   "ror{b}\t%0"
12453   [(set_attr "type" "rotate")
12454    (set (attr "length") 
12455      (if_then_else (match_operand 0 "register_operand" "") 
12456         (const_string "2")
12457         (const_string "*")))])
12459 (define_insn "*rotrqi3_1_one_bit_slp"
12460   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12461         (rotatert:QI (match_dup 0)
12462                      (match_operand:QI 1 "const1_operand" "")))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12465    && (TARGET_SHIFT1 || optimize_size)"
12466   "ror{b}\t%0"
12467   [(set_attr "type" "rotate1")
12468    (set (attr "length") 
12469      (if_then_else (match_operand 0 "register_operand" "") 
12470         (const_string "2")
12471         (const_string "*")))])
12473 (define_insn "*rotrqi3_1"
12474   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12475         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12476                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12479   "@
12480    ror{b}\t{%2, %0|%0, %2}
12481    ror{b}\t{%b2, %0|%0, %b2}"
12482   [(set_attr "type" "rotate")
12483    (set_attr "mode" "QI")])
12485 (define_insn "*rotrqi3_1_slp"
12486   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12487         (rotatert:QI (match_dup 0)
12488                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12489    (clobber (reg:CC FLAGS_REG))]
12490   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12491    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12492   "@
12493    ror{b}\t{%1, %0|%0, %1}
12494    ror{b}\t{%b1, %0|%0, %b1}"
12495   [(set_attr "type" "rotate1")
12496    (set_attr "mode" "QI")])
12498 ;; Bit set / bit test instructions
12500 (define_expand "extv"
12501   [(set (match_operand:SI 0 "register_operand" "")
12502         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12503                          (match_operand:SI 2 "immediate_operand" "")
12504                          (match_operand:SI 3 "immediate_operand" "")))]
12505   ""
12507   /* Handle extractions from %ah et al.  */
12508   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12509     FAIL;
12511   /* From mips.md: extract_bit_field doesn't verify that our source
12512      matches the predicate, so check it again here.  */
12513   if (! ext_register_operand (operands[1], VOIDmode))
12514     FAIL;
12517 (define_expand "extzv"
12518   [(set (match_operand:SI 0 "register_operand" "")
12519         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12520                          (match_operand:SI 2 "immediate_operand" "")
12521                          (match_operand:SI 3 "immediate_operand" "")))]
12522   ""
12524   /* Handle extractions from %ah et al.  */
12525   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12526     FAIL;
12528   /* From mips.md: extract_bit_field doesn't verify that our source
12529      matches the predicate, so check it again here.  */
12530   if (! ext_register_operand (operands[1], VOIDmode))
12531     FAIL;
12534 (define_expand "insv"
12535   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12536                       (match_operand 1 "immediate_operand" "")
12537                       (match_operand 2 "immediate_operand" ""))
12538         (match_operand 3 "register_operand" ""))]
12539   ""
12541   /* Handle extractions from %ah et al.  */
12542   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12543     FAIL;
12545   /* From mips.md: insert_bit_field doesn't verify that our source
12546      matches the predicate, so check it again here.  */
12547   if (! ext_register_operand (operands[0], VOIDmode))
12548     FAIL;
12550   if (TARGET_64BIT)
12551     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12552   else
12553     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12555   DONE;
12558 ;; %%% bts, btr, btc, bt.
12559 ;; In general these instructions are *slow* when applied to memory,
12560 ;; since they enforce atomic operation.  When applied to registers,
12561 ;; it depends on the cpu implementation.  They're never faster than
12562 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12563 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12564 ;; within the instruction itself, so operating on bits in the high
12565 ;; 32-bits of a register becomes easier.
12567 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12568 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12569 ;; negdf respectively, so they can never be disabled entirely.
12571 (define_insn "*btsq"
12572   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12573                          (const_int 1)
12574                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12575         (const_int 1))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12578   "bts{q} %1,%0"
12579   [(set_attr "type" "alu1")])
12581 (define_insn "*btrq"
12582   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12583                          (const_int 1)
12584                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12585         (const_int 0))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12588   "btr{q} %1,%0"
12589   [(set_attr "type" "alu1")])
12591 (define_insn "*btcq"
12592   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12593                          (const_int 1)
12594                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12595         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12596    (clobber (reg:CC FLAGS_REG))]
12597   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12598   "btc{q} %1,%0"
12599   [(set_attr "type" "alu1")])
12601 ;; Allow Nocona to avoid these instructions if a register is available.
12603 (define_peephole2
12604   [(match_scratch:DI 2 "r")
12605    (parallel [(set (zero_extract:DI
12606                      (match_operand:DI 0 "register_operand" "")
12607                      (const_int 1)
12608                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12609                    (const_int 1))
12610               (clobber (reg:CC FLAGS_REG))])]
12611   "TARGET_64BIT && !TARGET_USE_BT"
12612   [(const_int 0)]
12614   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615   rtx op1;
12617   if (HOST_BITS_PER_WIDE_INT >= 64)
12618     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619   else if (i < HOST_BITS_PER_WIDE_INT)
12620     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621   else
12622     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624   op1 = immed_double_const (lo, hi, DImode);
12625   if (i >= 31)
12626     {
12627       emit_move_insn (operands[2], op1);
12628       op1 = operands[2];
12629     }
12631   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12632   DONE;
12635 (define_peephole2
12636   [(match_scratch:DI 2 "r")
12637    (parallel [(set (zero_extract:DI
12638                      (match_operand:DI 0 "register_operand" "")
12639                      (const_int 1)
12640                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12641                    (const_int 0))
12642               (clobber (reg:CC FLAGS_REG))])]
12643   "TARGET_64BIT && !TARGET_USE_BT"
12644   [(const_int 0)]
12646   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12647   rtx op1;
12649   if (HOST_BITS_PER_WIDE_INT >= 64)
12650     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12651   else if (i < HOST_BITS_PER_WIDE_INT)
12652     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653   else
12654     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12656   op1 = immed_double_const (~lo, ~hi, DImode);
12657   if (i >= 32)
12658     {
12659       emit_move_insn (operands[2], op1);
12660       op1 = operands[2];
12661     }
12663   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12664   DONE;
12667 (define_peephole2
12668   [(match_scratch:DI 2 "r")
12669    (parallel [(set (zero_extract:DI
12670                      (match_operand:DI 0 "register_operand" "")
12671                      (const_int 1)
12672                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12673               (not:DI (zero_extract:DI
12674                         (match_dup 0) (const_int 1) (match_dup 1))))
12675               (clobber (reg:CC FLAGS_REG))])]
12676   "TARGET_64BIT && !TARGET_USE_BT"
12677   [(const_int 0)]
12679   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12680   rtx op1;
12682   if (HOST_BITS_PER_WIDE_INT >= 64)
12683     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12684   else if (i < HOST_BITS_PER_WIDE_INT)
12685     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12686   else
12687     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12689   op1 = immed_double_const (lo, hi, DImode);
12690   if (i >= 31)
12691     {
12692       emit_move_insn (operands[2], op1);
12693       op1 = operands[2];
12694     }
12696   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12697   DONE;
12700 ;; Store-flag instructions.
12702 ;; For all sCOND expanders, also expand the compare or test insn that
12703 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12705 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12706 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12707 ;; way, which can later delete the movzx if only QImode is needed.
12709 (define_expand "seq"
12710   [(set (match_operand:QI 0 "register_operand" "")
12711         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12712   ""
12713   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12715 (define_expand "sne"
12716   [(set (match_operand:QI 0 "register_operand" "")
12717         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12718   ""
12719   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12721 (define_expand "sgt"
12722   [(set (match_operand:QI 0 "register_operand" "")
12723         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12724   ""
12725   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12727 (define_expand "sgtu"
12728   [(set (match_operand:QI 0 "register_operand" "")
12729         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12730   ""
12731   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12733 (define_expand "slt"
12734   [(set (match_operand:QI 0 "register_operand" "")
12735         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12736   ""
12737   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12739 (define_expand "sltu"
12740   [(set (match_operand:QI 0 "register_operand" "")
12741         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742   ""
12743   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12745 (define_expand "sge"
12746   [(set (match_operand:QI 0 "register_operand" "")
12747         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12748   ""
12749   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12751 (define_expand "sgeu"
12752   [(set (match_operand:QI 0 "register_operand" "")
12753         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754   ""
12755   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12757 (define_expand "sle"
12758   [(set (match_operand:QI 0 "register_operand" "")
12759         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760   ""
12761   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12763 (define_expand "sleu"
12764   [(set (match_operand:QI 0 "register_operand" "")
12765         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766   ""
12767   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12769 (define_expand "sunordered"
12770   [(set (match_operand:QI 0 "register_operand" "")
12771         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772   "TARGET_80387 || TARGET_SSE"
12773   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12775 (define_expand "sordered"
12776   [(set (match_operand:QI 0 "register_operand" "")
12777         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778   "TARGET_80387"
12779   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12781 (define_expand "suneq"
12782   [(set (match_operand:QI 0 "register_operand" "")
12783         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12784   "TARGET_80387 || TARGET_SSE"
12785   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12787 (define_expand "sunge"
12788   [(set (match_operand:QI 0 "register_operand" "")
12789         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12790   "TARGET_80387 || TARGET_SSE"
12791   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12793 (define_expand "sungt"
12794   [(set (match_operand:QI 0 "register_operand" "")
12795         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12796   "TARGET_80387 || TARGET_SSE"
12797   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12799 (define_expand "sunle"
12800   [(set (match_operand:QI 0 "register_operand" "")
12801         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12802   "TARGET_80387 || TARGET_SSE"
12803   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12805 (define_expand "sunlt"
12806   [(set (match_operand:QI 0 "register_operand" "")
12807         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12808   "TARGET_80387 || TARGET_SSE"
12809   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12811 (define_expand "sltgt"
12812   [(set (match_operand:QI 0 "register_operand" "")
12813         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12814   "TARGET_80387 || TARGET_SSE"
12815   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12817 (define_insn "*setcc_1"
12818   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12819         (match_operator:QI 1 "ix86_comparison_operator"
12820           [(reg FLAGS_REG) (const_int 0)]))]
12821   ""
12822   "set%C1\t%0"
12823   [(set_attr "type" "setcc")
12824    (set_attr "mode" "QI")])
12826 (define_insn "*setcc_2"
12827   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12828         (match_operator:QI 1 "ix86_comparison_operator"
12829           [(reg FLAGS_REG) (const_int 0)]))]
12830   ""
12831   "set%C1\t%0"
12832   [(set_attr "type" "setcc")
12833    (set_attr "mode" "QI")])
12835 ;; In general it is not safe to assume too much about CCmode registers,
12836 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12837 ;; conditions this is safe on x86, so help combine not create
12839 ;;      seta    %al
12840 ;;      testb   %al, %al
12841 ;;      sete    %al
12843 (define_split 
12844   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12845         (ne:QI (match_operator 1 "ix86_comparison_operator"
12846                  [(reg FLAGS_REG) (const_int 0)])
12847             (const_int 0)))]
12848   ""
12849   [(set (match_dup 0) (match_dup 1))]
12851   PUT_MODE (operands[1], QImode);
12854 (define_split 
12855   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12856         (ne:QI (match_operator 1 "ix86_comparison_operator"
12857                  [(reg FLAGS_REG) (const_int 0)])
12858             (const_int 0)))]
12859   ""
12860   [(set (match_dup 0) (match_dup 1))]
12862   PUT_MODE (operands[1], QImode);
12865 (define_split 
12866   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12867         (eq:QI (match_operator 1 "ix86_comparison_operator"
12868                  [(reg FLAGS_REG) (const_int 0)])
12869             (const_int 0)))]
12870   ""
12871   [(set (match_dup 0) (match_dup 1))]
12873   rtx new_op1 = copy_rtx (operands[1]);
12874   operands[1] = new_op1;
12875   PUT_MODE (new_op1, QImode);
12876   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12877                                              GET_MODE (XEXP (new_op1, 0))));
12879   /* Make sure that (a) the CCmode we have for the flags is strong
12880      enough for the reversed compare or (b) we have a valid FP compare.  */
12881   if (! ix86_comparison_operator (new_op1, VOIDmode))
12882     FAIL;
12885 (define_split 
12886   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12887         (eq:QI (match_operator 1 "ix86_comparison_operator"
12888                  [(reg FLAGS_REG) (const_int 0)])
12889             (const_int 0)))]
12890   ""
12891   [(set (match_dup 0) (match_dup 1))]
12893   rtx new_op1 = copy_rtx (operands[1]);
12894   operands[1] = new_op1;
12895   PUT_MODE (new_op1, QImode);
12896   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12897                                              GET_MODE (XEXP (new_op1, 0))));
12899   /* Make sure that (a) the CCmode we have for the flags is strong
12900      enough for the reversed compare or (b) we have a valid FP compare.  */
12901   if (! ix86_comparison_operator (new_op1, VOIDmode))
12902     FAIL;
12905 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12906 ;; subsequent logical operations are used to imitate conditional moves.
12907 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12908 ;; it directly.
12910 (define_insn "*sse_setccsf"
12911   [(set (match_operand:SF 0 "register_operand" "=x")
12912         (match_operator:SF 1 "sse_comparison_operator"
12913           [(match_operand:SF 2 "register_operand" "0")
12914            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12915   "TARGET_SSE"
12916   "cmp%D1ss\t{%3, %0|%0, %3}"
12917   [(set_attr "type" "ssecmp")
12918    (set_attr "mode" "SF")])
12920 (define_insn "*sse_setccdf"
12921   [(set (match_operand:DF 0 "register_operand" "=Y")
12922         (match_operator:DF 1 "sse_comparison_operator"
12923           [(match_operand:DF 2 "register_operand" "0")
12924            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12925   "TARGET_SSE2"
12926   "cmp%D1sd\t{%3, %0|%0, %3}"
12927   [(set_attr "type" "ssecmp")
12928    (set_attr "mode" "DF")])
12930 ;; Basic conditional jump instructions.
12931 ;; We ignore the overflow flag for signed branch instructions.
12933 ;; For all bCOND expanders, also expand the compare or test insn that
12934 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12936 (define_expand "beq"
12937   [(set (pc)
12938         (if_then_else (match_dup 1)
12939                       (label_ref (match_operand 0 "" ""))
12940                       (pc)))]
12941   ""
12942   "ix86_expand_branch (EQ, operands[0]); DONE;")
12944 (define_expand "bne"
12945   [(set (pc)
12946         (if_then_else (match_dup 1)
12947                       (label_ref (match_operand 0 "" ""))
12948                       (pc)))]
12949   ""
12950   "ix86_expand_branch (NE, operands[0]); DONE;")
12952 (define_expand "bgt"
12953   [(set (pc)
12954         (if_then_else (match_dup 1)
12955                       (label_ref (match_operand 0 "" ""))
12956                       (pc)))]
12957   ""
12958   "ix86_expand_branch (GT, operands[0]); DONE;")
12960 (define_expand "bgtu"
12961   [(set (pc)
12962         (if_then_else (match_dup 1)
12963                       (label_ref (match_operand 0 "" ""))
12964                       (pc)))]
12965   ""
12966   "ix86_expand_branch (GTU, operands[0]); DONE;")
12968 (define_expand "blt"
12969   [(set (pc)
12970         (if_then_else (match_dup 1)
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "ix86_expand_branch (LT, operands[0]); DONE;")
12976 (define_expand "bltu"
12977   [(set (pc)
12978         (if_then_else (match_dup 1)
12979                       (label_ref (match_operand 0 "" ""))
12980                       (pc)))]
12981   ""
12982   "ix86_expand_branch (LTU, operands[0]); DONE;")
12984 (define_expand "bge"
12985   [(set (pc)
12986         (if_then_else (match_dup 1)
12987                       (label_ref (match_operand 0 "" ""))
12988                       (pc)))]
12989   ""
12990   "ix86_expand_branch (GE, operands[0]); DONE;")
12992 (define_expand "bgeu"
12993   [(set (pc)
12994         (if_then_else (match_dup 1)
12995                       (label_ref (match_operand 0 "" ""))
12996                       (pc)))]
12997   ""
12998   "ix86_expand_branch (GEU, operands[0]); DONE;")
13000 (define_expand "ble"
13001   [(set (pc)
13002         (if_then_else (match_dup 1)
13003                       (label_ref (match_operand 0 "" ""))
13004                       (pc)))]
13005   ""
13006   "ix86_expand_branch (LE, operands[0]); DONE;")
13008 (define_expand "bleu"
13009   [(set (pc)
13010         (if_then_else (match_dup 1)
13011                       (label_ref (match_operand 0 "" ""))
13012                       (pc)))]
13013   ""
13014   "ix86_expand_branch (LEU, operands[0]); DONE;")
13016 (define_expand "bunordered"
13017   [(set (pc)
13018         (if_then_else (match_dup 1)
13019                       (label_ref (match_operand 0 "" ""))
13020                       (pc)))]
13021   "TARGET_80387 || TARGET_SSE_MATH"
13022   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13024 (define_expand "bordered"
13025   [(set (pc)
13026         (if_then_else (match_dup 1)
13027                       (label_ref (match_operand 0 "" ""))
13028                       (pc)))]
13029   "TARGET_80387 || TARGET_SSE_MATH"
13030   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13032 (define_expand "buneq"
13033   [(set (pc)
13034         (if_then_else (match_dup 1)
13035                       (label_ref (match_operand 0 "" ""))
13036                       (pc)))]
13037   "TARGET_80387 || TARGET_SSE_MATH"
13038   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13040 (define_expand "bunge"
13041   [(set (pc)
13042         (if_then_else (match_dup 1)
13043                       (label_ref (match_operand 0 "" ""))
13044                       (pc)))]
13045   "TARGET_80387 || TARGET_SSE_MATH"
13046   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13048 (define_expand "bungt"
13049   [(set (pc)
13050         (if_then_else (match_dup 1)
13051                       (label_ref (match_operand 0 "" ""))
13052                       (pc)))]
13053   "TARGET_80387 || TARGET_SSE_MATH"
13054   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13056 (define_expand "bunle"
13057   [(set (pc)
13058         (if_then_else (match_dup 1)
13059                       (label_ref (match_operand 0 "" ""))
13060                       (pc)))]
13061   "TARGET_80387 || TARGET_SSE_MATH"
13062   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13064 (define_expand "bunlt"
13065   [(set (pc)
13066         (if_then_else (match_dup 1)
13067                       (label_ref (match_operand 0 "" ""))
13068                       (pc)))]
13069   "TARGET_80387 || TARGET_SSE_MATH"
13070   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13072 (define_expand "bltgt"
13073   [(set (pc)
13074         (if_then_else (match_dup 1)
13075                       (label_ref (match_operand 0 "" ""))
13076                       (pc)))]
13077   "TARGET_80387 || TARGET_SSE_MATH"
13078   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13080 (define_insn "*jcc_1"
13081   [(set (pc)
13082         (if_then_else (match_operator 1 "ix86_comparison_operator"
13083                                       [(reg FLAGS_REG) (const_int 0)])
13084                       (label_ref (match_operand 0 "" ""))
13085                       (pc)))]
13086   ""
13087   "%+j%C1\t%l0"
13088   [(set_attr "type" "ibr")
13089    (set_attr "modrm" "0")
13090    (set (attr "length")
13091            (if_then_else (and (ge (minus (match_dup 0) (pc))
13092                                   (const_int -126))
13093                               (lt (minus (match_dup 0) (pc))
13094                                   (const_int 128)))
13095              (const_int 2)
13096              (const_int 6)))])
13098 (define_insn "*jcc_2"
13099   [(set (pc)
13100         (if_then_else (match_operator 1 "ix86_comparison_operator"
13101                                       [(reg FLAGS_REG) (const_int 0)])
13102                       (pc)
13103                       (label_ref (match_operand 0 "" ""))))]
13104   ""
13105   "%+j%c1\t%l0"
13106   [(set_attr "type" "ibr")
13107    (set_attr "modrm" "0")
13108    (set (attr "length")
13109            (if_then_else (and (ge (minus (match_dup 0) (pc))
13110                                   (const_int -126))
13111                               (lt (minus (match_dup 0) (pc))
13112                                   (const_int 128)))
13113              (const_int 2)
13114              (const_int 6)))])
13116 ;; In general it is not safe to assume too much about CCmode registers,
13117 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13118 ;; conditions this is safe on x86, so help combine not create
13120 ;;      seta    %al
13121 ;;      testb   %al, %al
13122 ;;      je      Lfoo
13124 (define_split 
13125   [(set (pc)
13126         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13127                                       [(reg FLAGS_REG) (const_int 0)])
13128                           (const_int 0))
13129                       (label_ref (match_operand 1 "" ""))
13130                       (pc)))]
13131   ""
13132   [(set (pc)
13133         (if_then_else (match_dup 0)
13134                       (label_ref (match_dup 1))
13135                       (pc)))]
13137   PUT_MODE (operands[0], VOIDmode);
13139   
13140 (define_split 
13141   [(set (pc)
13142         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13143                                       [(reg FLAGS_REG) (const_int 0)])
13144                           (const_int 0))
13145                       (label_ref (match_operand 1 "" ""))
13146                       (pc)))]
13147   ""
13148   [(set (pc)
13149         (if_then_else (match_dup 0)
13150                       (label_ref (match_dup 1))
13151                       (pc)))]
13153   rtx new_op0 = copy_rtx (operands[0]);
13154   operands[0] = new_op0;
13155   PUT_MODE (new_op0, VOIDmode);
13156   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13157                                              GET_MODE (XEXP (new_op0, 0))));
13159   /* Make sure that (a) the CCmode we have for the flags is strong
13160      enough for the reversed compare or (b) we have a valid FP compare.  */
13161   if (! ix86_comparison_operator (new_op0, VOIDmode))
13162     FAIL;
13165 ;; Define combination compare-and-branch fp compare instructions to use
13166 ;; during early optimization.  Splitting the operation apart early makes
13167 ;; for bad code when we want to reverse the operation.
13169 (define_insn "*fp_jcc_1_mixed"
13170   [(set (pc)
13171         (if_then_else (match_operator 0 "comparison_operator"
13172                         [(match_operand 1 "register_operand" "f#x,x#f")
13173                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13174           (label_ref (match_operand 3 "" ""))
13175           (pc)))
13176    (clobber (reg:CCFP FPSR_REG))
13177    (clobber (reg:CCFP FLAGS_REG))]
13178   "TARGET_MIX_SSE_I387
13179    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13184 (define_insn "*fp_jcc_1_sse"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "x")
13188                          (match_operand 2 "nonimmediate_operand" "xm")])
13189           (label_ref (match_operand 3 "" ""))
13190           (pc)))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))]
13193   "TARGET_SSE_MATH
13194    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13195    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13196    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13197   "#")
13199 (define_insn "*fp_jcc_1_387"
13200   [(set (pc)
13201         (if_then_else (match_operator 0 "comparison_operator"
13202                         [(match_operand 1 "register_operand" "f")
13203                          (match_operand 2 "register_operand" "f")])
13204           (label_ref (match_operand 3 "" ""))
13205           (pc)))
13206    (clobber (reg:CCFP FPSR_REG))
13207    (clobber (reg:CCFP FLAGS_REG))]
13208   "TARGET_CMOVE && TARGET_80387
13209    && FLOAT_MODE_P (GET_MODE (operands[1]))
13210    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13211    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13212   "#")
13214 (define_insn "*fp_jcc_2_mixed"
13215   [(set (pc)
13216         (if_then_else (match_operator 0 "comparison_operator"
13217                         [(match_operand 1 "register_operand" "f#x,x#f")
13218                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13219           (pc)
13220           (label_ref (match_operand 3 "" ""))))
13221    (clobber (reg:CCFP FPSR_REG))
13222    (clobber (reg:CCFP FLAGS_REG))]
13223   "TARGET_MIX_SSE_I387
13224    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13225    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13226    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227   "#")
13229 (define_insn "*fp_jcc_2_sse"
13230   [(set (pc)
13231         (if_then_else (match_operator 0 "comparison_operator"
13232                         [(match_operand 1 "register_operand" "x")
13233                          (match_operand 2 "nonimmediate_operand" "xm")])
13234           (pc)
13235           (label_ref (match_operand 3 "" ""))))
13236    (clobber (reg:CCFP FPSR_REG))
13237    (clobber (reg:CCFP FLAGS_REG))]
13238   "TARGET_SSE_MATH
13239    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13240    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13241    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13242   "#")
13244 (define_insn "*fp_jcc_2_387"
13245   [(set (pc)
13246         (if_then_else (match_operator 0 "comparison_operator"
13247                         [(match_operand 1 "register_operand" "f")
13248                          (match_operand 2 "register_operand" "f")])
13249           (pc)
13250           (label_ref (match_operand 3 "" ""))))
13251    (clobber (reg:CCFP FPSR_REG))
13252    (clobber (reg:CCFP FLAGS_REG))]
13253   "TARGET_CMOVE && TARGET_80387
13254    && FLOAT_MODE_P (GET_MODE (operands[1]))
13255    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13256    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13257   "#")
13259 (define_insn "*fp_jcc_3_387"
13260   [(set (pc)
13261         (if_then_else (match_operator 0 "comparison_operator"
13262                         [(match_operand 1 "register_operand" "f")
13263                          (match_operand 2 "nonimmediate_operand" "fm")])
13264           (label_ref (match_operand 3 "" ""))
13265           (pc)))
13266    (clobber (reg:CCFP FPSR_REG))
13267    (clobber (reg:CCFP FLAGS_REG))
13268    (clobber (match_scratch:HI 4 "=a"))]
13269   "TARGET_80387
13270    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13271    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13272    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13273    && SELECT_CC_MODE (GET_CODE (operands[0]),
13274                       operands[1], operands[2]) == CCFPmode
13275    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13276   "#")
13278 (define_insn "*fp_jcc_4_387"
13279   [(set (pc)
13280         (if_then_else (match_operator 0 "comparison_operator"
13281                         [(match_operand 1 "register_operand" "f")
13282                          (match_operand 2 "nonimmediate_operand" "fm")])
13283           (pc)
13284           (label_ref (match_operand 3 "" ""))))
13285    (clobber (reg:CCFP FPSR_REG))
13286    (clobber (reg:CCFP FLAGS_REG))
13287    (clobber (match_scratch:HI 4 "=a"))]
13288   "TARGET_80387
13289    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13290    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13291    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13292    && SELECT_CC_MODE (GET_CODE (operands[0]),
13293                       operands[1], operands[2]) == CCFPmode
13294    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295   "#")
13297 (define_insn "*fp_jcc_5_387"
13298   [(set (pc)
13299         (if_then_else (match_operator 0 "comparison_operator"
13300                         [(match_operand 1 "register_operand" "f")
13301                          (match_operand 2 "register_operand" "f")])
13302           (label_ref (match_operand 3 "" ""))
13303           (pc)))
13304    (clobber (reg:CCFP FPSR_REG))
13305    (clobber (reg:CCFP FLAGS_REG))
13306    (clobber (match_scratch:HI 4 "=a"))]
13307   "TARGET_80387
13308    && FLOAT_MODE_P (GET_MODE (operands[1]))
13309    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13310    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13311   "#")
13313 (define_insn "*fp_jcc_6_387"
13314   [(set (pc)
13315         (if_then_else (match_operator 0 "comparison_operator"
13316                         [(match_operand 1 "register_operand" "f")
13317                          (match_operand 2 "register_operand" "f")])
13318           (pc)
13319           (label_ref (match_operand 3 "" ""))))
13320    (clobber (reg:CCFP FPSR_REG))
13321    (clobber (reg:CCFP FLAGS_REG))
13322    (clobber (match_scratch:HI 4 "=a"))]
13323   "TARGET_80387
13324    && FLOAT_MODE_P (GET_MODE (operands[1]))
13325    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13326    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13327   "#")
13329 (define_insn "*fp_jcc_7_387"
13330   [(set (pc)
13331         (if_then_else (match_operator 0 "comparison_operator"
13332                         [(match_operand 1 "register_operand" "f")
13333                          (match_operand 2 "const0_operand" "X")])
13334           (label_ref (match_operand 3 "" ""))
13335           (pc)))
13336    (clobber (reg:CCFP FPSR_REG))
13337    (clobber (reg:CCFP FLAGS_REG))
13338    (clobber (match_scratch:HI 4 "=a"))]
13339   "TARGET_80387
13340    && FLOAT_MODE_P (GET_MODE (operands[1]))
13341    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13342    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13343    && SELECT_CC_MODE (GET_CODE (operands[0]),
13344                       operands[1], operands[2]) == CCFPmode
13345    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13346   "#")
13348 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13349 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13350 ;; with a precedence over other operators and is always put in the first
13351 ;; place. Swap condition and operands to match ficom instruction.
13353 (define_insn "*fp_jcc_8<mode>_387"
13354   [(set (pc)
13355         (if_then_else (match_operator 0 "comparison_operator"
13356                         [(match_operator 1 "float_operator"
13357                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13358                            (match_operand 3 "register_operand" "f,f")])
13359           (label_ref (match_operand 4 "" ""))
13360           (pc)))
13361    (clobber (reg:CCFP FPSR_REG))
13362    (clobber (reg:CCFP FLAGS_REG))
13363    (clobber (match_scratch:HI 5 "=a,a"))]
13364   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13365    && FLOAT_MODE_P (GET_MODE (operands[3]))
13366    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13367    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13368    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13369    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13370   "#")
13372 (define_split
13373   [(set (pc)
13374         (if_then_else (match_operator 0 "comparison_operator"
13375                         [(match_operand 1 "register_operand" "")
13376                          (match_operand 2 "nonimmediate_operand" "")])
13377           (match_operand 3 "" "")
13378           (match_operand 4 "" "")))
13379    (clobber (reg:CCFP FPSR_REG))
13380    (clobber (reg:CCFP FLAGS_REG))]
13381   "reload_completed"
13382   [(const_int 0)]
13384   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13385                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13386   DONE;
13389 (define_split
13390   [(set (pc)
13391         (if_then_else (match_operator 0 "comparison_operator"
13392                         [(match_operand 1 "register_operand" "")
13393                          (match_operand 2 "general_operand" "")])
13394           (match_operand 3 "" "")
13395           (match_operand 4 "" "")))
13396    (clobber (reg:CCFP FPSR_REG))
13397    (clobber (reg:CCFP FLAGS_REG))
13398    (clobber (match_scratch:HI 5 "=a"))]
13399   "reload_completed"
13400   [(const_int 0)]
13402   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13403                         operands[3], operands[4], operands[5], NULL_RTX);
13404   DONE;
13407 (define_split
13408   [(set (pc)
13409         (if_then_else (match_operator 0 "comparison_operator"
13410                         [(match_operator 1 "float_operator"
13411                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13412                            (match_operand 3 "register_operand" "")])
13413           (match_operand 4 "" "")
13414           (match_operand 5 "" "")))
13415    (clobber (reg:CCFP FPSR_REG))
13416    (clobber (reg:CCFP FLAGS_REG))
13417    (clobber (match_scratch:HI 6 "=a"))]
13418   "reload_completed"
13419   [(const_int 0)]
13421   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13422   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13423                         operands[3], operands[7],
13424                         operands[4], operands[5], operands[6], NULL_RTX);
13425   DONE;
13428 ;; %%% Kill this when reload knows how to do it.
13429 (define_split
13430   [(set (pc)
13431         (if_then_else (match_operator 0 "comparison_operator"
13432                         [(match_operator 1 "float_operator"
13433                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13434                            (match_operand 3 "register_operand" "")])
13435           (match_operand 4 "" "")
13436           (match_operand 5 "" "")))
13437    (clobber (reg:CCFP FPSR_REG))
13438    (clobber (reg:CCFP FLAGS_REG))
13439    (clobber (match_scratch:HI 6 "=a"))]
13440   "reload_completed"
13441   [(const_int 0)]
13443   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13444   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13445   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13446                         operands[3], operands[7],
13447                         operands[4], operands[5], operands[6], operands[2]);
13448   DONE;
13451 ;; Unconditional and other jump instructions
13453 (define_insn "jump"
13454   [(set (pc)
13455         (label_ref (match_operand 0 "" "")))]
13456   ""
13457   "jmp\t%l0"
13458   [(set_attr "type" "ibr")
13459    (set (attr "length")
13460            (if_then_else (and (ge (minus (match_dup 0) (pc))
13461                                   (const_int -126))
13462                               (lt (minus (match_dup 0) (pc))
13463                                   (const_int 128)))
13464              (const_int 2)
13465              (const_int 5)))
13466    (set_attr "modrm" "0")])
13468 (define_expand "indirect_jump"
13469   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13470   ""
13471   "")
13473 (define_insn "*indirect_jump"
13474   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13475   "!TARGET_64BIT"
13476   "jmp\t%A0"
13477   [(set_attr "type" "ibr")
13478    (set_attr "length_immediate" "0")])
13480 (define_insn "*indirect_jump_rtx64"
13481   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13482   "TARGET_64BIT"
13483   "jmp\t%A0"
13484   [(set_attr "type" "ibr")
13485    (set_attr "length_immediate" "0")])
13487 (define_expand "tablejump"
13488   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13489               (use (label_ref (match_operand 1 "" "")))])]
13490   ""
13492   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13493      relative.  Convert the relative address to an absolute address.  */
13494   if (flag_pic)
13495     {
13496       rtx op0, op1;
13497       enum rtx_code code;
13499       if (TARGET_64BIT)
13500         {
13501           code = PLUS;
13502           op0 = operands[0];
13503           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13504         }
13505       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13506         {
13507           code = PLUS;
13508           op0 = operands[0];
13509           op1 = pic_offset_table_rtx;
13510         }
13511       else
13512         {
13513           code = MINUS;
13514           op0 = pic_offset_table_rtx;
13515           op1 = operands[0];
13516         }
13518       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13519                                          OPTAB_DIRECT);
13520     }
13523 (define_insn "*tablejump_1"
13524   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13525    (use (label_ref (match_operand 1 "" "")))]
13526   "!TARGET_64BIT"
13527   "jmp\t%A0"
13528   [(set_attr "type" "ibr")
13529    (set_attr "length_immediate" "0")])
13531 (define_insn "*tablejump_1_rtx64"
13532   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13533    (use (label_ref (match_operand 1 "" "")))]
13534   "TARGET_64BIT"
13535   "jmp\t%A0"
13536   [(set_attr "type" "ibr")
13537    (set_attr "length_immediate" "0")])
13539 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13541 (define_peephole2
13542   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13543    (set (match_operand:QI 1 "register_operand" "")
13544         (match_operator:QI 2 "ix86_comparison_operator"
13545           [(reg FLAGS_REG) (const_int 0)]))
13546    (set (match_operand 3 "q_regs_operand" "")
13547         (zero_extend (match_dup 1)))]
13548   "(peep2_reg_dead_p (3, operands[1])
13549     || operands_match_p (operands[1], operands[3]))
13550    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13551   [(set (match_dup 4) (match_dup 0))
13552    (set (strict_low_part (match_dup 5))
13553         (match_dup 2))]
13555   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13556   operands[5] = gen_lowpart (QImode, operands[3]);
13557   ix86_expand_clear (operands[3]);
13560 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13562 (define_peephole2
13563   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13564    (set (match_operand:QI 1 "register_operand" "")
13565         (match_operator:QI 2 "ix86_comparison_operator"
13566           [(reg FLAGS_REG) (const_int 0)]))
13567    (parallel [(set (match_operand 3 "q_regs_operand" "")
13568                    (zero_extend (match_dup 1)))
13569               (clobber (reg:CC FLAGS_REG))])]
13570   "(peep2_reg_dead_p (3, operands[1])
13571     || operands_match_p (operands[1], operands[3]))
13572    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13573   [(set (match_dup 4) (match_dup 0))
13574    (set (strict_low_part (match_dup 5))
13575         (match_dup 2))]
13577   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13578   operands[5] = gen_lowpart (QImode, operands[3]);
13579   ix86_expand_clear (operands[3]);
13582 ;; Call instructions.
13584 ;; The predicates normally associated with named expanders are not properly
13585 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13586 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13588 ;; Call subroutine returning no value.
13590 (define_expand "call_pop"
13591   [(parallel [(call (match_operand:QI 0 "" "")
13592                     (match_operand:SI 1 "" ""))
13593               (set (reg:SI SP_REG)
13594                    (plus:SI (reg:SI SP_REG)
13595                             (match_operand:SI 3 "" "")))])]
13596   "!TARGET_64BIT"
13598   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13599   DONE;
13602 (define_insn "*call_pop_0"
13603   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13604          (match_operand:SI 1 "" ""))
13605    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13606                             (match_operand:SI 2 "immediate_operand" "")))]
13607   "!TARGET_64BIT"
13609   if (SIBLING_CALL_P (insn))
13610     return "jmp\t%P0";
13611   else
13612     return "call\t%P0";
13614   [(set_attr "type" "call")])
13615   
13616 (define_insn "*call_pop_1"
13617   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13618          (match_operand:SI 1 "" ""))
13619    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13620                             (match_operand:SI 2 "immediate_operand" "i")))]
13621   "!TARGET_64BIT"
13623   if (constant_call_address_operand (operands[0], Pmode))
13624     {
13625       if (SIBLING_CALL_P (insn))
13626         return "jmp\t%P0";
13627       else
13628         return "call\t%P0";
13629     }
13630   if (SIBLING_CALL_P (insn))
13631     return "jmp\t%A0";
13632   else
13633     return "call\t%A0";
13635   [(set_attr "type" "call")])
13637 (define_expand "call"
13638   [(call (match_operand:QI 0 "" "")
13639          (match_operand 1 "" ""))
13640    (use (match_operand 2 "" ""))]
13641   ""
13643   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13644   DONE;
13647 (define_expand "sibcall"
13648   [(call (match_operand:QI 0 "" "")
13649          (match_operand 1 "" ""))
13650    (use (match_operand 2 "" ""))]
13651   ""
13653   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13654   DONE;
13657 (define_insn "*call_0"
13658   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13659          (match_operand 1 "" ""))]
13660   ""
13662   if (SIBLING_CALL_P (insn))
13663     return "jmp\t%P0";
13664   else
13665     return "call\t%P0";
13667   [(set_attr "type" "call")])
13669 (define_insn "*call_1"
13670   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13671          (match_operand 1 "" ""))]
13672   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13674   if (constant_call_address_operand (operands[0], Pmode))
13675     return "call\t%P0";
13676   return "call\t%A0";
13678   [(set_attr "type" "call")])
13680 (define_insn "*sibcall_1"
13681   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13682          (match_operand 1 "" ""))]
13683   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13685   if (constant_call_address_operand (operands[0], Pmode))
13686     return "jmp\t%P0";
13687   return "jmp\t%A0";
13689   [(set_attr "type" "call")])
13691 (define_insn "*call_1_rex64"
13692   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13693          (match_operand 1 "" ""))]
13694   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13696   if (constant_call_address_operand (operands[0], Pmode))
13697     return "call\t%P0";
13698   return "call\t%A0";
13700   [(set_attr "type" "call")])
13702 (define_insn "*sibcall_1_rex64"
13703   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13704          (match_operand 1 "" ""))]
13705   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13706   "jmp\t%P0"
13707   [(set_attr "type" "call")])
13709 (define_insn "*sibcall_1_rex64_v"
13710   [(call (mem:QI (reg:DI 40))
13711          (match_operand 0 "" ""))]
13712   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13713   "jmp\t*%%r11"
13714   [(set_attr "type" "call")])
13717 ;; Call subroutine, returning value in operand 0
13719 (define_expand "call_value_pop"
13720   [(parallel [(set (match_operand 0 "" "")
13721                    (call (match_operand:QI 1 "" "")
13722                          (match_operand:SI 2 "" "")))
13723               (set (reg:SI SP_REG)
13724                    (plus:SI (reg:SI SP_REG)
13725                             (match_operand:SI 4 "" "")))])]
13726   "!TARGET_64BIT"
13728   ix86_expand_call (operands[0], operands[1], operands[2],
13729                     operands[3], operands[4], 0);
13730   DONE;
13733 (define_expand "call_value"
13734   [(set (match_operand 0 "" "")
13735         (call (match_operand:QI 1 "" "")
13736               (match_operand:SI 2 "" "")))
13737    (use (match_operand:SI 3 "" ""))]
13738   ;; Operand 2 not used on the i386.
13739   ""
13741   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13742   DONE;
13745 (define_expand "sibcall_value"
13746   [(set (match_operand 0 "" "")
13747         (call (match_operand:QI 1 "" "")
13748               (match_operand:SI 2 "" "")))
13749    (use (match_operand:SI 3 "" ""))]
13750   ;; Operand 2 not used on the i386.
13751   ""
13753   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13754   DONE;
13757 ;; Call subroutine returning any type.
13759 (define_expand "untyped_call"
13760   [(parallel [(call (match_operand 0 "" "")
13761                     (const_int 0))
13762               (match_operand 1 "" "")
13763               (match_operand 2 "" "")])]
13764   ""
13766   int i;
13768   /* In order to give reg-stack an easier job in validating two
13769      coprocessor registers as containing a possible return value,
13770      simply pretend the untyped call returns a complex long double
13771      value.  */
13773   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13774                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13775                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13776                     NULL, 0);
13778   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13779     {
13780       rtx set = XVECEXP (operands[2], 0, i);
13781       emit_move_insn (SET_DEST (set), SET_SRC (set));
13782     }
13784   /* The optimizer does not know that the call sets the function value
13785      registers we stored in the result block.  We avoid problems by
13786      claiming that all hard registers are used and clobbered at this
13787      point.  */
13788   emit_insn (gen_blockage (const0_rtx));
13790   DONE;
13793 ;; Prologue and epilogue instructions
13795 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13796 ;; all of memory.  This blocks insns from being moved across this point.
13798 (define_insn "blockage"
13799   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13800   ""
13801   ""
13802   [(set_attr "length" "0")])
13804 ;; Insn emitted into the body of a function to return from a function.
13805 ;; This is only done if the function's epilogue is known to be simple.
13806 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13808 (define_expand "return"
13809   [(return)]
13810   "ix86_can_use_return_insn_p ()"
13812   if (current_function_pops_args)
13813     {
13814       rtx popc = GEN_INT (current_function_pops_args);
13815       emit_jump_insn (gen_return_pop_internal (popc));
13816       DONE;
13817     }
13820 (define_insn "return_internal"
13821   [(return)]
13822   "reload_completed"
13823   "ret"
13824   [(set_attr "length" "1")
13825    (set_attr "length_immediate" "0")
13826    (set_attr "modrm" "0")])
13828 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13829 ;; instruction Athlon and K8 have.
13831 (define_insn "return_internal_long"
13832   [(return)
13833    (unspec [(const_int 0)] UNSPEC_REP)]
13834   "reload_completed"
13835   "rep {;} ret"
13836   [(set_attr "length" "1")
13837    (set_attr "length_immediate" "0")
13838    (set_attr "prefix_rep" "1")
13839    (set_attr "modrm" "0")])
13841 (define_insn "return_pop_internal"
13842   [(return)
13843    (use (match_operand:SI 0 "const_int_operand" ""))]
13844   "reload_completed"
13845   "ret\t%0"
13846   [(set_attr "length" "3")
13847    (set_attr "length_immediate" "2")
13848    (set_attr "modrm" "0")])
13850 (define_insn "return_indirect_internal"
13851   [(return)
13852    (use (match_operand:SI 0 "register_operand" "r"))]
13853   "reload_completed"
13854   "jmp\t%A0"
13855   [(set_attr "type" "ibr")
13856    (set_attr "length_immediate" "0")])
13858 (define_insn "nop"
13859   [(const_int 0)]
13860   ""
13861   "nop"
13862   [(set_attr "length" "1")
13863    (set_attr "length_immediate" "0")
13864    (set_attr "modrm" "0")])
13866 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13867 ;; branch prediction penalty for the third jump in a 16-byte
13868 ;; block on K8.
13870 (define_insn "align"
13871   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13872   ""
13874 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13875   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13876 #else
13877   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13878      The align insn is used to avoid 3 jump instructions in the row to improve
13879      branch prediction and the benefits hardly outweight the cost of extra 8
13880      nops on the average inserted by full alignment pseudo operation.  */
13881 #endif
13882   return "";
13884   [(set_attr "length" "16")])
13886 (define_expand "prologue"
13887   [(const_int 1)]
13888   ""
13889   "ix86_expand_prologue (); DONE;")
13891 (define_insn "set_got"
13892   [(set (match_operand:SI 0 "register_operand" "=r")
13893         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13894    (clobber (reg:CC FLAGS_REG))]
13895   "!TARGET_64BIT"
13896   { return output_set_got (operands[0], NULL_RTX); }
13897   [(set_attr "type" "multi")
13898    (set_attr "length" "12")])
13900 (define_insn "set_got_labelled"
13901   [(set (match_operand:SI 0 "register_operand" "=r")
13902         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13903          UNSPEC_SET_GOT))
13904    (clobber (reg:CC FLAGS_REG))]
13905   "!TARGET_64BIT"
13906   { return output_set_got (operands[0], operands[1]); }
13907   [(set_attr "type" "multi")
13908    (set_attr "length" "12")])
13910 (define_insn "set_got_rex64"
13911   [(set (match_operand:DI 0 "register_operand" "=r")
13912         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13913   "TARGET_64BIT"
13914   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13915   [(set_attr "type" "lea")
13916    (set_attr "length" "6")])
13918 (define_expand "epilogue"
13919   [(const_int 1)]
13920   ""
13921   "ix86_expand_epilogue (1); DONE;")
13923 (define_expand "sibcall_epilogue"
13924   [(const_int 1)]
13925   ""
13926   "ix86_expand_epilogue (0); DONE;")
13928 (define_expand "eh_return"
13929   [(use (match_operand 0 "register_operand" ""))]
13930   ""
13932   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13934   /* Tricky bit: we write the address of the handler to which we will
13935      be returning into someone else's stack frame, one word below the
13936      stack address we wish to restore.  */
13937   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13938   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13939   tmp = gen_rtx_MEM (Pmode, tmp);
13940   emit_move_insn (tmp, ra);
13942   if (Pmode == SImode)
13943     emit_jump_insn (gen_eh_return_si (sa));
13944   else
13945     emit_jump_insn (gen_eh_return_di (sa));
13946   emit_barrier ();
13947   DONE;
13950 (define_insn_and_split "eh_return_si"
13951   [(set (pc) 
13952         (unspec [(match_operand:SI 0 "register_operand" "c")]
13953                  UNSPEC_EH_RETURN))]
13954   "!TARGET_64BIT"
13955   "#"
13956   "reload_completed"
13957   [(const_int 1)]
13958   "ix86_expand_epilogue (2); DONE;")
13960 (define_insn_and_split "eh_return_di"
13961   [(set (pc) 
13962         (unspec [(match_operand:DI 0 "register_operand" "c")]
13963                  UNSPEC_EH_RETURN))]
13964   "TARGET_64BIT"
13965   "#"
13966   "reload_completed"
13967   [(const_int 1)]
13968   "ix86_expand_epilogue (2); DONE;")
13970 (define_insn "leave"
13971   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13972    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13973    (clobber (mem:BLK (scratch)))]
13974   "!TARGET_64BIT"
13975   "leave"
13976   [(set_attr "type" "leave")])
13978 (define_insn "leave_rex64"
13979   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13980    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13981    (clobber (mem:BLK (scratch)))]
13982   "TARGET_64BIT"
13983   "leave"
13984   [(set_attr "type" "leave")])
13986 (define_expand "ffssi2"
13987   [(parallel
13988      [(set (match_operand:SI 0 "register_operand" "") 
13989            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13990       (clobber (match_scratch:SI 2 ""))
13991       (clobber (reg:CC FLAGS_REG))])]
13992   ""
13993   "")
13995 (define_insn_and_split "*ffs_cmove"
13996   [(set (match_operand:SI 0 "register_operand" "=r") 
13997         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13998    (clobber (match_scratch:SI 2 "=&r"))
13999    (clobber (reg:CC FLAGS_REG))]
14000   "TARGET_CMOVE"
14001   "#"
14002   "&& reload_completed"
14003   [(set (match_dup 2) (const_int -1))
14004    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14005               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14006    (set (match_dup 0) (if_then_else:SI
14007                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14008                         (match_dup 2)
14009                         (match_dup 0)))
14010    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14011               (clobber (reg:CC FLAGS_REG))])]
14012   "")
14014 (define_insn_and_split "*ffs_no_cmove"
14015   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14016         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14017    (clobber (match_scratch:SI 2 "=&q"))
14018    (clobber (reg:CC FLAGS_REG))]
14019   ""
14020   "#"
14021   "reload_completed"
14022   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14023               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14024    (set (strict_low_part (match_dup 3))
14025         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14026    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14027               (clobber (reg:CC FLAGS_REG))])
14028    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14029               (clobber (reg:CC FLAGS_REG))])
14030    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14031               (clobber (reg:CC FLAGS_REG))])]
14033   operands[3] = gen_lowpart (QImode, operands[2]);
14034   ix86_expand_clear (operands[2]);
14037 (define_insn "*ffssi_1"
14038   [(set (reg:CCZ FLAGS_REG)
14039         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14040                      (const_int 0)))
14041    (set (match_operand:SI 0 "register_operand" "=r")
14042         (ctz:SI (match_dup 1)))]
14043   ""
14044   "bsf{l}\t{%1, %0|%0, %1}"
14045   [(set_attr "prefix_0f" "1")])
14047 (define_expand "ffsdi2"
14048   [(parallel
14049      [(set (match_operand:DI 0 "register_operand" "") 
14050            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14051       (clobber (match_scratch:DI 2 ""))
14052       (clobber (reg:CC FLAGS_REG))])]
14053   "TARGET_64BIT && TARGET_CMOVE"
14054   "")
14056 (define_insn_and_split "*ffs_rex64"
14057   [(set (match_operand:DI 0 "register_operand" "=r") 
14058         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14059    (clobber (match_scratch:DI 2 "=&r"))
14060    (clobber (reg:CC FLAGS_REG))]
14061   "TARGET_64BIT && TARGET_CMOVE"
14062   "#"
14063   "&& reload_completed"
14064   [(set (match_dup 2) (const_int -1))
14065    (parallel [(set (reg:CCZ FLAGS_REG)
14066                    (compare:CCZ (match_dup 1) (const_int 0)))
14067               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14068    (set (match_dup 0) (if_then_else:DI
14069                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14070                         (match_dup 2)
14071                         (match_dup 0)))
14072    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14073               (clobber (reg:CC FLAGS_REG))])]
14074   "")
14076 (define_insn "*ffsdi_1"
14077   [(set (reg:CCZ FLAGS_REG)
14078         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14079                      (const_int 0)))
14080    (set (match_operand:DI 0 "register_operand" "=r")
14081         (ctz:DI (match_dup 1)))]
14082   "TARGET_64BIT"
14083   "bsf{q}\t{%1, %0|%0, %1}"
14084   [(set_attr "prefix_0f" "1")])
14086 (define_insn "ctzsi2"
14087   [(set (match_operand:SI 0 "register_operand" "=r")
14088         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14089    (clobber (reg:CC FLAGS_REG))]
14090   ""
14091   "bsf{l}\t{%1, %0|%0, %1}"
14092   [(set_attr "prefix_0f" "1")])
14094 (define_insn "ctzdi2"
14095   [(set (match_operand:DI 0 "register_operand" "=r")
14096         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14097    (clobber (reg:CC FLAGS_REG))]
14098   "TARGET_64BIT"
14099   "bsf{q}\t{%1, %0|%0, %1}"
14100   [(set_attr "prefix_0f" "1")])
14102 (define_expand "clzsi2"
14103   [(parallel
14104      [(set (match_operand:SI 0 "register_operand" "")
14105            (minus:SI (const_int 31)
14106                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107       (clobber (reg:CC FLAGS_REG))])
14108    (parallel
14109      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110       (clobber (reg:CC FLAGS_REG))])]
14111   ""
14112   "")
14114 (define_insn "*bsr"
14115   [(set (match_operand:SI 0 "register_operand" "=r")
14116         (minus:SI (const_int 31)
14117                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118    (clobber (reg:CC FLAGS_REG))]
14119   ""
14120   "bsr{l}\t{%1, %0|%0, %1}"
14121   [(set_attr "prefix_0f" "1")])
14123 (define_expand "clzdi2"
14124   [(parallel
14125      [(set (match_operand:DI 0 "register_operand" "")
14126            (minus:DI (const_int 63)
14127                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14128       (clobber (reg:CC FLAGS_REG))])
14129    (parallel
14130      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14131       (clobber (reg:CC FLAGS_REG))])]
14132   "TARGET_64BIT"
14133   "")
14135 (define_insn "*bsr_rex64"
14136   [(set (match_operand:DI 0 "register_operand" "=r")
14137         (minus:DI (const_int 63)
14138                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14139    (clobber (reg:CC FLAGS_REG))]
14140   "TARGET_64BIT"
14141   "bsr{q}\t{%1, %0|%0, %1}"
14142   [(set_attr "prefix_0f" "1")])
14144 ;; Thread-local storage patterns for ELF.
14146 ;; Note that these code sequences must appear exactly as shown
14147 ;; in order to allow linker relaxation.
14149 (define_insn "*tls_global_dynamic_32_gnu"
14150   [(set (match_operand:SI 0 "register_operand" "=a")
14151         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14152                     (match_operand:SI 2 "tls_symbolic_operand" "")
14153                     (match_operand:SI 3 "call_insn_operand" "")]
14154                     UNSPEC_TLS_GD))
14155    (clobber (match_scratch:SI 4 "=d"))
14156    (clobber (match_scratch:SI 5 "=c"))
14157    (clobber (reg:CC FLAGS_REG))]
14158   "!TARGET_64BIT && TARGET_GNU_TLS"
14159   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14160   [(set_attr "type" "multi")
14161    (set_attr "length" "12")])
14163 (define_insn "*tls_global_dynamic_32_sun"
14164   [(set (match_operand:SI 0 "register_operand" "=a")
14165         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14166                     (match_operand:SI 2 "tls_symbolic_operand" "")
14167                     (match_operand:SI 3 "call_insn_operand" "")]
14168                     UNSPEC_TLS_GD))
14169    (clobber (match_scratch:SI 4 "=d"))
14170    (clobber (match_scratch:SI 5 "=c"))
14171    (clobber (reg:CC FLAGS_REG))]
14172   "!TARGET_64BIT && TARGET_SUN_TLS"
14173   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14174         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14175   [(set_attr "type" "multi")
14176    (set_attr "length" "14")])
14178 (define_expand "tls_global_dynamic_32"
14179   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14180                    (unspec:SI
14181                     [(match_dup 2)
14182                      (match_operand:SI 1 "tls_symbolic_operand" "")
14183                      (match_dup 3)]
14184                     UNSPEC_TLS_GD))
14185               (clobber (match_scratch:SI 4 ""))
14186               (clobber (match_scratch:SI 5 ""))
14187               (clobber (reg:CC FLAGS_REG))])]
14188   ""
14190   if (flag_pic)
14191     operands[2] = pic_offset_table_rtx;
14192   else
14193     {
14194       operands[2] = gen_reg_rtx (Pmode);
14195       emit_insn (gen_set_got (operands[2]));
14196     }
14197   if (TARGET_GNU2_TLS)
14198     {
14199        emit_insn (gen_tls_dynamic_gnu2_32
14200                   (operands[0], operands[1], operands[2]));
14201        DONE;
14202     }
14203   operands[3] = ix86_tls_get_addr ();
14206 (define_insn "*tls_global_dynamic_64"
14207   [(set (match_operand:DI 0 "register_operand" "=a")
14208         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14209                  (match_operand:DI 3 "" "")))
14210    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14211               UNSPEC_TLS_GD)]
14212   "TARGET_64BIT"
14213   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14214   [(set_attr "type" "multi")
14215    (set_attr "length" "16")])
14217 (define_expand "tls_global_dynamic_64"
14218   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14219                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14220               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14221                          UNSPEC_TLS_GD)])]
14222   ""
14224   if (TARGET_GNU2_TLS)
14225     {
14226        emit_insn (gen_tls_dynamic_gnu2_64
14227                   (operands[0], operands[1]));
14228        DONE;
14229     }
14230   operands[2] = ix86_tls_get_addr ();
14233 (define_insn "*tls_local_dynamic_base_32_gnu"
14234   [(set (match_operand:SI 0 "register_operand" "=a")
14235         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14236                     (match_operand:SI 2 "call_insn_operand" "")]
14237                    UNSPEC_TLS_LD_BASE))
14238    (clobber (match_scratch:SI 3 "=d"))
14239    (clobber (match_scratch:SI 4 "=c"))
14240    (clobber (reg:CC FLAGS_REG))]
14241   "!TARGET_64BIT && TARGET_GNU_TLS"
14242   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14243   [(set_attr "type" "multi")
14244    (set_attr "length" "11")])
14246 (define_insn "*tls_local_dynamic_base_32_sun"
14247   [(set (match_operand:SI 0 "register_operand" "=a")
14248         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14249                     (match_operand:SI 2 "call_insn_operand" "")]
14250                    UNSPEC_TLS_LD_BASE))
14251    (clobber (match_scratch:SI 3 "=d"))
14252    (clobber (match_scratch:SI 4 "=c"))
14253    (clobber (reg:CC FLAGS_REG))]
14254   "!TARGET_64BIT && TARGET_SUN_TLS"
14255   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14256         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14257   [(set_attr "type" "multi")
14258    (set_attr "length" "13")])
14260 (define_expand "tls_local_dynamic_base_32"
14261   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14262                    (unspec:SI [(match_dup 1) (match_dup 2)]
14263                               UNSPEC_TLS_LD_BASE))
14264               (clobber (match_scratch:SI 3 ""))
14265               (clobber (match_scratch:SI 4 ""))
14266               (clobber (reg:CC FLAGS_REG))])]
14267   ""
14269   if (flag_pic)
14270     operands[1] = pic_offset_table_rtx;
14271   else
14272     {
14273       operands[1] = gen_reg_rtx (Pmode);
14274       emit_insn (gen_set_got (operands[1]));
14275     }
14276   if (TARGET_GNU2_TLS)
14277     {
14278        emit_insn (gen_tls_dynamic_gnu2_32
14279                   (operands[0], ix86_tls_module_base (), operands[1]));
14280        DONE;
14281     }
14282   operands[2] = ix86_tls_get_addr ();
14285 (define_insn "*tls_local_dynamic_base_64"
14286   [(set (match_operand:DI 0 "register_operand" "=a")
14287         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14288                  (match_operand:DI 2 "" "")))
14289    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14290   "TARGET_64BIT"
14291   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14292   [(set_attr "type" "multi")
14293    (set_attr "length" "12")])
14295 (define_expand "tls_local_dynamic_base_64"
14296   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14297                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14298               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14299   ""
14301   if (TARGET_GNU2_TLS)
14302     {
14303        emit_insn (gen_tls_dynamic_gnu2_64
14304                   (operands[0], ix86_tls_module_base ()));
14305        DONE;
14306     }
14307   operands[1] = ix86_tls_get_addr ();
14310 ;; Local dynamic of a single variable is a lose.  Show combine how
14311 ;; to convert that back to global dynamic.
14313 (define_insn_and_split "*tls_local_dynamic_32_once"
14314   [(set (match_operand:SI 0 "register_operand" "=a")
14315         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14316                              (match_operand:SI 2 "call_insn_operand" "")]
14317                             UNSPEC_TLS_LD_BASE)
14318                  (const:SI (unspec:SI
14319                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14320                             UNSPEC_DTPOFF))))
14321    (clobber (match_scratch:SI 4 "=d"))
14322    (clobber (match_scratch:SI 5 "=c"))
14323    (clobber (reg:CC FLAGS_REG))]
14324   ""
14325   "#"
14326   ""
14327   [(parallel [(set (match_dup 0)
14328                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14329                               UNSPEC_TLS_GD))
14330               (clobber (match_dup 4))
14331               (clobber (match_dup 5))
14332               (clobber (reg:CC FLAGS_REG))])]
14333   "")
14335 ;; Load and add the thread base pointer from %gs:0.
14337 (define_insn "*load_tp_si"
14338   [(set (match_operand:SI 0 "register_operand" "=r")
14339         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14340   "!TARGET_64BIT"
14341   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14342   [(set_attr "type" "imov")
14343    (set_attr "modrm" "0")
14344    (set_attr "length" "7")
14345    (set_attr "memory" "load")
14346    (set_attr "imm_disp" "false")])
14348 (define_insn "*add_tp_si"
14349   [(set (match_operand:SI 0 "register_operand" "=r")
14350         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14351                  (match_operand:SI 1 "register_operand" "0")))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "!TARGET_64BIT"
14354   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14355   [(set_attr "type" "alu")
14356    (set_attr "modrm" "0")
14357    (set_attr "length" "7")
14358    (set_attr "memory" "load")
14359    (set_attr "imm_disp" "false")])
14361 (define_insn "*load_tp_di"
14362   [(set (match_operand:DI 0 "register_operand" "=r")
14363         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14364   "TARGET_64BIT"
14365   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14366   [(set_attr "type" "imov")
14367    (set_attr "modrm" "0")
14368    (set_attr "length" "7")
14369    (set_attr "memory" "load")
14370    (set_attr "imm_disp" "false")])
14372 (define_insn "*add_tp_di"
14373   [(set (match_operand:DI 0 "register_operand" "=r")
14374         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14375                  (match_operand:DI 1 "register_operand" "0")))
14376    (clobber (reg:CC FLAGS_REG))]
14377   "TARGET_64BIT"
14378   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14379   [(set_attr "type" "alu")
14380    (set_attr "modrm" "0")
14381    (set_attr "length" "7")
14382    (set_attr "memory" "load")
14383    (set_attr "imm_disp" "false")])
14385 ;; GNU2 TLS patterns can be split.
14387 (define_expand "tls_dynamic_gnu2_32"
14388   [(set (match_dup 3)
14389         (plus:SI (match_operand:SI 2 "register_operand" "")
14390                  (const:SI
14391                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14392                              UNSPEC_TLSDESC))))
14393    (parallel
14394     [(set (match_operand:SI 0 "register_operand" "")
14395           (unspec:SI [(match_dup 1) (match_dup 3)
14396                       (match_dup 2) (reg:SI SP_REG)]
14397                       UNSPEC_TLSDESC))
14398      (clobber (reg:CC FLAGS_REG))])]
14399   "!TARGET_64BIT && TARGET_GNU2_TLS"
14401   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14402   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14405 (define_insn "*tls_dynamic_lea_32"
14406   [(set (match_operand:SI 0 "register_operand" "=r")
14407         (plus:SI (match_operand:SI 1 "register_operand" "b")
14408                  (const:SI
14409                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14410                               UNSPEC_TLSDESC))))]
14411   "!TARGET_64BIT && TARGET_GNU2_TLS"
14412   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14413   [(set_attr "type" "lea")
14414    (set_attr "mode" "SI")
14415    (set_attr "length" "6")
14416    (set_attr "length_address" "4")])
14418 (define_insn "*tls_dynamic_call_32"
14419   [(set (match_operand:SI 0 "register_operand" "=a")
14420         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14421                     (match_operand:SI 2 "register_operand" "0")
14422                     ;; we have to make sure %ebx still points to the GOT
14423                     (match_operand:SI 3 "register_operand" "b")
14424                     (reg:SI SP_REG)]
14425                    UNSPEC_TLSDESC))
14426    (clobber (reg:CC FLAGS_REG))]
14427   "!TARGET_64BIT && TARGET_GNU2_TLS"
14428   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14429   [(set_attr "type" "call")
14430    (set_attr "length" "2")
14431    (set_attr "length_address" "0")])
14433 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14434   [(set (match_operand:SI 0 "register_operand" "=&a")
14435         (plus:SI
14436          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14437                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14438                               (match_operand:SI 5 "" "")
14439                               (match_operand:SI 2 "register_operand" "b")
14440                               (reg:SI SP_REG)]
14441                              UNSPEC_TLSDESC))
14442          (const:SI (unspec:SI
14443                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14444                     UNSPEC_DTPOFF))))
14445    (clobber (reg:CC FLAGS_REG))]
14446   "!TARGET_64BIT && TARGET_GNU2_TLS"
14447   "#"
14448   ""
14449   [(parallel
14450     [(set (match_dup 0)
14451           (plus:SI (match_dup 3)
14452                    (match_dup 5)))
14453      (clobber (reg:CC FLAGS_REG))])]
14455   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14456   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14459 (define_expand "tls_dynamic_gnu2_64"
14460   [(set (match_dup 2)
14461         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14462                    UNSPEC_TLSDESC))
14463    (parallel
14464     [(set (match_operand:DI 0 "register_operand" "")
14465           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14466                      UNSPEC_TLSDESC))
14467      (clobber (reg:CC FLAGS_REG))])]
14468   "TARGET_64BIT && TARGET_GNU2_TLS"
14470   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14471   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14474 (define_insn "*tls_dynamic_lea_64"
14475   [(set (match_operand:DI 0 "register_operand" "=r")
14476         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14477                    UNSPEC_TLSDESC))]
14478   "TARGET_64BIT && TARGET_GNU2_TLS"
14479   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14480   [(set_attr "type" "lea")
14481    (set_attr "mode" "DI")
14482    (set_attr "length" "7")
14483    (set_attr "length_address" "4")])
14485 (define_insn "*tls_dynamic_call_64"
14486   [(set (match_operand:DI 0 "register_operand" "=a")
14487         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14488                     (match_operand:DI 2 "register_operand" "0")
14489                     (reg:DI SP_REG)]
14490                    UNSPEC_TLSDESC))
14491    (clobber (reg:CC FLAGS_REG))]
14492   "TARGET_64BIT && TARGET_GNU2_TLS"
14493   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14494   [(set_attr "type" "call")
14495    (set_attr "length" "2")
14496    (set_attr "length_address" "0")])
14498 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14499   [(set (match_operand:DI 0 "register_operand" "=&a")
14500         (plus:DI
14501          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14502                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14503                               (match_operand:DI 4 "" "")
14504                               (reg:DI SP_REG)]
14505                               UNSPEC_TLSDESC))
14506          (const:DI (unspec:DI
14507                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14508                     UNSPEC_DTPOFF))))
14509    (clobber (reg:CC FLAGS_REG))]
14510   "TARGET_64BIT && TARGET_GNU2_TLS"
14511   "#"
14512   ""
14513   [(parallel
14514     [(set (match_dup 0)
14515           (plus:DI (match_dup 2)
14516                    (match_dup 4)))
14517      (clobber (reg:CC FLAGS_REG))])]
14519   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14520   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14525 ;; These patterns match the binary 387 instructions for addM3, subM3,
14526 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14527 ;; SFmode.  The first is the normal insn, the second the same insn but
14528 ;; with one operand a conversion, and the third the same insn but with
14529 ;; the other operand a conversion.  The conversion may be SFmode or
14530 ;; SImode if the target mode DFmode, but only SImode if the target mode
14531 ;; is SFmode.
14533 ;; Gcc is slightly more smart about handling normal two address instructions
14534 ;; so use special patterns for add and mull.
14536 (define_insn "*fop_sf_comm_mixed"
14537   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14538         (match_operator:SF 3 "binary_fp_operator"
14539                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14540                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14541   "TARGET_MIX_SSE_I387
14542    && COMMUTATIVE_ARITH_P (operands[3])
14543    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14544   "* return output_387_binary_op (insn, operands);"
14545   [(set (attr "type") 
14546         (if_then_else (eq_attr "alternative" "1")
14547            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14548               (const_string "ssemul")
14549               (const_string "sseadd"))
14550            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14551               (const_string "fmul")
14552               (const_string "fop"))))
14553    (set_attr "mode" "SF")])
14555 (define_insn "*fop_sf_comm_sse"
14556   [(set (match_operand:SF 0 "register_operand" "=x")
14557         (match_operator:SF 3 "binary_fp_operator"
14558                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14559                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14560   "TARGET_SSE_MATH
14561    && COMMUTATIVE_ARITH_P (operands[3])
14562    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14563   "* return output_387_binary_op (insn, operands);"
14564   [(set (attr "type") 
14565         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14566            (const_string "ssemul")
14567            (const_string "sseadd")))
14568    (set_attr "mode" "SF")])
14570 (define_insn "*fop_sf_comm_i387"
14571   [(set (match_operand:SF 0 "register_operand" "=f")
14572         (match_operator:SF 3 "binary_fp_operator"
14573                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14574                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14575   "TARGET_80387
14576    && COMMUTATIVE_ARITH_P (operands[3])
14577    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14578   "* return output_387_binary_op (insn, operands);"
14579   [(set (attr "type") 
14580         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14581            (const_string "fmul")
14582            (const_string "fop")))
14583    (set_attr "mode" "SF")])
14585 (define_insn "*fop_sf_1_mixed"
14586   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14587         (match_operator:SF 3 "binary_fp_operator"
14588                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14589                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14590   "TARGET_MIX_SSE_I387
14591    && !COMMUTATIVE_ARITH_P (operands[3])
14592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14593   "* return output_387_binary_op (insn, operands);"
14594   [(set (attr "type") 
14595         (cond [(and (eq_attr "alternative" "2")
14596                     (match_operand:SF 3 "mult_operator" ""))
14597                  (const_string "ssemul")
14598                (and (eq_attr "alternative" "2")
14599                     (match_operand:SF 3 "div_operator" ""))
14600                  (const_string "ssediv")
14601                (eq_attr "alternative" "2")
14602                  (const_string "sseadd")
14603                (match_operand:SF 3 "mult_operator" "") 
14604                  (const_string "fmul")
14605                (match_operand:SF 3 "div_operator" "") 
14606                  (const_string "fdiv")
14607               ]
14608               (const_string "fop")))
14609    (set_attr "mode" "SF")])
14611 (define_insn "*fop_sf_1_sse"
14612   [(set (match_operand:SF 0 "register_operand" "=x")
14613         (match_operator:SF 3 "binary_fp_operator"
14614                         [(match_operand:SF 1 "register_operand" "0")
14615                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14616   "TARGET_SSE_MATH
14617    && !COMMUTATIVE_ARITH_P (operands[3])"
14618   "* return output_387_binary_op (insn, operands);"
14619   [(set (attr "type") 
14620         (cond [(match_operand:SF 3 "mult_operator" "")
14621                  (const_string "ssemul")
14622                (match_operand:SF 3 "div_operator" "")
14623                  (const_string "ssediv")
14624               ]
14625               (const_string "sseadd")))
14626    (set_attr "mode" "SF")])
14628 ;; This pattern is not fully shadowed by the pattern above.
14629 (define_insn "*fop_sf_1_i387"
14630   [(set (match_operand:SF 0 "register_operand" "=f,f")
14631         (match_operator:SF 3 "binary_fp_operator"
14632                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14633                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14634   "TARGET_80387 && !TARGET_SSE_MATH
14635    && !COMMUTATIVE_ARITH_P (operands[3])
14636    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14637   "* return output_387_binary_op (insn, operands);"
14638   [(set (attr "type") 
14639         (cond [(match_operand:SF 3 "mult_operator" "") 
14640                  (const_string "fmul")
14641                (match_operand:SF 3 "div_operator" "") 
14642                  (const_string "fdiv")
14643               ]
14644               (const_string "fop")))
14645    (set_attr "mode" "SF")])
14647 ;; ??? Add SSE splitters for these!
14648 (define_insn "*fop_sf_2<mode>_i387"
14649   [(set (match_operand:SF 0 "register_operand" "=f,f")
14650         (match_operator:SF 3 "binary_fp_operator"
14651           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14652            (match_operand:SF 2 "register_operand" "0,0")]))]
14653   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14654   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14655   [(set (attr "type") 
14656         (cond [(match_operand:SF 3 "mult_operator" "") 
14657                  (const_string "fmul")
14658                (match_operand:SF 3 "div_operator" "") 
14659                  (const_string "fdiv")
14660               ]
14661               (const_string "fop")))
14662    (set_attr "fp_int_src" "true")
14663    (set_attr "mode" "<MODE>")])
14665 (define_insn "*fop_sf_3<mode>_i387"
14666   [(set (match_operand:SF 0 "register_operand" "=f,f")
14667         (match_operator:SF 3 "binary_fp_operator"
14668           [(match_operand:SF 1 "register_operand" "0,0")
14669            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14670   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14671   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14672   [(set (attr "type") 
14673         (cond [(match_operand:SF 3 "mult_operator" "") 
14674                  (const_string "fmul")
14675                (match_operand:SF 3 "div_operator" "") 
14676                  (const_string "fdiv")
14677               ]
14678               (const_string "fop")))
14679    (set_attr "fp_int_src" "true")
14680    (set_attr "mode" "<MODE>")])
14682 (define_insn "*fop_df_comm_mixed"
14683   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14684         (match_operator:DF 3 "binary_fp_operator"
14685                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14686                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14687   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14688    && COMMUTATIVE_ARITH_P (operands[3])
14689    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14690   "* return output_387_binary_op (insn, operands);"
14691   [(set (attr "type") 
14692         (if_then_else (eq_attr "alternative" "1")
14693            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14694               (const_string "ssemul")
14695               (const_string "sseadd"))
14696            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14697               (const_string "fmul")
14698               (const_string "fop"))))
14699    (set_attr "mode" "DF")])
14701 (define_insn "*fop_df_comm_sse"
14702   [(set (match_operand:DF 0 "register_operand" "=Y")
14703         (match_operator:DF 3 "binary_fp_operator"
14704                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14705                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14706   "TARGET_SSE2 && TARGET_SSE_MATH
14707    && COMMUTATIVE_ARITH_P (operands[3])
14708    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14709   "* return output_387_binary_op (insn, operands);"
14710   [(set (attr "type") 
14711         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14712            (const_string "ssemul")
14713            (const_string "sseadd")))
14714    (set_attr "mode" "DF")])
14716 (define_insn "*fop_df_comm_i387"
14717   [(set (match_operand:DF 0 "register_operand" "=f")
14718         (match_operator:DF 3 "binary_fp_operator"
14719                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14720                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14721   "TARGET_80387
14722    && COMMUTATIVE_ARITH_P (operands[3])
14723    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14724   "* return output_387_binary_op (insn, operands);"
14725   [(set (attr "type") 
14726         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14727            (const_string "fmul")
14728            (const_string "fop")))
14729    (set_attr "mode" "DF")])
14731 (define_insn "*fop_df_1_mixed"
14732   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14733         (match_operator:DF 3 "binary_fp_operator"
14734                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14735                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14736   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14737    && !COMMUTATIVE_ARITH_P (operands[3])
14738    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14739   "* return output_387_binary_op (insn, operands);"
14740   [(set (attr "type") 
14741         (cond [(and (eq_attr "alternative" "2")
14742                     (match_operand:SF 3 "mult_operator" ""))
14743                  (const_string "ssemul")
14744                (and (eq_attr "alternative" "2")
14745                     (match_operand:SF 3 "div_operator" ""))
14746                  (const_string "ssediv")
14747                (eq_attr "alternative" "2")
14748                  (const_string "sseadd")
14749                (match_operand:DF 3 "mult_operator" "") 
14750                  (const_string "fmul")
14751                (match_operand:DF 3 "div_operator" "") 
14752                  (const_string "fdiv")
14753               ]
14754               (const_string "fop")))
14755    (set_attr "mode" "DF")])
14757 (define_insn "*fop_df_1_sse"
14758   [(set (match_operand:DF 0 "register_operand" "=Y")
14759         (match_operator:DF 3 "binary_fp_operator"
14760                         [(match_operand:DF 1 "register_operand" "0")
14761                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14762   "TARGET_SSE2 && TARGET_SSE_MATH
14763    && !COMMUTATIVE_ARITH_P (operands[3])"
14764   "* return output_387_binary_op (insn, operands);"
14765   [(set_attr "mode" "DF")
14766    (set (attr "type") 
14767         (cond [(match_operand:SF 3 "mult_operator" "")
14768                  (const_string "ssemul")
14769                (match_operand:SF 3 "div_operator" "")
14770                  (const_string "ssediv")
14771               ]
14772               (const_string "sseadd")))])
14774 ;; This pattern is not fully shadowed by the pattern above.
14775 (define_insn "*fop_df_1_i387"
14776   [(set (match_operand:DF 0 "register_operand" "=f,f")
14777         (match_operator:DF 3 "binary_fp_operator"
14778                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14779                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14780   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14781    && !COMMUTATIVE_ARITH_P (operands[3])
14782    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14783   "* return output_387_binary_op (insn, operands);"
14784   [(set (attr "type") 
14785         (cond [(match_operand:DF 3 "mult_operator" "") 
14786                  (const_string "fmul")
14787                (match_operand:DF 3 "div_operator" "")
14788                  (const_string "fdiv")
14789               ]
14790               (const_string "fop")))
14791    (set_attr "mode" "DF")])
14793 ;; ??? Add SSE splitters for these!
14794 (define_insn "*fop_df_2<mode>_i387"
14795   [(set (match_operand:DF 0 "register_operand" "=f,f")
14796         (match_operator:DF 3 "binary_fp_operator"
14797            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14798             (match_operand:DF 2 "register_operand" "0,0")]))]
14799   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14800    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14801   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14802   [(set (attr "type") 
14803         (cond [(match_operand:DF 3 "mult_operator" "") 
14804                  (const_string "fmul")
14805                (match_operand:DF 3 "div_operator" "") 
14806                  (const_string "fdiv")
14807               ]
14808               (const_string "fop")))
14809    (set_attr "fp_int_src" "true")
14810    (set_attr "mode" "<MODE>")])
14812 (define_insn "*fop_df_3<mode>_i387"
14813   [(set (match_operand:DF 0 "register_operand" "=f,f")
14814         (match_operator:DF 3 "binary_fp_operator"
14815            [(match_operand:DF 1 "register_operand" "0,0")
14816             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14817   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14818    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14819   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14820   [(set (attr "type") 
14821         (cond [(match_operand:DF 3 "mult_operator" "") 
14822                  (const_string "fmul")
14823                (match_operand:DF 3 "div_operator" "") 
14824                  (const_string "fdiv")
14825               ]
14826               (const_string "fop")))
14827    (set_attr "fp_int_src" "true")
14828    (set_attr "mode" "<MODE>")])
14830 (define_insn "*fop_df_4_i387"
14831   [(set (match_operand:DF 0 "register_operand" "=f,f")
14832         (match_operator:DF 3 "binary_fp_operator"
14833            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14834             (match_operand:DF 2 "register_operand" "0,f")]))]
14835   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14836    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14837   "* return output_387_binary_op (insn, operands);"
14838   [(set (attr "type") 
14839         (cond [(match_operand:DF 3 "mult_operator" "") 
14840                  (const_string "fmul")
14841                (match_operand:DF 3 "div_operator" "") 
14842                  (const_string "fdiv")
14843               ]
14844               (const_string "fop")))
14845    (set_attr "mode" "SF")])
14847 (define_insn "*fop_df_5_i387"
14848   [(set (match_operand:DF 0 "register_operand" "=f,f")
14849         (match_operator:DF 3 "binary_fp_operator"
14850           [(match_operand:DF 1 "register_operand" "0,f")
14851            (float_extend:DF
14852             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14853   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14854   "* return output_387_binary_op (insn, operands);"
14855   [(set (attr "type") 
14856         (cond [(match_operand:DF 3 "mult_operator" "") 
14857                  (const_string "fmul")
14858                (match_operand:DF 3 "div_operator" "") 
14859                  (const_string "fdiv")
14860               ]
14861               (const_string "fop")))
14862    (set_attr "mode" "SF")])
14864 (define_insn "*fop_df_6_i387"
14865   [(set (match_operand:DF 0 "register_operand" "=f,f")
14866         (match_operator:DF 3 "binary_fp_operator"
14867           [(float_extend:DF
14868             (match_operand:SF 1 "register_operand" "0,f"))
14869            (float_extend:DF
14870             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14871   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14872   "* return output_387_binary_op (insn, operands);"
14873   [(set (attr "type") 
14874         (cond [(match_operand:DF 3 "mult_operator" "") 
14875                  (const_string "fmul")
14876                (match_operand:DF 3 "div_operator" "") 
14877                  (const_string "fdiv")
14878               ]
14879               (const_string "fop")))
14880    (set_attr "mode" "SF")])
14882 (define_insn "*fop_xf_comm_i387"
14883   [(set (match_operand:XF 0 "register_operand" "=f")
14884         (match_operator:XF 3 "binary_fp_operator"
14885                         [(match_operand:XF 1 "register_operand" "%0")
14886                          (match_operand:XF 2 "register_operand" "f")]))]
14887   "TARGET_80387
14888    && COMMUTATIVE_ARITH_P (operands[3])"
14889   "* return output_387_binary_op (insn, operands);"
14890   [(set (attr "type") 
14891         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14892            (const_string "fmul")
14893            (const_string "fop")))
14894    (set_attr "mode" "XF")])
14896 (define_insn "*fop_xf_1_i387"
14897   [(set (match_operand:XF 0 "register_operand" "=f,f")
14898         (match_operator:XF 3 "binary_fp_operator"
14899                         [(match_operand:XF 1 "register_operand" "0,f")
14900                          (match_operand:XF 2 "register_operand" "f,0")]))]
14901   "TARGET_80387
14902    && !COMMUTATIVE_ARITH_P (operands[3])"
14903   "* return output_387_binary_op (insn, operands);"
14904   [(set (attr "type") 
14905         (cond [(match_operand:XF 3 "mult_operator" "") 
14906                  (const_string "fmul")
14907                (match_operand:XF 3 "div_operator" "") 
14908                  (const_string "fdiv")
14909               ]
14910               (const_string "fop")))
14911    (set_attr "mode" "XF")])
14913 (define_insn "*fop_xf_2<mode>_i387"
14914   [(set (match_operand:XF 0 "register_operand" "=f,f")
14915         (match_operator:XF 3 "binary_fp_operator"
14916            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14917             (match_operand:XF 2 "register_operand" "0,0")]))]
14918   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14919   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14920   [(set (attr "type") 
14921         (cond [(match_operand:XF 3 "mult_operator" "") 
14922                  (const_string "fmul")
14923                (match_operand:XF 3 "div_operator" "") 
14924                  (const_string "fdiv")
14925               ]
14926               (const_string "fop")))
14927    (set_attr "fp_int_src" "true")
14928    (set_attr "mode" "<MODE>")])
14930 (define_insn "*fop_xf_3<mode>_i387"
14931   [(set (match_operand:XF 0 "register_operand" "=f,f")
14932         (match_operator:XF 3 "binary_fp_operator"
14933           [(match_operand:XF 1 "register_operand" "0,0")
14934            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14935   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14936   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14937   [(set (attr "type") 
14938         (cond [(match_operand:XF 3 "mult_operator" "") 
14939                  (const_string "fmul")
14940                (match_operand:XF 3 "div_operator" "") 
14941                  (const_string "fdiv")
14942               ]
14943               (const_string "fop")))
14944    (set_attr "fp_int_src" "true")
14945    (set_attr "mode" "<MODE>")])
14947 (define_insn "*fop_xf_4_i387"
14948   [(set (match_operand:XF 0 "register_operand" "=f,f")
14949         (match_operator:XF 3 "binary_fp_operator"
14950            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14951             (match_operand:XF 2 "register_operand" "0,f")]))]
14952   "TARGET_80387"
14953   "* return output_387_binary_op (insn, operands);"
14954   [(set (attr "type") 
14955         (cond [(match_operand:XF 3 "mult_operator" "") 
14956                  (const_string "fmul")
14957                (match_operand:XF 3 "div_operator" "") 
14958                  (const_string "fdiv")
14959               ]
14960               (const_string "fop")))
14961    (set_attr "mode" "SF")])
14963 (define_insn "*fop_xf_5_i387"
14964   [(set (match_operand:XF 0 "register_operand" "=f,f")
14965         (match_operator:XF 3 "binary_fp_operator"
14966           [(match_operand:XF 1 "register_operand" "0,f")
14967            (float_extend:XF
14968             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14969   "TARGET_80387"
14970   "* return output_387_binary_op (insn, operands);"
14971   [(set (attr "type") 
14972         (cond [(match_operand:XF 3 "mult_operator" "") 
14973                  (const_string "fmul")
14974                (match_operand:XF 3 "div_operator" "") 
14975                  (const_string "fdiv")
14976               ]
14977               (const_string "fop")))
14978    (set_attr "mode" "SF")])
14980 (define_insn "*fop_xf_6_i387"
14981   [(set (match_operand:XF 0 "register_operand" "=f,f")
14982         (match_operator:XF 3 "binary_fp_operator"
14983           [(float_extend:XF
14984             (match_operand 1 "register_operand" "0,f"))
14985            (float_extend:XF
14986             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14987   "TARGET_80387"
14988   "* return output_387_binary_op (insn, operands);"
14989   [(set (attr "type") 
14990         (cond [(match_operand:XF 3 "mult_operator" "") 
14991                  (const_string "fmul")
14992                (match_operand:XF 3 "div_operator" "") 
14993                  (const_string "fdiv")
14994               ]
14995               (const_string "fop")))
14996    (set_attr "mode" "SF")])
14998 (define_split
14999   [(set (match_operand 0 "register_operand" "")
15000         (match_operator 3 "binary_fp_operator"
15001            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15002             (match_operand 2 "register_operand" "")]))]
15003   "TARGET_80387 && reload_completed
15004    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15005   [(const_int 0)]
15007   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15008   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15009   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15010                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15011                                           GET_MODE (operands[3]),
15012                                           operands[4],
15013                                           operands[2])));
15014   ix86_free_from_memory (GET_MODE (operands[1]));
15015   DONE;
15018 (define_split
15019   [(set (match_operand 0 "register_operand" "")
15020         (match_operator 3 "binary_fp_operator"
15021            [(match_operand 1 "register_operand" "")
15022             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15023   "TARGET_80387 && reload_completed
15024    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15025   [(const_int 0)]
15027   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15028   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15029   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15030                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15031                                           GET_MODE (operands[3]),
15032                                           operands[1],
15033                                           operands[4])));
15034   ix86_free_from_memory (GET_MODE (operands[2]));
15035   DONE;
15038 ;; FPU special functions.
15040 (define_expand "sqrtsf2"
15041   [(set (match_operand:SF 0 "register_operand" "")
15042         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15043   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15045   if (!TARGET_SSE_MATH)
15046     operands[1] = force_reg (SFmode, operands[1]);
15049 (define_insn "*sqrtsf2_mixed"
15050   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15051         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15052   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15053   "@
15054    fsqrt
15055    sqrtss\t{%1, %0|%0, %1}"
15056   [(set_attr "type" "fpspc,sse")
15057    (set_attr "mode" "SF,SF")
15058    (set_attr "athlon_decode" "direct,*")])
15060 (define_insn "*sqrtsf2_sse"
15061   [(set (match_operand:SF 0 "register_operand" "=x")
15062         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15063   "TARGET_SSE_MATH"
15064   "sqrtss\t{%1, %0|%0, %1}"
15065   [(set_attr "type" "sse")
15066    (set_attr "mode" "SF")
15067    (set_attr "athlon_decode" "*")])
15069 (define_insn "*sqrtsf2_i387"
15070   [(set (match_operand:SF 0 "register_operand" "=f")
15071         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15072   "TARGET_USE_FANCY_MATH_387"
15073   "fsqrt"
15074   [(set_attr "type" "fpspc")
15075    (set_attr "mode" "SF")
15076    (set_attr "athlon_decode" "direct")])
15078 (define_expand "sqrtdf2"
15079   [(set (match_operand:DF 0 "register_operand" "")
15080         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15081   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15083   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15084     operands[1] = force_reg (DFmode, operands[1]);
15087 (define_insn "*sqrtdf2_mixed"
15088   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15089         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15090   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15091   "@
15092    fsqrt
15093    sqrtsd\t{%1, %0|%0, %1}"
15094   [(set_attr "type" "fpspc,sse")
15095    (set_attr "mode" "DF,DF")
15096    (set_attr "athlon_decode" "direct,*")])
15098 (define_insn "*sqrtdf2_sse"
15099   [(set (match_operand:DF 0 "register_operand" "=Y")
15100         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15101   "TARGET_SSE2 && TARGET_SSE_MATH"
15102   "sqrtsd\t{%1, %0|%0, %1}"
15103   [(set_attr "type" "sse")
15104    (set_attr "mode" "DF")
15105    (set_attr "athlon_decode" "*")])
15107 (define_insn "*sqrtdf2_i387"
15108   [(set (match_operand:DF 0 "register_operand" "=f")
15109         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15110   "TARGET_USE_FANCY_MATH_387"
15111   "fsqrt"
15112   [(set_attr "type" "fpspc")
15113    (set_attr "mode" "DF")
15114    (set_attr "athlon_decode" "direct")])
15116 (define_insn "*sqrtextendsfdf2_i387"
15117   [(set (match_operand:DF 0 "register_operand" "=f")
15118         (sqrt:DF (float_extend:DF
15119                   (match_operand:SF 1 "register_operand" "0"))))]
15120   "TARGET_USE_FANCY_MATH_387
15121    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15122   "fsqrt"
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "DF")
15125    (set_attr "athlon_decode" "direct")])
15127 (define_insn "sqrtxf2"
15128   [(set (match_operand:XF 0 "register_operand" "=f")
15129         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15130   "TARGET_USE_FANCY_MATH_387 
15131    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15132   "fsqrt"
15133   [(set_attr "type" "fpspc")
15134    (set_attr "mode" "XF")
15135    (set_attr "athlon_decode" "direct")])
15137 (define_insn "*sqrtextendsfxf2_i387"
15138   [(set (match_operand:XF 0 "register_operand" "=f")
15139         (sqrt:XF (float_extend:XF
15140                   (match_operand:SF 1 "register_operand" "0"))))]
15141   "TARGET_USE_FANCY_MATH_387"
15142   "fsqrt"
15143   [(set_attr "type" "fpspc")
15144    (set_attr "mode" "XF")
15145    (set_attr "athlon_decode" "direct")])
15147 (define_insn "*sqrtextenddfxf2_i387"
15148   [(set (match_operand:XF 0 "register_operand" "=f")
15149         (sqrt:XF (float_extend:XF
15150                   (match_operand:DF 1 "register_operand" "0"))))]
15151   "TARGET_USE_FANCY_MATH_387"
15152   "fsqrt"
15153   [(set_attr "type" "fpspc")
15154    (set_attr "mode" "XF")
15155    (set_attr "athlon_decode" "direct")])
15157 (define_insn "fpremxf4"
15158   [(set (match_operand:XF 0 "register_operand" "=f")
15159         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15160                     (match_operand:XF 3 "register_operand" "1")]
15161                    UNSPEC_FPREM_F))
15162    (set (match_operand:XF 1 "register_operand" "=u")
15163         (unspec:XF [(match_dup 2) (match_dup 3)]
15164                    UNSPEC_FPREM_U))
15165    (set (reg:CCFP FPSR_REG)
15166         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15167   "TARGET_USE_FANCY_MATH_387
15168    && flag_unsafe_math_optimizations"
15169   "fprem"
15170   [(set_attr "type" "fpspc")
15171    (set_attr "mode" "XF")])
15173 (define_expand "fmodsf3"
15174   [(use (match_operand:SF 0 "register_operand" ""))
15175    (use (match_operand:SF 1 "register_operand" ""))
15176    (use (match_operand:SF 2 "register_operand" ""))]
15177   "TARGET_USE_FANCY_MATH_387
15178    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15179    && flag_unsafe_math_optimizations"
15181   rtx label = gen_label_rtx ();
15183   rtx op1 = gen_reg_rtx (XFmode);
15184   rtx op2 = gen_reg_rtx (XFmode);
15186   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15187   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15189   emit_label (label);
15191   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15192   ix86_emit_fp_unordered_jump (label);
15194   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15195   DONE;
15198 (define_expand "fmoddf3"
15199   [(use (match_operand:DF 0 "register_operand" ""))
15200    (use (match_operand:DF 1 "register_operand" ""))
15201    (use (match_operand:DF 2 "register_operand" ""))]
15202   "TARGET_USE_FANCY_MATH_387
15203    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15204    && flag_unsafe_math_optimizations"
15206   rtx label = gen_label_rtx ();
15208   rtx op1 = gen_reg_rtx (XFmode);
15209   rtx op2 = gen_reg_rtx (XFmode);
15211   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15212   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15214   emit_label (label);
15216   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15217   ix86_emit_fp_unordered_jump (label);
15219   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15220   DONE;
15223 (define_expand "fmodxf3"
15224   [(use (match_operand:XF 0 "register_operand" ""))
15225    (use (match_operand:XF 1 "register_operand" ""))
15226    (use (match_operand:XF 2 "register_operand" ""))]
15227   "TARGET_USE_FANCY_MATH_387
15228    && flag_unsafe_math_optimizations"
15230   rtx label = gen_label_rtx ();
15232   emit_label (label);
15234   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15235                            operands[1], operands[2]));
15236   ix86_emit_fp_unordered_jump (label);
15238   emit_move_insn (operands[0], operands[1]);
15239   DONE;
15242 (define_insn "fprem1xf4"
15243   [(set (match_operand:XF 0 "register_operand" "=f")
15244         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15245                     (match_operand:XF 3 "register_operand" "1")]
15246                    UNSPEC_FPREM1_F))
15247    (set (match_operand:XF 1 "register_operand" "=u")
15248         (unspec:XF [(match_dup 2) (match_dup 3)]
15249                    UNSPEC_FPREM1_U))
15250    (set (reg:CCFP FPSR_REG)
15251         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15252   "TARGET_USE_FANCY_MATH_387
15253    && flag_unsafe_math_optimizations"
15254   "fprem1"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "XF")])
15258 (define_expand "dremsf3"
15259   [(use (match_operand:SF 0 "register_operand" ""))
15260    (use (match_operand:SF 1 "register_operand" ""))
15261    (use (match_operand:SF 2 "register_operand" ""))]
15262   "TARGET_USE_FANCY_MATH_387
15263    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15264    && flag_unsafe_math_optimizations"
15266   rtx label = gen_label_rtx ();
15268   rtx op1 = gen_reg_rtx (XFmode);
15269   rtx op2 = gen_reg_rtx (XFmode);
15271   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15272   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15274   emit_label (label);
15276   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15277   ix86_emit_fp_unordered_jump (label);
15279   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15280   DONE;
15283 (define_expand "dremdf3"
15284   [(use (match_operand:DF 0 "register_operand" ""))
15285    (use (match_operand:DF 1 "register_operand" ""))
15286    (use (match_operand:DF 2 "register_operand" ""))]
15287   "TARGET_USE_FANCY_MATH_387
15288    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15289    && flag_unsafe_math_optimizations"
15291   rtx label = gen_label_rtx ();
15293   rtx op1 = gen_reg_rtx (XFmode);
15294   rtx op2 = gen_reg_rtx (XFmode);
15296   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15297   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15299   emit_label (label);
15301   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15302   ix86_emit_fp_unordered_jump (label);
15304   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15305   DONE;
15308 (define_expand "dremxf3"
15309   [(use (match_operand:XF 0 "register_operand" ""))
15310    (use (match_operand:XF 1 "register_operand" ""))
15311    (use (match_operand:XF 2 "register_operand" ""))]
15312   "TARGET_USE_FANCY_MATH_387
15313    && flag_unsafe_math_optimizations"
15315   rtx label = gen_label_rtx ();
15317   emit_label (label);
15319   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15320                             operands[1], operands[2]));
15321   ix86_emit_fp_unordered_jump (label);
15323   emit_move_insn (operands[0], operands[1]);
15324   DONE;
15327 (define_insn "*sindf2"
15328   [(set (match_operand:DF 0 "register_operand" "=f")
15329         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15330   "TARGET_USE_FANCY_MATH_387
15331    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15332    && flag_unsafe_math_optimizations"
15333   "fsin"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "DF")])
15337 (define_insn "*sinsf2"
15338   [(set (match_operand:SF 0 "register_operand" "=f")
15339         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15340   "TARGET_USE_FANCY_MATH_387
15341    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15342    && flag_unsafe_math_optimizations"
15343   "fsin"
15344   [(set_attr "type" "fpspc")
15345    (set_attr "mode" "SF")])
15347 (define_insn "*sinextendsfdf2"
15348   [(set (match_operand:DF 0 "register_operand" "=f")
15349         (unspec:DF [(float_extend:DF
15350                      (match_operand:SF 1 "register_operand" "0"))]
15351                    UNSPEC_SIN))]
15352   "TARGET_USE_FANCY_MATH_387
15353    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15354    && flag_unsafe_math_optimizations"
15355   "fsin"
15356   [(set_attr "type" "fpspc")
15357    (set_attr "mode" "DF")])
15359 (define_insn "*sinxf2"
15360   [(set (match_operand:XF 0 "register_operand" "=f")
15361         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15362   "TARGET_USE_FANCY_MATH_387
15363    && flag_unsafe_math_optimizations"
15364   "fsin"
15365   [(set_attr "type" "fpspc")
15366    (set_attr "mode" "XF")])
15368 (define_insn "*cosdf2"
15369   [(set (match_operand:DF 0 "register_operand" "=f")
15370         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15371   "TARGET_USE_FANCY_MATH_387
15372    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15373    && flag_unsafe_math_optimizations"
15374   "fcos"
15375   [(set_attr "type" "fpspc")
15376    (set_attr "mode" "DF")])
15378 (define_insn "*cossf2"
15379   [(set (match_operand:SF 0 "register_operand" "=f")
15380         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15383    && flag_unsafe_math_optimizations"
15384   "fcos"
15385   [(set_attr "type" "fpspc")
15386    (set_attr "mode" "SF")])
15388 (define_insn "*cosextendsfdf2"
15389   [(set (match_operand:DF 0 "register_operand" "=f")
15390         (unspec:DF [(float_extend:DF
15391                      (match_operand:SF 1 "register_operand" "0"))]
15392                    UNSPEC_COS))]
15393   "TARGET_USE_FANCY_MATH_387
15394    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15395    && flag_unsafe_math_optimizations"
15396   "fcos"
15397   [(set_attr "type" "fpspc")
15398    (set_attr "mode" "DF")])
15400 (define_insn "*cosxf2"
15401   [(set (match_operand:XF 0 "register_operand" "=f")
15402         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations"
15405   "fcos"
15406   [(set_attr "type" "fpspc")
15407    (set_attr "mode" "XF")])
15409 ;; With sincos pattern defined, sin and cos builtin function will be
15410 ;; expanded to sincos pattern with one of its outputs left unused. 
15411 ;; Cse pass  will detected, if two sincos patterns can be combined,
15412 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15413 ;; depending on the unused output.
15415 (define_insn "sincosdf3"
15416   [(set (match_operand:DF 0 "register_operand" "=f")
15417         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15418                    UNSPEC_SINCOS_COS))
15419    (set (match_operand:DF 1 "register_operand" "=u")
15420         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15423    && flag_unsafe_math_optimizations"
15424   "fsincos"
15425   [(set_attr "type" "fpspc")
15426    (set_attr "mode" "DF")])
15428 (define_split
15429   [(set (match_operand:DF 0 "register_operand" "")
15430         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15431                    UNSPEC_SINCOS_COS))
15432    (set (match_operand:DF 1 "register_operand" "")
15433         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15434   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15435    && !reload_completed && !reload_in_progress"
15436   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15437   "")
15439 (define_split
15440   [(set (match_operand:DF 0 "register_operand" "")
15441         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15442                    UNSPEC_SINCOS_COS))
15443    (set (match_operand:DF 1 "register_operand" "")
15444         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15445   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15446    && !reload_completed && !reload_in_progress"
15447   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15448   "")
15450 (define_insn "sincossf3"
15451   [(set (match_operand:SF 0 "register_operand" "=f")
15452         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15453                    UNSPEC_SINCOS_COS))
15454    (set (match_operand:SF 1 "register_operand" "=u")
15455         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15456   "TARGET_USE_FANCY_MATH_387
15457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15458    && flag_unsafe_math_optimizations"
15459   "fsincos"
15460   [(set_attr "type" "fpspc")
15461    (set_attr "mode" "SF")])
15463 (define_split
15464   [(set (match_operand:SF 0 "register_operand" "")
15465         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15466                    UNSPEC_SINCOS_COS))
15467    (set (match_operand:SF 1 "register_operand" "")
15468         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15469   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15470    && !reload_completed && !reload_in_progress"
15471   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15472   "")
15474 (define_split
15475   [(set (match_operand:SF 0 "register_operand" "")
15476         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15477                    UNSPEC_SINCOS_COS))
15478    (set (match_operand:SF 1 "register_operand" "")
15479         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15480   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15481    && !reload_completed && !reload_in_progress"
15482   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15483   "")
15485 (define_insn "*sincosextendsfdf3"
15486   [(set (match_operand:DF 0 "register_operand" "=f")
15487         (unspec:DF [(float_extend:DF
15488                      (match_operand:SF 2 "register_operand" "0"))]
15489                    UNSPEC_SINCOS_COS))
15490    (set (match_operand:DF 1 "register_operand" "=u")
15491         (unspec:DF [(float_extend:DF
15492                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15495    && flag_unsafe_math_optimizations"
15496   "fsincos"
15497   [(set_attr "type" "fpspc")
15498    (set_attr "mode" "DF")])
15500 (define_split
15501   [(set (match_operand:DF 0 "register_operand" "")
15502         (unspec:DF [(float_extend:DF
15503                      (match_operand:SF 2 "register_operand" ""))]
15504                    UNSPEC_SINCOS_COS))
15505    (set (match_operand:DF 1 "register_operand" "")
15506         (unspec:DF [(float_extend:DF
15507                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15508   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15509    && !reload_completed && !reload_in_progress"
15510   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15511                                    (match_dup 2))] UNSPEC_SIN))]
15512   "")
15514 (define_split
15515   [(set (match_operand:DF 0 "register_operand" "")
15516         (unspec:DF [(float_extend:DF
15517                      (match_operand:SF 2 "register_operand" ""))]
15518                    UNSPEC_SINCOS_COS))
15519    (set (match_operand:DF 1 "register_operand" "")
15520         (unspec:DF [(float_extend:DF
15521                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15522   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15523    && !reload_completed && !reload_in_progress"
15524   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15525                                    (match_dup 2))] UNSPEC_COS))]
15526   "")
15528 (define_insn "sincosxf3"
15529   [(set (match_operand:XF 0 "register_operand" "=f")
15530         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15531                    UNSPEC_SINCOS_COS))
15532    (set (match_operand:XF 1 "register_operand" "=u")
15533         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15534   "TARGET_USE_FANCY_MATH_387
15535    && flag_unsafe_math_optimizations"
15536   "fsincos"
15537   [(set_attr "type" "fpspc")
15538    (set_attr "mode" "XF")])
15540 (define_split
15541   [(set (match_operand:XF 0 "register_operand" "")
15542         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15543                    UNSPEC_SINCOS_COS))
15544    (set (match_operand:XF 1 "register_operand" "")
15545         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15546   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15547    && !reload_completed && !reload_in_progress"
15548   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15549   "")
15551 (define_split
15552   [(set (match_operand:XF 0 "register_operand" "")
15553         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15554                    UNSPEC_SINCOS_COS))
15555    (set (match_operand:XF 1 "register_operand" "")
15556         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15557   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15558    && !reload_completed && !reload_in_progress"
15559   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15560   "")
15562 (define_insn "*tandf3_1"
15563   [(set (match_operand:DF 0 "register_operand" "=f")
15564         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15565                    UNSPEC_TAN_ONE))
15566    (set (match_operand:DF 1 "register_operand" "=u")
15567         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15570    && flag_unsafe_math_optimizations"
15571   "fptan"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "mode" "DF")])
15575 ;; optimize sequence: fptan
15576 ;;                    fstp    %st(0)
15577 ;;                    fld1
15578 ;; into fptan insn.
15580 (define_peephole2
15581   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15582                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15583                              UNSPEC_TAN_ONE))
15584              (set (match_operand:DF 1 "register_operand" "")
15585                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15586    (set (match_dup 0)
15587         (match_operand:DF 3 "immediate_operand" ""))]
15588   "standard_80387_constant_p (operands[3]) == 2"
15589   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15590              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15591   "")
15593 (define_expand "tandf2"
15594   [(parallel [(set (match_dup 2)
15595                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15596                               UNSPEC_TAN_ONE))
15597               (set (match_operand:DF 0 "register_operand" "")
15598                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15599   "TARGET_USE_FANCY_MATH_387
15600    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15601    && flag_unsafe_math_optimizations"
15603   operands[2] = gen_reg_rtx (DFmode);
15606 (define_insn "*tansf3_1"
15607   [(set (match_operand:SF 0 "register_operand" "=f")
15608         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15609                    UNSPEC_TAN_ONE))
15610    (set (match_operand:SF 1 "register_operand" "=u")
15611         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15612   "TARGET_USE_FANCY_MATH_387
15613    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15614    && flag_unsafe_math_optimizations"
15615   "fptan"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "SF")])
15619 ;; optimize sequence: fptan
15620 ;;                    fstp    %st(0)
15621 ;;                    fld1
15622 ;; into fptan insn.
15624 (define_peephole2
15625   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15626                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15627                              UNSPEC_TAN_ONE))
15628              (set (match_operand:SF 1 "register_operand" "")
15629                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15630    (set (match_dup 0)
15631         (match_operand:SF 3 "immediate_operand" ""))]
15632   "standard_80387_constant_p (operands[3]) == 2"
15633   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15634              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15635   "")
15637 (define_expand "tansf2"
15638   [(parallel [(set (match_dup 2)
15639                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15640                               UNSPEC_TAN_ONE))
15641               (set (match_operand:SF 0 "register_operand" "")
15642                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15643   "TARGET_USE_FANCY_MATH_387
15644    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15645    && flag_unsafe_math_optimizations"
15647   operands[2] = gen_reg_rtx (SFmode);
15650 (define_insn "*tanxf3_1"
15651   [(set (match_operand:XF 0 "register_operand" "=f")
15652         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15653                    UNSPEC_TAN_ONE))
15654    (set (match_operand:XF 1 "register_operand" "=u")
15655         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_unsafe_math_optimizations"
15658   "fptan"
15659   [(set_attr "type" "fpspc")
15660    (set_attr "mode" "XF")])
15662 ;; optimize sequence: fptan
15663 ;;                    fstp    %st(0)
15664 ;;                    fld1
15665 ;; into fptan insn.
15667 (define_peephole2
15668   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15669                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15670                              UNSPEC_TAN_ONE))
15671              (set (match_operand:XF 1 "register_operand" "")
15672                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15673    (set (match_dup 0)
15674         (match_operand:XF 3 "immediate_operand" ""))]
15675   "standard_80387_constant_p (operands[3]) == 2"
15676   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15677              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15678   "")
15680 (define_expand "tanxf2"
15681   [(parallel [(set (match_dup 2)
15682                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15683                               UNSPEC_TAN_ONE))
15684               (set (match_operand:XF 0 "register_operand" "")
15685                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15686   "TARGET_USE_FANCY_MATH_387
15687    && flag_unsafe_math_optimizations"
15689   operands[2] = gen_reg_rtx (XFmode);
15692 (define_insn "atan2df3_1"
15693   [(set (match_operand:DF 0 "register_operand" "=f")
15694         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15695                     (match_operand:DF 1 "register_operand" "u")]
15696                    UNSPEC_FPATAN))
15697    (clobber (match_scratch:DF 3 "=1"))]
15698   "TARGET_USE_FANCY_MATH_387
15699    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15700    && flag_unsafe_math_optimizations"
15701   "fpatan"
15702   [(set_attr "type" "fpspc")
15703    (set_attr "mode" "DF")])
15705 (define_expand "atan2df3"
15706   [(use (match_operand:DF 0 "register_operand" ""))
15707    (use (match_operand:DF 2 "register_operand" ""))
15708    (use (match_operand:DF 1 "register_operand" ""))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15713   rtx copy = gen_reg_rtx (DFmode);
15714   emit_move_insn (copy, operands[1]);
15715   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15716   DONE;
15719 (define_expand "atandf2"
15720   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15721                    (unspec:DF [(match_dup 2)
15722                                (match_operand:DF 1 "register_operand" "")]
15723                     UNSPEC_FPATAN))
15724               (clobber (match_scratch:DF 3 ""))])]
15725   "TARGET_USE_FANCY_MATH_387
15726    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727    && flag_unsafe_math_optimizations"
15729   operands[2] = gen_reg_rtx (DFmode);
15730   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15733 (define_insn "atan2sf3_1"
15734   [(set (match_operand:SF 0 "register_operand" "=f")
15735         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15736                     (match_operand:SF 1 "register_operand" "u")]
15737                    UNSPEC_FPATAN))
15738    (clobber (match_scratch:SF 3 "=1"))]
15739   "TARGET_USE_FANCY_MATH_387
15740    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15741    && flag_unsafe_math_optimizations"
15742   "fpatan"
15743   [(set_attr "type" "fpspc")
15744    (set_attr "mode" "SF")])
15746 (define_expand "atan2sf3"
15747   [(use (match_operand:SF 0 "register_operand" ""))
15748    (use (match_operand:SF 2 "register_operand" ""))
15749    (use (match_operand:SF 1 "register_operand" ""))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15752    && flag_unsafe_math_optimizations"
15754   rtx copy = gen_reg_rtx (SFmode);
15755   emit_move_insn (copy, operands[1]);
15756   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15757   DONE;
15760 (define_expand "atansf2"
15761   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15762                    (unspec:SF [(match_dup 2)
15763                                (match_operand:SF 1 "register_operand" "")]
15764                     UNSPEC_FPATAN))
15765               (clobber (match_scratch:SF 3 ""))])]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15768    && flag_unsafe_math_optimizations"
15770   operands[2] = gen_reg_rtx (SFmode);
15771   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15774 (define_insn "atan2xf3_1"
15775   [(set (match_operand:XF 0 "register_operand" "=f")
15776         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15777                     (match_operand:XF 1 "register_operand" "u")]
15778                    UNSPEC_FPATAN))
15779    (clobber (match_scratch:XF 3 "=1"))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && flag_unsafe_math_optimizations"
15782   "fpatan"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "XF")])
15786 (define_expand "atan2xf3"
15787   [(use (match_operand:XF 0 "register_operand" ""))
15788    (use (match_operand:XF 2 "register_operand" ""))
15789    (use (match_operand:XF 1 "register_operand" ""))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && flag_unsafe_math_optimizations"
15793   rtx copy = gen_reg_rtx (XFmode);
15794   emit_move_insn (copy, operands[1]);
15795   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15796   DONE;
15799 (define_expand "atanxf2"
15800   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15801                    (unspec:XF [(match_dup 2)
15802                                (match_operand:XF 1 "register_operand" "")]
15803                     UNSPEC_FPATAN))
15804               (clobber (match_scratch:XF 3 ""))])]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15808   operands[2] = gen_reg_rtx (XFmode);
15809   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15812 (define_expand "asindf2"
15813   [(set (match_dup 2)
15814         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15815    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15816    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15817    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15818    (parallel [(set (match_dup 7)
15819                    (unspec:XF [(match_dup 6) (match_dup 2)]
15820                               UNSPEC_FPATAN))
15821               (clobber (match_scratch:XF 8 ""))])
15822    (set (match_operand:DF 0 "register_operand" "")
15823         (float_truncate:DF (match_dup 7)))]
15824   "TARGET_USE_FANCY_MATH_387
15825    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15826    && flag_unsafe_math_optimizations"
15828   int i;
15830   for (i=2; i<8; i++)
15831     operands[i] = gen_reg_rtx (XFmode);
15833   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15836 (define_expand "asinsf2"
15837   [(set (match_dup 2)
15838         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15839    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15840    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15841    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15842    (parallel [(set (match_dup 7)
15843                    (unspec:XF [(match_dup 6) (match_dup 2)]
15844                               UNSPEC_FPATAN))
15845               (clobber (match_scratch:XF 8 ""))])
15846    (set (match_operand:SF 0 "register_operand" "")
15847         (float_truncate:SF (match_dup 7)))]
15848   "TARGET_USE_FANCY_MATH_387
15849    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15850    && flag_unsafe_math_optimizations"
15852   int i;
15854   for (i=2; i<8; i++)
15855     operands[i] = gen_reg_rtx (XFmode);
15857   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15860 (define_expand "asinxf2"
15861   [(set (match_dup 2)
15862         (mult:XF (match_operand:XF 1 "register_operand" "")
15863                  (match_dup 1)))
15864    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15865    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15866    (parallel [(set (match_operand:XF 0 "register_operand" "")
15867                    (unspec:XF [(match_dup 5) (match_dup 1)]
15868                               UNSPEC_FPATAN))
15869               (clobber (match_scratch:XF 6 ""))])]
15870   "TARGET_USE_FANCY_MATH_387
15871    && flag_unsafe_math_optimizations"
15873   int i;
15875   for (i=2; i<6; i++)
15876     operands[i] = gen_reg_rtx (XFmode);
15878   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15881 (define_expand "acosdf2"
15882   [(set (match_dup 2)
15883         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15884    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15885    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15886    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15887    (parallel [(set (match_dup 7)
15888                    (unspec:XF [(match_dup 2) (match_dup 6)]
15889                               UNSPEC_FPATAN))
15890               (clobber (match_scratch:XF 8 ""))])
15891    (set (match_operand:DF 0 "register_operand" "")
15892         (float_truncate:DF (match_dup 7)))]
15893   "TARGET_USE_FANCY_MATH_387
15894    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15895    && flag_unsafe_math_optimizations"
15897   int i;
15899   for (i=2; i<8; i++)
15900     operands[i] = gen_reg_rtx (XFmode);
15902   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15905 (define_expand "acossf2"
15906   [(set (match_dup 2)
15907         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15908    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15909    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15910    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15911    (parallel [(set (match_dup 7)
15912                    (unspec:XF [(match_dup 2) (match_dup 6)]
15913                               UNSPEC_FPATAN))
15914               (clobber (match_scratch:XF 8 ""))])
15915    (set (match_operand:SF 0 "register_operand" "")
15916         (float_truncate:SF (match_dup 7)))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15919    && flag_unsafe_math_optimizations"
15921   int i;
15923   for (i=2; i<8; i++)
15924     operands[i] = gen_reg_rtx (XFmode);
15926   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15929 (define_expand "acosxf2"
15930   [(set (match_dup 2)
15931         (mult:XF (match_operand:XF 1 "register_operand" "")
15932                  (match_dup 1)))
15933    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15934    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15935    (parallel [(set (match_operand:XF 0 "register_operand" "")
15936                    (unspec:XF [(match_dup 1) (match_dup 5)]
15937                               UNSPEC_FPATAN))
15938               (clobber (match_scratch:XF 6 ""))])]
15939   "TARGET_USE_FANCY_MATH_387
15940    && flag_unsafe_math_optimizations"
15942   int i;
15944   for (i=2; i<6; i++)
15945     operands[i] = gen_reg_rtx (XFmode);
15947   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15950 (define_insn "fyl2x_xf3"
15951   [(set (match_operand:XF 0 "register_operand" "=f")
15952         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15953                     (match_operand:XF 1 "register_operand" "u")]
15954                    UNSPEC_FYL2X))
15955    (clobber (match_scratch:XF 3 "=1"))]
15956   "TARGET_USE_FANCY_MATH_387
15957    && flag_unsafe_math_optimizations"
15958   "fyl2x"
15959   [(set_attr "type" "fpspc")
15960    (set_attr "mode" "XF")])
15962 (define_expand "logsf2"
15963   [(set (match_dup 2)
15964         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15965    (parallel [(set (match_dup 4)
15966                    (unspec:XF [(match_dup 2)
15967                                (match_dup 3)] UNSPEC_FYL2X))
15968               (clobber (match_scratch:XF 5 ""))])
15969    (set (match_operand:SF 0 "register_operand" "")
15970         (float_truncate:SF (match_dup 4)))]
15971   "TARGET_USE_FANCY_MATH_387
15972    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15973    && flag_unsafe_math_optimizations"
15975   rtx temp;
15977   operands[2] = gen_reg_rtx (XFmode);
15978   operands[3] = gen_reg_rtx (XFmode);
15979   operands[4] = gen_reg_rtx (XFmode);
15981   temp = standard_80387_constant_rtx (4); /* fldln2 */
15982   emit_move_insn (operands[3], temp);
15985 (define_expand "logdf2"
15986   [(set (match_dup 2)
15987         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15988    (parallel [(set (match_dup 4)
15989                    (unspec:XF [(match_dup 2)
15990                                (match_dup 3)] UNSPEC_FYL2X))
15991               (clobber (match_scratch:XF 5 ""))])
15992    (set (match_operand:DF 0 "register_operand" "")
15993         (float_truncate:DF (match_dup 4)))]
15994   "TARGET_USE_FANCY_MATH_387
15995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15996    && flag_unsafe_math_optimizations"
15998   rtx temp;
16000   operands[2] = gen_reg_rtx (XFmode);
16001   operands[3] = gen_reg_rtx (XFmode);
16002   operands[4] = gen_reg_rtx (XFmode);
16004   temp = standard_80387_constant_rtx (4); /* fldln2 */
16005   emit_move_insn (operands[3], temp);
16008 (define_expand "logxf2"
16009   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16011                                (match_dup 2)] UNSPEC_FYL2X))
16012               (clobber (match_scratch:XF 3 ""))])]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16016   rtx temp;
16018   operands[2] = gen_reg_rtx (XFmode);
16019   temp = standard_80387_constant_rtx (4); /* fldln2 */
16020   emit_move_insn (operands[2], temp);
16023 (define_expand "log10sf2"
16024   [(set (match_dup 2)
16025         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16026    (parallel [(set (match_dup 4)
16027                    (unspec:XF [(match_dup 2)
16028                                (match_dup 3)] UNSPEC_FYL2X))
16029               (clobber (match_scratch:XF 5 ""))])
16030    (set (match_operand:SF 0 "register_operand" "")
16031         (float_truncate:SF (match_dup 4)))]
16032   "TARGET_USE_FANCY_MATH_387
16033    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16034    && flag_unsafe_math_optimizations"
16036   rtx temp;
16038   operands[2] = gen_reg_rtx (XFmode);
16039   operands[3] = gen_reg_rtx (XFmode);
16040   operands[4] = gen_reg_rtx (XFmode);
16042   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16043   emit_move_insn (operands[3], temp);
16046 (define_expand "log10df2"
16047   [(set (match_dup 2)
16048         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16049    (parallel [(set (match_dup 4)
16050                    (unspec:XF [(match_dup 2)
16051                                (match_dup 3)] UNSPEC_FYL2X))
16052               (clobber (match_scratch:XF 5 ""))])
16053    (set (match_operand:DF 0 "register_operand" "")
16054         (float_truncate:DF (match_dup 4)))]
16055   "TARGET_USE_FANCY_MATH_387
16056    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16057    && flag_unsafe_math_optimizations"
16059   rtx temp;
16061   operands[2] = gen_reg_rtx (XFmode);
16062   operands[3] = gen_reg_rtx (XFmode);
16063   operands[4] = gen_reg_rtx (XFmode);
16065   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16066   emit_move_insn (operands[3], temp);
16069 (define_expand "log10xf2"
16070   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16071                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16072                                (match_dup 2)] UNSPEC_FYL2X))
16073               (clobber (match_scratch:XF 3 ""))])]
16074   "TARGET_USE_FANCY_MATH_387
16075    && flag_unsafe_math_optimizations"
16077   rtx temp;
16079   operands[2] = gen_reg_rtx (XFmode);
16080   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16081   emit_move_insn (operands[2], temp);
16084 (define_expand "log2sf2"
16085   [(set (match_dup 2)
16086         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16087    (parallel [(set (match_dup 4)
16088                    (unspec:XF [(match_dup 2)
16089                                (match_dup 3)] UNSPEC_FYL2X))
16090               (clobber (match_scratch:XF 5 ""))])
16091    (set (match_operand:SF 0 "register_operand" "")
16092         (float_truncate:SF (match_dup 4)))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16095    && flag_unsafe_math_optimizations"
16097   operands[2] = gen_reg_rtx (XFmode);
16098   operands[3] = gen_reg_rtx (XFmode);
16099   operands[4] = gen_reg_rtx (XFmode);
16101   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16104 (define_expand "log2df2"
16105   [(set (match_dup 2)
16106         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16107    (parallel [(set (match_dup 4)
16108                    (unspec:XF [(match_dup 2)
16109                                (match_dup 3)] UNSPEC_FYL2X))
16110               (clobber (match_scratch:XF 5 ""))])
16111    (set (match_operand:DF 0 "register_operand" "")
16112         (float_truncate:DF (match_dup 4)))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16117   operands[2] = gen_reg_rtx (XFmode);
16118   operands[3] = gen_reg_rtx (XFmode);
16119   operands[4] = gen_reg_rtx (XFmode);
16121   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16124 (define_expand "log2xf2"
16125   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16126                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16127                                (match_dup 2)] UNSPEC_FYL2X))
16128               (clobber (match_scratch:XF 3 ""))])]
16129   "TARGET_USE_FANCY_MATH_387
16130    && flag_unsafe_math_optimizations"
16132   operands[2] = gen_reg_rtx (XFmode);
16133   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16136 (define_insn "fyl2xp1_xf3"
16137   [(set (match_operand:XF 0 "register_operand" "=f")
16138         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16139                     (match_operand:XF 1 "register_operand" "u")]
16140                    UNSPEC_FYL2XP1))
16141    (clobber (match_scratch:XF 3 "=1"))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations"
16144   "fyl2xp1"
16145   [(set_attr "type" "fpspc")
16146    (set_attr "mode" "XF")])
16148 (define_expand "log1psf2"
16149   [(use (match_operand:SF 0 "register_operand" ""))
16150    (use (match_operand:SF 1 "register_operand" ""))]
16151   "TARGET_USE_FANCY_MATH_387
16152    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16153    && flag_unsafe_math_optimizations"
16155   rtx op0 = gen_reg_rtx (XFmode);
16156   rtx op1 = gen_reg_rtx (XFmode);
16158   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16159   ix86_emit_i387_log1p (op0, op1);
16160   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16161   DONE;
16164 (define_expand "log1pdf2"
16165   [(use (match_operand:DF 0 "register_operand" ""))
16166    (use (match_operand:DF 1 "register_operand" ""))]
16167   "TARGET_USE_FANCY_MATH_387
16168    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16169    && flag_unsafe_math_optimizations"
16171   rtx op0 = gen_reg_rtx (XFmode);
16172   rtx op1 = gen_reg_rtx (XFmode);
16174   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16175   ix86_emit_i387_log1p (op0, op1);
16176   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16177   DONE;
16180 (define_expand "log1pxf2"
16181   [(use (match_operand:XF 0 "register_operand" ""))
16182    (use (match_operand:XF 1 "register_operand" ""))]
16183   "TARGET_USE_FANCY_MATH_387
16184    && flag_unsafe_math_optimizations"
16186   ix86_emit_i387_log1p (operands[0], operands[1]);
16187   DONE;
16190 (define_insn "*fxtractxf3"
16191   [(set (match_operand:XF 0 "register_operand" "=f")
16192         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16193                    UNSPEC_XTRACT_FRACT))
16194    (set (match_operand:XF 1 "register_operand" "=u")
16195         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16196   "TARGET_USE_FANCY_MATH_387
16197    && flag_unsafe_math_optimizations"
16198   "fxtract"
16199   [(set_attr "type" "fpspc")
16200    (set_attr "mode" "XF")])
16202 (define_expand "logbsf2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16205    (parallel [(set (match_dup 3)
16206                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16207               (set (match_dup 4)
16208                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16209    (set (match_operand:SF 0 "register_operand" "")
16210         (float_truncate:SF (match_dup 4)))]
16211   "TARGET_USE_FANCY_MATH_387
16212    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16213    && flag_unsafe_math_optimizations"
16215   operands[2] = gen_reg_rtx (XFmode);
16216   operands[3] = gen_reg_rtx (XFmode);
16217   operands[4] = gen_reg_rtx (XFmode);
16220 (define_expand "logbdf2"
16221   [(set (match_dup 2)
16222         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16223    (parallel [(set (match_dup 3)
16224                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16225               (set (match_dup 4)
16226                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16227    (set (match_operand:DF 0 "register_operand" "")
16228         (float_truncate:DF (match_dup 4)))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16231    && flag_unsafe_math_optimizations"
16233   operands[2] = gen_reg_rtx (XFmode);
16234   operands[3] = gen_reg_rtx (XFmode);
16235   operands[4] = gen_reg_rtx (XFmode);
16238 (define_expand "logbxf2"
16239   [(parallel [(set (match_dup 2)
16240                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16241                               UNSPEC_XTRACT_FRACT))
16242               (set (match_operand:XF 0 "register_operand" "")
16243                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16247   operands[2] = gen_reg_rtx (XFmode);
16250 (define_expand "ilogbsi2"
16251   [(parallel [(set (match_dup 2)
16252                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16253                               UNSPEC_XTRACT_FRACT))
16254               (set (match_operand:XF 3 "register_operand" "")
16255                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16256    (parallel [(set (match_operand:SI 0 "register_operand" "")
16257                    (fix:SI (match_dup 3)))
16258               (clobber (reg:CC FLAGS_REG))])]
16259   "TARGET_USE_FANCY_MATH_387
16260    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16261    && flag_unsafe_math_optimizations"
16263   operands[2] = gen_reg_rtx (XFmode);
16264   operands[3] = gen_reg_rtx (XFmode);
16267 (define_insn "*f2xm1xf2"
16268   [(set (match_operand:XF 0 "register_operand" "=f")
16269         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16270          UNSPEC_F2XM1))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16273   "f2xm1"
16274   [(set_attr "type" "fpspc")
16275    (set_attr "mode" "XF")])
16277 (define_insn "*fscalexf4"
16278   [(set (match_operand:XF 0 "register_operand" "=f")
16279         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16280                     (match_operand:XF 3 "register_operand" "1")]
16281                    UNSPEC_FSCALE_FRACT))
16282    (set (match_operand:XF 1 "register_operand" "=u")
16283         (unspec:XF [(match_dup 2) (match_dup 3)]
16284                    UNSPEC_FSCALE_EXP))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16287   "fscale"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16291 (define_expand "expsf2"
16292   [(set (match_dup 2)
16293         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16294    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16295    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16296    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16297    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16298    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16299    (parallel [(set (match_dup 10)
16300                    (unspec:XF [(match_dup 9) (match_dup 5)]
16301                               UNSPEC_FSCALE_FRACT))
16302               (set (match_dup 11)
16303                    (unspec:XF [(match_dup 9) (match_dup 5)]
16304                               UNSPEC_FSCALE_EXP))])
16305    (set (match_operand:SF 0 "register_operand" "")
16306         (float_truncate:SF (match_dup 10)))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16311   rtx temp;
16312   int i;
16314   for (i=2; i<12; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16316   temp = standard_80387_constant_rtx (5); /* fldl2e */
16317   emit_move_insn (operands[3], temp);
16318   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16321 (define_expand "expdf2"
16322   [(set (match_dup 2)
16323         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16324    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16325    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16326    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16327    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16328    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16329    (parallel [(set (match_dup 10)
16330                    (unspec:XF [(match_dup 9) (match_dup 5)]
16331                               UNSPEC_FSCALE_FRACT))
16332               (set (match_dup 11)
16333                    (unspec:XF [(match_dup 9) (match_dup 5)]
16334                               UNSPEC_FSCALE_EXP))])
16335    (set (match_operand:DF 0 "register_operand" "")
16336         (float_truncate:DF (match_dup 10)))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16339    && flag_unsafe_math_optimizations"
16341   rtx temp;
16342   int i;
16344   for (i=2; i<12; i++)
16345     operands[i] = gen_reg_rtx (XFmode);
16346   temp = standard_80387_constant_rtx (5); /* fldl2e */
16347   emit_move_insn (operands[3], temp);
16348   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16351 (define_expand "expxf2"
16352   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16353                                (match_dup 2)))
16354    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16355    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16356    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16357    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16358    (parallel [(set (match_operand:XF 0 "register_operand" "")
16359                    (unspec:XF [(match_dup 8) (match_dup 4)]
16360                               UNSPEC_FSCALE_FRACT))
16361               (set (match_dup 9)
16362                    (unspec:XF [(match_dup 8) (match_dup 4)]
16363                               UNSPEC_FSCALE_EXP))])]
16364   "TARGET_USE_FANCY_MATH_387
16365    && flag_unsafe_math_optimizations"
16367   rtx temp;
16368   int i;
16370   for (i=2; i<10; i++)
16371     operands[i] = gen_reg_rtx (XFmode);
16372   temp = standard_80387_constant_rtx (5); /* fldl2e */
16373   emit_move_insn (operands[2], temp);
16374   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16377 (define_expand "exp10sf2"
16378   [(set (match_dup 2)
16379         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16380    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16381    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16382    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16383    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16384    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16385    (parallel [(set (match_dup 10)
16386                    (unspec:XF [(match_dup 9) (match_dup 5)]
16387                               UNSPEC_FSCALE_FRACT))
16388               (set (match_dup 11)
16389                    (unspec:XF [(match_dup 9) (match_dup 5)]
16390                               UNSPEC_FSCALE_EXP))])
16391    (set (match_operand:SF 0 "register_operand" "")
16392         (float_truncate:SF (match_dup 10)))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16395    && flag_unsafe_math_optimizations"
16397   rtx temp;
16398   int i;
16400   for (i=2; i<12; i++)
16401     operands[i] = gen_reg_rtx (XFmode);
16402   temp = standard_80387_constant_rtx (6); /* fldl2t */
16403   emit_move_insn (operands[3], temp);
16404   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16407 (define_expand "exp10df2"
16408   [(set (match_dup 2)
16409         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16410    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16411    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16412    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16413    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16414    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16415    (parallel [(set (match_dup 10)
16416                    (unspec:XF [(match_dup 9) (match_dup 5)]
16417                               UNSPEC_FSCALE_FRACT))
16418               (set (match_dup 11)
16419                    (unspec:XF [(match_dup 9) (match_dup 5)]
16420                               UNSPEC_FSCALE_EXP))])
16421    (set (match_operand:DF 0 "register_operand" "")
16422         (float_truncate:DF (match_dup 10)))]
16423   "TARGET_USE_FANCY_MATH_387
16424    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16427   rtx temp;
16428   int i;
16430   for (i=2; i<12; i++)
16431     operands[i] = gen_reg_rtx (XFmode);
16432   temp = standard_80387_constant_rtx (6); /* fldl2t */
16433   emit_move_insn (operands[3], temp);
16434   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16437 (define_expand "exp10xf2"
16438   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16439                                (match_dup 2)))
16440    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16441    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16442    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16443    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16444    (parallel [(set (match_operand:XF 0 "register_operand" "")
16445                    (unspec:XF [(match_dup 8) (match_dup 4)]
16446                               UNSPEC_FSCALE_FRACT))
16447               (set (match_dup 9)
16448                    (unspec:XF [(match_dup 8) (match_dup 4)]
16449                               UNSPEC_FSCALE_EXP))])]
16450   "TARGET_USE_FANCY_MATH_387
16451    && flag_unsafe_math_optimizations"
16453   rtx temp;
16454   int i;
16456   for (i=2; i<10; i++)
16457     operands[i] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (6); /* fldl2t */
16459   emit_move_insn (operands[2], temp);
16460   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16463 (define_expand "exp2sf2"
16464   [(set (match_dup 2)
16465         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16466    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16467    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16468    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16469    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16470    (parallel [(set (match_dup 8)
16471                    (unspec:XF [(match_dup 7) (match_dup 3)]
16472                               UNSPEC_FSCALE_FRACT))
16473               (set (match_dup 9)
16474                    (unspec:XF [(match_dup 7) (match_dup 3)]
16475                               UNSPEC_FSCALE_EXP))])
16476    (set (match_operand:SF 0 "register_operand" "")
16477         (float_truncate:SF (match_dup 8)))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16482   int i;
16484   for (i=2; i<10; i++)
16485     operands[i] = gen_reg_rtx (XFmode);
16486   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16489 (define_expand "exp2df2"
16490   [(set (match_dup 2)
16491         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16492    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16493    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16494    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16495    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16496    (parallel [(set (match_dup 8)
16497                    (unspec:XF [(match_dup 7) (match_dup 3)]
16498                               UNSPEC_FSCALE_FRACT))
16499               (set (match_dup 9)
16500                    (unspec:XF [(match_dup 7) (match_dup 3)]
16501                               UNSPEC_FSCALE_EXP))])
16502    (set (match_operand:DF 0 "register_operand" "")
16503         (float_truncate:DF (match_dup 8)))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16506    && flag_unsafe_math_optimizations"
16508   int i;
16510   for (i=2; i<10; i++)
16511     operands[i] = gen_reg_rtx (XFmode);
16512   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16515 (define_expand "exp2xf2"
16516   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16517    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16518    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16519    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16520    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16521    (parallel [(set (match_operand:XF 0 "register_operand" "")
16522                    (unspec:XF [(match_dup 7) (match_dup 3)]
16523                               UNSPEC_FSCALE_FRACT))
16524               (set (match_dup 8)
16525                    (unspec:XF [(match_dup 7) (match_dup 3)]
16526                               UNSPEC_FSCALE_EXP))])]
16527   "TARGET_USE_FANCY_MATH_387
16528    && flag_unsafe_math_optimizations"
16530   int i;
16532   for (i=2; i<9; i++)
16533     operands[i] = gen_reg_rtx (XFmode);
16534   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16537 (define_expand "expm1df2"
16538   [(set (match_dup 2)
16539         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16540    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16541    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16542    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16543    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16544    (parallel [(set (match_dup 8)
16545                    (unspec:XF [(match_dup 7) (match_dup 5)]
16546                               UNSPEC_FSCALE_FRACT))
16547                    (set (match_dup 9)
16548                    (unspec:XF [(match_dup 7) (match_dup 5)]
16549                               UNSPEC_FSCALE_EXP))])
16550    (parallel [(set (match_dup 11)
16551                    (unspec:XF [(match_dup 10) (match_dup 9)]
16552                               UNSPEC_FSCALE_FRACT))
16553               (set (match_dup 12)
16554                    (unspec:XF [(match_dup 10) (match_dup 9)]
16555                               UNSPEC_FSCALE_EXP))])
16556    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16557    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16558    (set (match_operand:DF 0 "register_operand" "")
16559         (float_truncate:DF (match_dup 14)))]
16560   "TARGET_USE_FANCY_MATH_387
16561    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16562    && flag_unsafe_math_optimizations"
16564   rtx temp;
16565   int i;
16567   for (i=2; i<15; i++)
16568     operands[i] = gen_reg_rtx (XFmode);
16569   temp = standard_80387_constant_rtx (5); /* fldl2e */
16570   emit_move_insn (operands[3], temp);
16571   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16574 (define_expand "expm1sf2"
16575   [(set (match_dup 2)
16576         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16577    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16578    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16579    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16580    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16581    (parallel [(set (match_dup 8)
16582                    (unspec:XF [(match_dup 7) (match_dup 5)]
16583                               UNSPEC_FSCALE_FRACT))
16584                    (set (match_dup 9)
16585                    (unspec:XF [(match_dup 7) (match_dup 5)]
16586                               UNSPEC_FSCALE_EXP))])
16587    (parallel [(set (match_dup 11)
16588                    (unspec:XF [(match_dup 10) (match_dup 9)]
16589                               UNSPEC_FSCALE_FRACT))
16590               (set (match_dup 12)
16591                    (unspec:XF [(match_dup 10) (match_dup 9)]
16592                               UNSPEC_FSCALE_EXP))])
16593    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16594    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16595    (set (match_operand:SF 0 "register_operand" "")
16596         (float_truncate:SF (match_dup 14)))]
16597   "TARGET_USE_FANCY_MATH_387
16598    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16599    && flag_unsafe_math_optimizations"
16601   rtx temp;
16602   int i;
16604   for (i=2; i<15; i++)
16605     operands[i] = gen_reg_rtx (XFmode);
16606   temp = standard_80387_constant_rtx (5); /* fldl2e */
16607   emit_move_insn (operands[3], temp);
16608   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16611 (define_expand "expm1xf2"
16612   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16613                                (match_dup 2)))
16614    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16615    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16616    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16617    (parallel [(set (match_dup 7)
16618                    (unspec:XF [(match_dup 6) (match_dup 4)]
16619                               UNSPEC_FSCALE_FRACT))
16620                    (set (match_dup 8)
16621                    (unspec:XF [(match_dup 6) (match_dup 4)]
16622                               UNSPEC_FSCALE_EXP))])
16623    (parallel [(set (match_dup 10)
16624                    (unspec:XF [(match_dup 9) (match_dup 8)]
16625                               UNSPEC_FSCALE_FRACT))
16626               (set (match_dup 11)
16627                    (unspec:XF [(match_dup 9) (match_dup 8)]
16628                               UNSPEC_FSCALE_EXP))])
16629    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16630    (set (match_operand:XF 0 "register_operand" "")
16631         (plus:XF (match_dup 12) (match_dup 7)))]
16632   "TARGET_USE_FANCY_MATH_387
16633    && flag_unsafe_math_optimizations"
16635   rtx temp;
16636   int i;
16638   for (i=2; i<13; i++)
16639     operands[i] = gen_reg_rtx (XFmode);
16640   temp = standard_80387_constant_rtx (5); /* fldl2e */
16641   emit_move_insn (operands[2], temp);
16642   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16645 (define_expand "ldexpdf3"
16646   [(set (match_dup 3)
16647         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16648    (set (match_dup 4)
16649         (float:XF (match_operand:SI 2 "register_operand" "")))
16650    (parallel [(set (match_dup 5)
16651                    (unspec:XF [(match_dup 3) (match_dup 4)]
16652                               UNSPEC_FSCALE_FRACT))
16653               (set (match_dup 6)
16654                    (unspec:XF [(match_dup 3) (match_dup 4)]
16655                               UNSPEC_FSCALE_EXP))])
16656    (set (match_operand:DF 0 "register_operand" "")
16657         (float_truncate:DF (match_dup 5)))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16660    && flag_unsafe_math_optimizations"
16662   int i;
16664   for (i=3; i<7; i++)
16665     operands[i] = gen_reg_rtx (XFmode);
16668 (define_expand "ldexpsf3"
16669   [(set (match_dup 3)
16670         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16671    (set (match_dup 4)
16672         (float:XF (match_operand:SI 2 "register_operand" "")))
16673    (parallel [(set (match_dup 5)
16674                    (unspec:XF [(match_dup 3) (match_dup 4)]
16675                               UNSPEC_FSCALE_FRACT))
16676               (set (match_dup 6)
16677                    (unspec:XF [(match_dup 3) (match_dup 4)]
16678                               UNSPEC_FSCALE_EXP))])
16679    (set (match_operand:SF 0 "register_operand" "")
16680         (float_truncate:SF (match_dup 5)))]
16681   "TARGET_USE_FANCY_MATH_387
16682    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16683    && flag_unsafe_math_optimizations"
16685   int i;
16687   for (i=3; i<7; i++)
16688     operands[i] = gen_reg_rtx (XFmode);
16691 (define_expand "ldexpxf3"
16692   [(set (match_dup 3)
16693         (float:XF (match_operand:SI 2 "register_operand" "")))
16694    (parallel [(set (match_operand:XF 0 " register_operand" "")
16695                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16696                                (match_dup 3)]
16697                               UNSPEC_FSCALE_FRACT))
16698               (set (match_dup 4)
16699                    (unspec:XF [(match_dup 1) (match_dup 3)]
16700                               UNSPEC_FSCALE_EXP))])]
16701   "TARGET_USE_FANCY_MATH_387
16702    && flag_unsafe_math_optimizations"
16704   int i;
16706   for (i=3; i<5; i++)
16707     operands[i] = gen_reg_rtx (XFmode);
16711 (define_insn "frndintxf2"
16712   [(set (match_operand:XF 0 "register_operand" "=f")
16713         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16714          UNSPEC_FRNDINT))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && flag_unsafe_math_optimizations"
16717   "frndint"
16718   [(set_attr "type" "fpspc")
16719    (set_attr "mode" "XF")])
16721 (define_expand "rintdf2"
16722   [(use (match_operand:DF 0 "register_operand" ""))
16723    (use (match_operand:DF 1 "register_operand" ""))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16726    && flag_unsafe_math_optimizations"
16728   rtx op0 = gen_reg_rtx (XFmode);
16729   rtx op1 = gen_reg_rtx (XFmode);
16731   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16732   emit_insn (gen_frndintxf2 (op0, op1));
16734   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16735   DONE;
16738 (define_expand "rintsf2"
16739   [(use (match_operand:SF 0 "register_operand" ""))
16740    (use (match_operand:SF 1 "register_operand" ""))]
16741   "TARGET_USE_FANCY_MATH_387
16742    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16743    && flag_unsafe_math_optimizations"
16745   rtx op0 = gen_reg_rtx (XFmode);
16746   rtx op1 = gen_reg_rtx (XFmode);
16748   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16749   emit_insn (gen_frndintxf2 (op0, op1));
16751   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16752   DONE;
16755 (define_expand "rintxf2"
16756   [(use (match_operand:XF 0 "register_operand" ""))
16757    (use (match_operand:XF 1 "register_operand" ""))]
16758   "TARGET_USE_FANCY_MATH_387
16759    && flag_unsafe_math_optimizations"
16761   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16762   DONE;
16765 (define_insn_and_split "*fistdi2_1"
16766   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16767         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16768          UNSPEC_FIST))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && flag_unsafe_math_optimizations
16771    && !(reload_completed || reload_in_progress)"
16772   "#"
16773   "&& 1"
16774   [(const_int 0)]
16776   if (memory_operand (operands[0], VOIDmode))
16777     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16778   else
16779     {
16780       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16781       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16782                                          operands[2]));
16783     }
16784   DONE;
16786   [(set_attr "type" "fpspc")
16787    (set_attr "mode" "DI")])
16789 (define_insn "fistdi2"
16790   [(set (match_operand:DI 0 "memory_operand" "=m")
16791         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16792          UNSPEC_FIST))
16793    (clobber (match_scratch:XF 2 "=&1f"))]
16794   "TARGET_USE_FANCY_MATH_387
16795    && flag_unsafe_math_optimizations"
16796   "* return output_fix_trunc (insn, operands, 0);"
16797   [(set_attr "type" "fpspc")
16798    (set_attr "mode" "DI")])
16800 (define_insn "fistdi2_with_temp"
16801   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16802         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16803          UNSPEC_FIST))
16804    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16805    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16806   "TARGET_USE_FANCY_MATH_387
16807    && flag_unsafe_math_optimizations"
16808   "#"
16809   [(set_attr "type" "fpspc")
16810    (set_attr "mode" "DI")])
16812 (define_split 
16813   [(set (match_operand:DI 0 "register_operand" "")
16814         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16815          UNSPEC_FIST))
16816    (clobber (match_operand:DI 2 "memory_operand" ""))
16817    (clobber (match_scratch 3 ""))]
16818   "reload_completed"
16819   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16820               (clobber (match_dup 3))])
16821    (set (match_dup 0) (match_dup 2))]
16822   "")
16824 (define_split 
16825   [(set (match_operand:DI 0 "memory_operand" "")
16826         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16827          UNSPEC_FIST))
16828    (clobber (match_operand:DI 2 "memory_operand" ""))
16829    (clobber (match_scratch 3 ""))]
16830   "reload_completed"
16831   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16832               (clobber (match_dup 3))])]
16833   "")
16835 (define_insn_and_split "*fist<mode>2_1"
16836   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16837         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16838          UNSPEC_FIST))]
16839   "TARGET_USE_FANCY_MATH_387
16840    && flag_unsafe_math_optimizations
16841    && !(reload_completed || reload_in_progress)"
16842   "#"
16843   "&& 1"
16844   [(const_int 0)]
16846   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16847   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16848                                         operands[2]));
16849   DONE;
16851   [(set_attr "type" "fpspc")
16852    (set_attr "mode" "<MODE>")])
16854 (define_insn "fist<mode>2"
16855   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16856         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16857          UNSPEC_FIST))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && flag_unsafe_math_optimizations"
16860   "* return output_fix_trunc (insn, operands, 0);"
16861   [(set_attr "type" "fpspc")
16862    (set_attr "mode" "<MODE>")])
16864 (define_insn "fist<mode>2_with_temp"
16865   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16866         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16867          UNSPEC_FIST))
16868    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations"
16871   "#"
16872   [(set_attr "type" "fpspc")
16873    (set_attr "mode" "<MODE>")])
16875 (define_split 
16876   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16877         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16878          UNSPEC_FIST))
16879    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16880   "reload_completed"
16881   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16882                        UNSPEC_FIST))
16883    (set (match_dup 0) (match_dup 2))]
16884   "")
16886 (define_split 
16887   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16888         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16889          UNSPEC_FIST))
16890    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16891   "reload_completed"
16892   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16893                        UNSPEC_FIST))]
16894   "")
16896 (define_expand "lrint<mode>2"
16897   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16898         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16899          UNSPEC_FIST))]
16900   "TARGET_USE_FANCY_MATH_387
16901    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16902    && flag_unsafe_math_optimizations"
16903   "")
16905 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16906 (define_insn_and_split "frndintxf2_floor"
16907   [(set (match_operand:XF 0 "register_operand" "=f")
16908         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16909          UNSPEC_FRNDINT_FLOOR))
16910    (clobber (reg:CC FLAGS_REG))]
16911   "TARGET_USE_FANCY_MATH_387
16912    && flag_unsafe_math_optimizations
16913    && !(reload_completed || reload_in_progress)"
16914   "#"
16915   "&& 1"
16916   [(const_int 0)]
16918   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16920   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16921   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16923   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16924                                         operands[2], operands[3]));
16925   DONE;
16927   [(set_attr "type" "frndint")
16928    (set_attr "i387_cw" "floor")
16929    (set_attr "mode" "XF")])
16931 (define_insn "frndintxf2_floor_i387"
16932   [(set (match_operand:XF 0 "register_operand" "=f")
16933         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16934          UNSPEC_FRNDINT_FLOOR))
16935    (use (match_operand:HI 2 "memory_operand" "m"))
16936    (use (match_operand:HI 3 "memory_operand" "m"))]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations"
16939   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16940   [(set_attr "type" "frndint")
16941    (set_attr "i387_cw" "floor")
16942    (set_attr "mode" "XF")])
16944 (define_expand "floorxf2"
16945   [(use (match_operand:XF 0 "register_operand" ""))
16946    (use (match_operand:XF 1 "register_operand" ""))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && flag_unsafe_math_optimizations"
16950   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16951   DONE;
16954 (define_expand "floordf2"
16955   [(use (match_operand:DF 0 "register_operand" ""))
16956    (use (match_operand:DF 1 "register_operand" ""))]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16959    && flag_unsafe_math_optimizations"
16961   rtx op0 = gen_reg_rtx (XFmode);
16962   rtx op1 = gen_reg_rtx (XFmode);
16964   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16965   emit_insn (gen_frndintxf2_floor (op0, op1));
16967   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16968   DONE;
16971 (define_expand "floorsf2"
16972   [(use (match_operand:SF 0 "register_operand" ""))
16973    (use (match_operand:SF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16976    && flag_unsafe_math_optimizations"
16978   rtx op0 = gen_reg_rtx (XFmode);
16979   rtx op1 = gen_reg_rtx (XFmode);
16981   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16982   emit_insn (gen_frndintxf2_floor (op0, op1));
16984   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16985   DONE;
16988 (define_insn_and_split "*fist<mode>2_floor_1"
16989   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16990         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16991          UNSPEC_FIST_FLOOR))
16992    (clobber (reg:CC FLAGS_REG))]
16993   "TARGET_USE_FANCY_MATH_387
16994    && flag_unsafe_math_optimizations
16995    && !(reload_completed || reload_in_progress)"
16996   "#"
16997   "&& 1"
16998   [(const_int 0)]
17000   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17002   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17003   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17004   if (memory_operand (operands[0], VOIDmode))
17005     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17006                                       operands[2], operands[3]));
17007   else
17008     {
17009       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17010       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17011                                                   operands[2], operands[3],
17012                                                   operands[4]));
17013     }
17014   DONE;
17016   [(set_attr "type" "fistp")
17017    (set_attr "i387_cw" "floor")
17018    (set_attr "mode" "<MODE>")])
17020 (define_insn "fistdi2_floor"
17021   [(set (match_operand:DI 0 "memory_operand" "=m")
17022         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17023          UNSPEC_FIST_FLOOR))
17024    (use (match_operand:HI 2 "memory_operand" "m"))
17025    (use (match_operand:HI 3 "memory_operand" "m"))
17026    (clobber (match_scratch:XF 4 "=&1f"))]
17027   "TARGET_USE_FANCY_MATH_387
17028    && flag_unsafe_math_optimizations"
17029   "* return output_fix_trunc (insn, operands, 0);"
17030   [(set_attr "type" "fistp")
17031    (set_attr "i387_cw" "floor")
17032    (set_attr "mode" "DI")])
17034 (define_insn "fistdi2_floor_with_temp"
17035   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17036         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17037          UNSPEC_FIST_FLOOR))
17038    (use (match_operand:HI 2 "memory_operand" "m,m"))
17039    (use (match_operand:HI 3 "memory_operand" "m,m"))
17040    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17041    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations"
17044   "#"
17045   [(set_attr "type" "fistp")
17046    (set_attr "i387_cw" "floor")
17047    (set_attr "mode" "DI")])
17049 (define_split 
17050   [(set (match_operand:DI 0 "register_operand" "")
17051         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17052          UNSPEC_FIST_FLOOR))
17053    (use (match_operand:HI 2 "memory_operand" ""))
17054    (use (match_operand:HI 3 "memory_operand" ""))
17055    (clobber (match_operand:DI 4 "memory_operand" ""))
17056    (clobber (match_scratch 5 ""))]
17057   "reload_completed"
17058   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17059               (use (match_dup 2))
17060               (use (match_dup 3))
17061               (clobber (match_dup 5))])
17062    (set (match_dup 0) (match_dup 4))]
17063   "")
17065 (define_split 
17066   [(set (match_operand:DI 0 "memory_operand" "")
17067         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17068          UNSPEC_FIST_FLOOR))
17069    (use (match_operand:HI 2 "memory_operand" ""))
17070    (use (match_operand:HI 3 "memory_operand" ""))
17071    (clobber (match_operand:DI 4 "memory_operand" ""))
17072    (clobber (match_scratch 5 ""))]
17073   "reload_completed"
17074   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17075               (use (match_dup 2))
17076               (use (match_dup 3))
17077               (clobber (match_dup 5))])]
17078   "")
17080 (define_insn "fist<mode>2_floor"
17081   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17082         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17083          UNSPEC_FIST_FLOOR))
17084    (use (match_operand:HI 2 "memory_operand" "m"))
17085    (use (match_operand:HI 3 "memory_operand" "m"))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations"
17088   "* return output_fix_trunc (insn, operands, 0);"
17089   [(set_attr "type" "fistp")
17090    (set_attr "i387_cw" "floor")
17091    (set_attr "mode" "<MODE>")])
17093 (define_insn "fist<mode>2_floor_with_temp"
17094   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17095         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17096          UNSPEC_FIST_FLOOR))
17097    (use (match_operand:HI 2 "memory_operand" "m,m"))
17098    (use (match_operand:HI 3 "memory_operand" "m,m"))
17099    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17100   "TARGET_USE_FANCY_MATH_387
17101    && flag_unsafe_math_optimizations"
17102   "#"
17103   [(set_attr "type" "fistp")
17104    (set_attr "i387_cw" "floor")
17105    (set_attr "mode" "<MODE>")])
17107 (define_split 
17108   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17109         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17110          UNSPEC_FIST_FLOOR))
17111    (use (match_operand:HI 2 "memory_operand" ""))
17112    (use (match_operand:HI 3 "memory_operand" ""))
17113    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17114   "reload_completed"
17115   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17116                                   UNSPEC_FIST_FLOOR))
17117               (use (match_dup 2))
17118               (use (match_dup 3))])
17119    (set (match_dup 0) (match_dup 4))]
17120   "")
17122 (define_split 
17123   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17124         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17125          UNSPEC_FIST_FLOOR))
17126    (use (match_operand:HI 2 "memory_operand" ""))
17127    (use (match_operand:HI 3 "memory_operand" ""))
17128    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17129   "reload_completed"
17130   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17131                                   UNSPEC_FIST_FLOOR))
17132               (use (match_dup 2))
17133               (use (match_dup 3))])]
17134   "")
17136 (define_expand "lfloor<mode>2"
17137   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17138                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17139                     UNSPEC_FIST_FLOOR))
17140               (clobber (reg:CC FLAGS_REG))])]
17141   "TARGET_USE_FANCY_MATH_387
17142    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17143    && flag_unsafe_math_optimizations"
17144   "")
17146 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17147 (define_insn_and_split "frndintxf2_ceil"
17148   [(set (match_operand:XF 0 "register_operand" "=f")
17149         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17150          UNSPEC_FRNDINT_CEIL))
17151    (clobber (reg:CC FLAGS_REG))]
17152   "TARGET_USE_FANCY_MATH_387
17153    && flag_unsafe_math_optimizations
17154    && !(reload_completed || reload_in_progress)"
17155   "#"
17156   "&& 1"
17157   [(const_int 0)]
17159   ix86_optimize_mode_switching[I387_CEIL] = 1;
17161   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17162   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17164   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17165                                        operands[2], operands[3]));
17166   DONE;
17168   [(set_attr "type" "frndint")
17169    (set_attr "i387_cw" "ceil")
17170    (set_attr "mode" "XF")])
17172 (define_insn "frndintxf2_ceil_i387"
17173   [(set (match_operand:XF 0 "register_operand" "=f")
17174         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17175          UNSPEC_FRNDINT_CEIL))
17176    (use (match_operand:HI 2 "memory_operand" "m"))
17177    (use (match_operand:HI 3 "memory_operand" "m"))]
17178   "TARGET_USE_FANCY_MATH_387
17179    && flag_unsafe_math_optimizations"
17180   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17181   [(set_attr "type" "frndint")
17182    (set_attr "i387_cw" "ceil")
17183    (set_attr "mode" "XF")])
17185 (define_expand "ceilxf2"
17186   [(use (match_operand:XF 0 "register_operand" ""))
17187    (use (match_operand:XF 1 "register_operand" ""))]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations"
17191   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17192   DONE;
17195 (define_expand "ceildf2"
17196   [(use (match_operand:DF 0 "register_operand" ""))
17197    (use (match_operand:DF 1 "register_operand" ""))]
17198   "TARGET_USE_FANCY_MATH_387
17199    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17200    && flag_unsafe_math_optimizations"
17202   rtx op0 = gen_reg_rtx (XFmode);
17203   rtx op1 = gen_reg_rtx (XFmode);
17205   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17206   emit_insn (gen_frndintxf2_ceil (op0, op1));
17208   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17209   DONE;
17212 (define_expand "ceilsf2"
17213   [(use (match_operand:SF 0 "register_operand" ""))
17214    (use (match_operand:SF 1 "register_operand" ""))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17217    && flag_unsafe_math_optimizations"
17219   rtx op0 = gen_reg_rtx (XFmode);
17220   rtx op1 = gen_reg_rtx (XFmode);
17222   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17223   emit_insn (gen_frndintxf2_ceil (op0, op1));
17225   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17226   DONE;
17229 (define_insn_and_split "*fist<mode>2_ceil_1"
17230   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17231         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17232          UNSPEC_FIST_CEIL))
17233    (clobber (reg:CC FLAGS_REG))]
17234   "TARGET_USE_FANCY_MATH_387
17235    && flag_unsafe_math_optimizations
17236    && !(reload_completed || reload_in_progress)"
17237   "#"
17238   "&& 1"
17239   [(const_int 0)]
17241   ix86_optimize_mode_switching[I387_CEIL] = 1;
17243   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17244   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17245   if (memory_operand (operands[0], VOIDmode))
17246     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17247                                      operands[2], operands[3]));
17248   else
17249     {
17250       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17251       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17252                                                  operands[2], operands[3],
17253                                                  operands[4]));
17254     }
17255   DONE;
17257   [(set_attr "type" "fistp")
17258    (set_attr "i387_cw" "ceil")
17259    (set_attr "mode" "<MODE>")])
17261 (define_insn "fistdi2_ceil"
17262   [(set (match_operand:DI 0 "memory_operand" "=m")
17263         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17264          UNSPEC_FIST_CEIL))
17265    (use (match_operand:HI 2 "memory_operand" "m"))
17266    (use (match_operand:HI 3 "memory_operand" "m"))
17267    (clobber (match_scratch:XF 4 "=&1f"))]
17268   "TARGET_USE_FANCY_MATH_387
17269    && flag_unsafe_math_optimizations"
17270   "* return output_fix_trunc (insn, operands, 0);"
17271   [(set_attr "type" "fistp")
17272    (set_attr "i387_cw" "ceil")
17273    (set_attr "mode" "DI")])
17275 (define_insn "fistdi2_ceil_with_temp"
17276   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17277         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17278          UNSPEC_FIST_CEIL))
17279    (use (match_operand:HI 2 "memory_operand" "m,m"))
17280    (use (match_operand:HI 3 "memory_operand" "m,m"))
17281    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17282    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17283   "TARGET_USE_FANCY_MATH_387
17284    && flag_unsafe_math_optimizations"
17285   "#"
17286   [(set_attr "type" "fistp")
17287    (set_attr "i387_cw" "ceil")
17288    (set_attr "mode" "DI")])
17290 (define_split 
17291   [(set (match_operand:DI 0 "register_operand" "")
17292         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17293          UNSPEC_FIST_CEIL))
17294    (use (match_operand:HI 2 "memory_operand" ""))
17295    (use (match_operand:HI 3 "memory_operand" ""))
17296    (clobber (match_operand:DI 4 "memory_operand" ""))
17297    (clobber (match_scratch 5 ""))]
17298   "reload_completed"
17299   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17300               (use (match_dup 2))
17301               (use (match_dup 3))
17302               (clobber (match_dup 5))])
17303    (set (match_dup 0) (match_dup 4))]
17304   "")
17306 (define_split 
17307   [(set (match_operand:DI 0 "memory_operand" "")
17308         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17309          UNSPEC_FIST_CEIL))
17310    (use (match_operand:HI 2 "memory_operand" ""))
17311    (use (match_operand:HI 3 "memory_operand" ""))
17312    (clobber (match_operand:DI 4 "memory_operand" ""))
17313    (clobber (match_scratch 5 ""))]
17314   "reload_completed"
17315   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17316               (use (match_dup 2))
17317               (use (match_dup 3))
17318               (clobber (match_dup 5))])]
17319   "")
17321 (define_insn "fist<mode>2_ceil"
17322   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17323         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17324          UNSPEC_FIST_CEIL))
17325    (use (match_operand:HI 2 "memory_operand" "m"))
17326    (use (match_operand:HI 3 "memory_operand" "m"))]
17327   "TARGET_USE_FANCY_MATH_387
17328    && flag_unsafe_math_optimizations"
17329   "* return output_fix_trunc (insn, operands, 0);"
17330   [(set_attr "type" "fistp")
17331    (set_attr "i387_cw" "ceil")
17332    (set_attr "mode" "<MODE>")])
17334 (define_insn "fist<mode>2_ceil_with_temp"
17335   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17336         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17337          UNSPEC_FIST_CEIL))
17338    (use (match_operand:HI 2 "memory_operand" "m,m"))
17339    (use (match_operand:HI 3 "memory_operand" "m,m"))
17340    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && flag_unsafe_math_optimizations"
17343   "#"
17344   [(set_attr "type" "fistp")
17345    (set_attr "i387_cw" "ceil")
17346    (set_attr "mode" "<MODE>")])
17348 (define_split 
17349   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17350         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17351          UNSPEC_FIST_CEIL))
17352    (use (match_operand:HI 2 "memory_operand" ""))
17353    (use (match_operand:HI 3 "memory_operand" ""))
17354    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17355   "reload_completed"
17356   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17357                                   UNSPEC_FIST_CEIL))
17358               (use (match_dup 2))
17359               (use (match_dup 3))])
17360    (set (match_dup 0) (match_dup 4))]
17361   "")
17363 (define_split 
17364   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17365         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17366          UNSPEC_FIST_CEIL))
17367    (use (match_operand:HI 2 "memory_operand" ""))
17368    (use (match_operand:HI 3 "memory_operand" ""))
17369    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17370   "reload_completed"
17371   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17372                                   UNSPEC_FIST_CEIL))
17373               (use (match_dup 2))
17374               (use (match_dup 3))])]
17375   "")
17377 (define_expand "lceil<mode>2"
17378   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17379                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17380                     UNSPEC_FIST_CEIL))
17381               (clobber (reg:CC FLAGS_REG))])]
17382   "TARGET_USE_FANCY_MATH_387
17383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17384    && flag_unsafe_math_optimizations"
17385   "")
17387 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17388 (define_insn_and_split "frndintxf2_trunc"
17389   [(set (match_operand:XF 0 "register_operand" "=f")
17390         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17391          UNSPEC_FRNDINT_TRUNC))
17392    (clobber (reg:CC FLAGS_REG))]
17393   "TARGET_USE_FANCY_MATH_387
17394    && flag_unsafe_math_optimizations
17395    && !(reload_completed || reload_in_progress)"
17396   "#"
17397   "&& 1"
17398   [(const_int 0)]
17400   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17402   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17403   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17405   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17406                                         operands[2], operands[3]));
17407   DONE;
17409   [(set_attr "type" "frndint")
17410    (set_attr "i387_cw" "trunc")
17411    (set_attr "mode" "XF")])
17413 (define_insn "frndintxf2_trunc_i387"
17414   [(set (match_operand:XF 0 "register_operand" "=f")
17415         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17416          UNSPEC_FRNDINT_TRUNC))
17417    (use (match_operand:HI 2 "memory_operand" "m"))
17418    (use (match_operand:HI 3 "memory_operand" "m"))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && flag_unsafe_math_optimizations"
17421   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17422   [(set_attr "type" "frndint")
17423    (set_attr "i387_cw" "trunc")
17424    (set_attr "mode" "XF")])
17426 (define_expand "btruncxf2"
17427   [(use (match_operand:XF 0 "register_operand" ""))
17428    (use (match_operand:XF 1 "register_operand" ""))]
17429   "TARGET_USE_FANCY_MATH_387
17430    && flag_unsafe_math_optimizations"
17432   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17433   DONE;
17436 (define_expand "btruncdf2"
17437   [(use (match_operand:DF 0 "register_operand" ""))
17438    (use (match_operand:DF 1 "register_operand" ""))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17441    && flag_unsafe_math_optimizations"
17443   rtx op0 = gen_reg_rtx (XFmode);
17444   rtx op1 = gen_reg_rtx (XFmode);
17446   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17447   emit_insn (gen_frndintxf2_trunc (op0, op1));
17449   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17450   DONE;
17453 (define_expand "btruncsf2"
17454   [(use (match_operand:SF 0 "register_operand" ""))
17455    (use (match_operand:SF 1 "register_operand" ""))]
17456   "TARGET_USE_FANCY_MATH_387
17457    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17458    && flag_unsafe_math_optimizations"
17460   rtx op0 = gen_reg_rtx (XFmode);
17461   rtx op1 = gen_reg_rtx (XFmode);
17463   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17464   emit_insn (gen_frndintxf2_trunc (op0, op1));
17466   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17467   DONE;
17470 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17471 (define_insn_and_split "frndintxf2_mask_pm"
17472   [(set (match_operand:XF 0 "register_operand" "=f")
17473         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17474          UNSPEC_FRNDINT_MASK_PM))
17475    (clobber (reg:CC FLAGS_REG))]
17476   "TARGET_USE_FANCY_MATH_387
17477    && flag_unsafe_math_optimizations
17478    && !(reload_completed || reload_in_progress)"
17479   "#"
17480   "&& 1"
17481   [(const_int 0)]
17483   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17485   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17486   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17488   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17489                                           operands[2], operands[3]));
17490   DONE;
17492   [(set_attr "type" "frndint")
17493    (set_attr "i387_cw" "mask_pm")
17494    (set_attr "mode" "XF")])
17496 (define_insn "frndintxf2_mask_pm_i387"
17497   [(set (match_operand:XF 0 "register_operand" "=f")
17498         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17499          UNSPEC_FRNDINT_MASK_PM))
17500    (use (match_operand:HI 2 "memory_operand" "m"))
17501    (use (match_operand:HI 3 "memory_operand" "m"))]
17502   "TARGET_USE_FANCY_MATH_387
17503    && flag_unsafe_math_optimizations"
17504   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17505   [(set_attr "type" "frndint")
17506    (set_attr "i387_cw" "mask_pm")
17507    (set_attr "mode" "XF")])
17509 (define_expand "nearbyintxf2"
17510   [(use (match_operand:XF 0 "register_operand" ""))
17511    (use (match_operand:XF 1 "register_operand" ""))]
17512   "TARGET_USE_FANCY_MATH_387
17513    && flag_unsafe_math_optimizations"
17515   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17517   DONE;
17520 (define_expand "nearbyintdf2"
17521   [(use (match_operand:DF 0 "register_operand" ""))
17522    (use (match_operand:DF 1 "register_operand" ""))]
17523   "TARGET_USE_FANCY_MATH_387
17524    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17525    && flag_unsafe_math_optimizations"
17527   rtx op0 = gen_reg_rtx (XFmode);
17528   rtx op1 = gen_reg_rtx (XFmode);
17530   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17531   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17533   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17534   DONE;
17537 (define_expand "nearbyintsf2"
17538   [(use (match_operand:SF 0 "register_operand" ""))
17539    (use (match_operand:SF 1 "register_operand" ""))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17542    && flag_unsafe_math_optimizations"
17544   rtx op0 = gen_reg_rtx (XFmode);
17545   rtx op1 = gen_reg_rtx (XFmode);
17547   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17548   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17550   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17551   DONE;
17555 ;; Block operation instructions
17557 (define_insn "cld"
17558  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17559  ""
17560  "cld"
17561   [(set_attr "type" "cld")])
17563 (define_expand "movmemsi"
17564   [(use (match_operand:BLK 0 "memory_operand" ""))
17565    (use (match_operand:BLK 1 "memory_operand" ""))
17566    (use (match_operand:SI 2 "nonmemory_operand" ""))
17567    (use (match_operand:SI 3 "const_int_operand" ""))]
17568   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17570  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17571    DONE;
17572  else
17573    FAIL;
17576 (define_expand "movmemdi"
17577   [(use (match_operand:BLK 0 "memory_operand" ""))
17578    (use (match_operand:BLK 1 "memory_operand" ""))
17579    (use (match_operand:DI 2 "nonmemory_operand" ""))
17580    (use (match_operand:DI 3 "const_int_operand" ""))]
17581   "TARGET_64BIT"
17583  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17584    DONE;
17585  else
17586    FAIL;
17589 ;; Most CPUs don't like single string operations
17590 ;; Handle this case here to simplify previous expander.
17592 (define_expand "strmov"
17593   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17594    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17595    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17596               (clobber (reg:CC FLAGS_REG))])
17597    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17598               (clobber (reg:CC FLAGS_REG))])]
17599   ""
17601   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17603   /* If .md ever supports :P for Pmode, these can be directly
17604      in the pattern above.  */
17605   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17606   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17608   if (TARGET_SINGLE_STRINGOP || optimize_size)
17609     {
17610       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17611                                       operands[2], operands[3],
17612                                       operands[5], operands[6]));
17613       DONE;
17614     }
17616   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17619 (define_expand "strmov_singleop"
17620   [(parallel [(set (match_operand 1 "memory_operand" "")
17621                    (match_operand 3 "memory_operand" ""))
17622               (set (match_operand 0 "register_operand" "")
17623                    (match_operand 4 "" ""))
17624               (set (match_operand 2 "register_operand" "")
17625                    (match_operand 5 "" ""))
17626               (use (reg:SI DIRFLAG_REG))])]
17627   "TARGET_SINGLE_STRINGOP || optimize_size"
17628   "")
17630 (define_insn "*strmovdi_rex_1"
17631   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17632         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17633    (set (match_operand:DI 0 "register_operand" "=D")
17634         (plus:DI (match_dup 2)
17635                  (const_int 8)))
17636    (set (match_operand:DI 1 "register_operand" "=S")
17637         (plus:DI (match_dup 3)
17638                  (const_int 8)))
17639    (use (reg:SI DIRFLAG_REG))]
17640   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17641   "movsq"
17642   [(set_attr "type" "str")
17643    (set_attr "mode" "DI")
17644    (set_attr "memory" "both")])
17646 (define_insn "*strmovsi_1"
17647   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17648         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17649    (set (match_operand:SI 0 "register_operand" "=D")
17650         (plus:SI (match_dup 2)
17651                  (const_int 4)))
17652    (set (match_operand:SI 1 "register_operand" "=S")
17653         (plus:SI (match_dup 3)
17654                  (const_int 4)))
17655    (use (reg:SI DIRFLAG_REG))]
17656   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17657   "{movsl|movsd}"
17658   [(set_attr "type" "str")
17659    (set_attr "mode" "SI")
17660    (set_attr "memory" "both")])
17662 (define_insn "*strmovsi_rex_1"
17663   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17664         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17665    (set (match_operand:DI 0 "register_operand" "=D")
17666         (plus:DI (match_dup 2)
17667                  (const_int 4)))
17668    (set (match_operand:DI 1 "register_operand" "=S")
17669         (plus:DI (match_dup 3)
17670                  (const_int 4)))
17671    (use (reg:SI DIRFLAG_REG))]
17672   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17673   "{movsl|movsd}"
17674   [(set_attr "type" "str")
17675    (set_attr "mode" "SI")
17676    (set_attr "memory" "both")])
17678 (define_insn "*strmovhi_1"
17679   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17680         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17681    (set (match_operand:SI 0 "register_operand" "=D")
17682         (plus:SI (match_dup 2)
17683                  (const_int 2)))
17684    (set (match_operand:SI 1 "register_operand" "=S")
17685         (plus:SI (match_dup 3)
17686                  (const_int 2)))
17687    (use (reg:SI DIRFLAG_REG))]
17688   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17689   "movsw"
17690   [(set_attr "type" "str")
17691    (set_attr "memory" "both")
17692    (set_attr "mode" "HI")])
17694 (define_insn "*strmovhi_rex_1"
17695   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17696         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17697    (set (match_operand:DI 0 "register_operand" "=D")
17698         (plus:DI (match_dup 2)
17699                  (const_int 2)))
17700    (set (match_operand:DI 1 "register_operand" "=S")
17701         (plus:DI (match_dup 3)
17702                  (const_int 2)))
17703    (use (reg:SI DIRFLAG_REG))]
17704   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17705   "movsw"
17706   [(set_attr "type" "str")
17707    (set_attr "memory" "both")
17708    (set_attr "mode" "HI")])
17710 (define_insn "*strmovqi_1"
17711   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17712         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17713    (set (match_operand:SI 0 "register_operand" "=D")
17714         (plus:SI (match_dup 2)
17715                  (const_int 1)))
17716    (set (match_operand:SI 1 "register_operand" "=S")
17717         (plus:SI (match_dup 3)
17718                  (const_int 1)))
17719    (use (reg:SI DIRFLAG_REG))]
17720   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17721   "movsb"
17722   [(set_attr "type" "str")
17723    (set_attr "memory" "both")
17724    (set_attr "mode" "QI")])
17726 (define_insn "*strmovqi_rex_1"
17727   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17728         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17729    (set (match_operand:DI 0 "register_operand" "=D")
17730         (plus:DI (match_dup 2)
17731                  (const_int 1)))
17732    (set (match_operand:DI 1 "register_operand" "=S")
17733         (plus:DI (match_dup 3)
17734                  (const_int 1)))
17735    (use (reg:SI DIRFLAG_REG))]
17736   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17737   "movsb"
17738   [(set_attr "type" "str")
17739    (set_attr "memory" "both")
17740    (set_attr "mode" "QI")])
17742 (define_expand "rep_mov"
17743   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17744               (set (match_operand 0 "register_operand" "")
17745                    (match_operand 5 "" ""))
17746               (set (match_operand 2 "register_operand" "")
17747                    (match_operand 6 "" ""))
17748               (set (match_operand 1 "memory_operand" "")
17749                    (match_operand 3 "memory_operand" ""))
17750               (use (match_dup 4))
17751               (use (reg:SI DIRFLAG_REG))])]
17752   ""
17753   "")
17755 (define_insn "*rep_movdi_rex64"
17756   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17757    (set (match_operand:DI 0 "register_operand" "=D") 
17758         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17759                             (const_int 3))
17760                  (match_operand:DI 3 "register_operand" "0")))
17761    (set (match_operand:DI 1 "register_operand" "=S") 
17762         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17763                  (match_operand:DI 4 "register_operand" "1")))
17764    (set (mem:BLK (match_dup 3))
17765         (mem:BLK (match_dup 4)))
17766    (use (match_dup 5))
17767    (use (reg:SI DIRFLAG_REG))]
17768   "TARGET_64BIT"
17769   "{rep\;movsq|rep movsq}"
17770   [(set_attr "type" "str")
17771    (set_attr "prefix_rep" "1")
17772    (set_attr "memory" "both")
17773    (set_attr "mode" "DI")])
17775 (define_insn "*rep_movsi"
17776   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17777    (set (match_operand:SI 0 "register_operand" "=D") 
17778         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17779                             (const_int 2))
17780                  (match_operand:SI 3 "register_operand" "0")))
17781    (set (match_operand:SI 1 "register_operand" "=S") 
17782         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17783                  (match_operand:SI 4 "register_operand" "1")))
17784    (set (mem:BLK (match_dup 3))
17785         (mem:BLK (match_dup 4)))
17786    (use (match_dup 5))
17787    (use (reg:SI DIRFLAG_REG))]
17788   "!TARGET_64BIT"
17789   "{rep\;movsl|rep movsd}"
17790   [(set_attr "type" "str")
17791    (set_attr "prefix_rep" "1")
17792    (set_attr "memory" "both")
17793    (set_attr "mode" "SI")])
17795 (define_insn "*rep_movsi_rex64"
17796   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17797    (set (match_operand:DI 0 "register_operand" "=D") 
17798         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17799                             (const_int 2))
17800                  (match_operand:DI 3 "register_operand" "0")))
17801    (set (match_operand:DI 1 "register_operand" "=S") 
17802         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17803                  (match_operand:DI 4 "register_operand" "1")))
17804    (set (mem:BLK (match_dup 3))
17805         (mem:BLK (match_dup 4)))
17806    (use (match_dup 5))
17807    (use (reg:SI DIRFLAG_REG))]
17808   "TARGET_64BIT"
17809   "{rep\;movsl|rep movsd}"
17810   [(set_attr "type" "str")
17811    (set_attr "prefix_rep" "1")
17812    (set_attr "memory" "both")
17813    (set_attr "mode" "SI")])
17815 (define_insn "*rep_movqi"
17816   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17817    (set (match_operand:SI 0 "register_operand" "=D") 
17818         (plus:SI (match_operand:SI 3 "register_operand" "0")
17819                  (match_operand:SI 5 "register_operand" "2")))
17820    (set (match_operand:SI 1 "register_operand" "=S") 
17821         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17822    (set (mem:BLK (match_dup 3))
17823         (mem:BLK (match_dup 4)))
17824    (use (match_dup 5))
17825    (use (reg:SI DIRFLAG_REG))]
17826   "!TARGET_64BIT"
17827   "{rep\;movsb|rep movsb}"
17828   [(set_attr "type" "str")
17829    (set_attr "prefix_rep" "1")
17830    (set_attr "memory" "both")
17831    (set_attr "mode" "SI")])
17833 (define_insn "*rep_movqi_rex64"
17834   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17835    (set (match_operand:DI 0 "register_operand" "=D") 
17836         (plus:DI (match_operand:DI 3 "register_operand" "0")
17837                  (match_operand:DI 5 "register_operand" "2")))
17838    (set (match_operand:DI 1 "register_operand" "=S") 
17839         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17840    (set (mem:BLK (match_dup 3))
17841         (mem:BLK (match_dup 4)))
17842    (use (match_dup 5))
17843    (use (reg:SI DIRFLAG_REG))]
17844   "TARGET_64BIT"
17845   "{rep\;movsb|rep movsb}"
17846   [(set_attr "type" "str")
17847    (set_attr "prefix_rep" "1")
17848    (set_attr "memory" "both")
17849    (set_attr "mode" "SI")])
17851 (define_expand "setmemsi"
17852    [(use (match_operand:BLK 0 "memory_operand" ""))
17853     (use (match_operand:SI 1 "nonmemory_operand" ""))
17854     (use (match_operand 2 "const_int_operand" ""))
17855     (use (match_operand 3 "const_int_operand" ""))]
17856   ""
17858  /* If value to set is not zero, use the library routine.  */
17859  if (operands[2] != const0_rtx)
17860    FAIL;
17862  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17863    DONE;
17864  else
17865    FAIL;
17868 (define_expand "setmemdi"
17869    [(use (match_operand:BLK 0 "memory_operand" ""))
17870     (use (match_operand:DI 1 "nonmemory_operand" ""))
17871     (use (match_operand 2 "const_int_operand" ""))
17872     (use (match_operand 3 "const_int_operand" ""))]
17873   "TARGET_64BIT"
17875  /* If value to set is not zero, use the library routine.  */
17876  if (operands[2] != const0_rtx)
17877    FAIL;
17879  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17880    DONE;
17881  else
17882    FAIL;
17885 ;; Most CPUs don't like single string operations
17886 ;; Handle this case here to simplify previous expander.
17888 (define_expand "strset"
17889   [(set (match_operand 1 "memory_operand" "")
17890         (match_operand 2 "register_operand" ""))
17891    (parallel [(set (match_operand 0 "register_operand" "")
17892                    (match_dup 3))
17893               (clobber (reg:CC FLAGS_REG))])]
17894   ""
17896   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17897     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17899   /* If .md ever supports :P for Pmode, this can be directly
17900      in the pattern above.  */
17901   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17902                               GEN_INT (GET_MODE_SIZE (GET_MODE
17903                                                       (operands[2]))));
17904   if (TARGET_SINGLE_STRINGOP || optimize_size)
17905     {
17906       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17907                                       operands[3]));
17908       DONE;
17909     }
17912 (define_expand "strset_singleop"
17913   [(parallel [(set (match_operand 1 "memory_operand" "")
17914                    (match_operand 2 "register_operand" ""))
17915               (set (match_operand 0 "register_operand" "")
17916                    (match_operand 3 "" ""))
17917               (use (reg:SI DIRFLAG_REG))])]
17918   "TARGET_SINGLE_STRINGOP || optimize_size"
17919   "")
17921 (define_insn "*strsetdi_rex_1"
17922   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17923         (match_operand:DI 2 "register_operand" "a"))
17924    (set (match_operand:DI 0 "register_operand" "=D")
17925         (plus:DI (match_dup 1)
17926                  (const_int 8)))
17927    (use (reg:SI DIRFLAG_REG))]
17928   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17929   "stosq"
17930   [(set_attr "type" "str")
17931    (set_attr "memory" "store")
17932    (set_attr "mode" "DI")])
17934 (define_insn "*strsetsi_1"
17935   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17936         (match_operand:SI 2 "register_operand" "a"))
17937    (set (match_operand:SI 0 "register_operand" "=D")
17938         (plus:SI (match_dup 1)
17939                  (const_int 4)))
17940    (use (reg:SI DIRFLAG_REG))]
17941   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17942   "{stosl|stosd}"
17943   [(set_attr "type" "str")
17944    (set_attr "memory" "store")
17945    (set_attr "mode" "SI")])
17947 (define_insn "*strsetsi_rex_1"
17948   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17949         (match_operand:SI 2 "register_operand" "a"))
17950    (set (match_operand:DI 0 "register_operand" "=D")
17951         (plus:DI (match_dup 1)
17952                  (const_int 4)))
17953    (use (reg:SI DIRFLAG_REG))]
17954   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17955   "{stosl|stosd}"
17956   [(set_attr "type" "str")
17957    (set_attr "memory" "store")
17958    (set_attr "mode" "SI")])
17960 (define_insn "*strsethi_1"
17961   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17962         (match_operand:HI 2 "register_operand" "a"))
17963    (set (match_operand:SI 0 "register_operand" "=D")
17964         (plus:SI (match_dup 1)
17965                  (const_int 2)))
17966    (use (reg:SI DIRFLAG_REG))]
17967   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17968   "stosw"
17969   [(set_attr "type" "str")
17970    (set_attr "memory" "store")
17971    (set_attr "mode" "HI")])
17973 (define_insn "*strsethi_rex_1"
17974   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17975         (match_operand:HI 2 "register_operand" "a"))
17976    (set (match_operand:DI 0 "register_operand" "=D")
17977         (plus:DI (match_dup 1)
17978                  (const_int 2)))
17979    (use (reg:SI DIRFLAG_REG))]
17980   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17981   "stosw"
17982   [(set_attr "type" "str")
17983    (set_attr "memory" "store")
17984    (set_attr "mode" "HI")])
17986 (define_insn "*strsetqi_1"
17987   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17988         (match_operand:QI 2 "register_operand" "a"))
17989    (set (match_operand:SI 0 "register_operand" "=D")
17990         (plus:SI (match_dup 1)
17991                  (const_int 1)))
17992    (use (reg:SI DIRFLAG_REG))]
17993   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17994   "stosb"
17995   [(set_attr "type" "str")
17996    (set_attr "memory" "store")
17997    (set_attr "mode" "QI")])
17999 (define_insn "*strsetqi_rex_1"
18000   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18001         (match_operand:QI 2 "register_operand" "a"))
18002    (set (match_operand:DI 0 "register_operand" "=D")
18003         (plus:DI (match_dup 1)
18004                  (const_int 1)))
18005    (use (reg:SI DIRFLAG_REG))]
18006   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18007   "stosb"
18008   [(set_attr "type" "str")
18009    (set_attr "memory" "store")
18010    (set_attr "mode" "QI")])
18012 (define_expand "rep_stos"
18013   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18014               (set (match_operand 0 "register_operand" "")
18015                    (match_operand 4 "" ""))
18016               (set (match_operand 2 "memory_operand" "") (const_int 0))
18017               (use (match_operand 3 "register_operand" ""))
18018               (use (match_dup 1))
18019               (use (reg:SI DIRFLAG_REG))])]
18020   ""
18021   "")
18023 (define_insn "*rep_stosdi_rex64"
18024   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18025    (set (match_operand:DI 0 "register_operand" "=D") 
18026         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18027                             (const_int 3))
18028                  (match_operand:DI 3 "register_operand" "0")))
18029    (set (mem:BLK (match_dup 3))
18030         (const_int 0))
18031    (use (match_operand:DI 2 "register_operand" "a"))
18032    (use (match_dup 4))
18033    (use (reg:SI DIRFLAG_REG))]
18034   "TARGET_64BIT"
18035   "{rep\;stosq|rep stosq}"
18036   [(set_attr "type" "str")
18037    (set_attr "prefix_rep" "1")
18038    (set_attr "memory" "store")
18039    (set_attr "mode" "DI")])
18041 (define_insn "*rep_stossi"
18042   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18043    (set (match_operand:SI 0 "register_operand" "=D") 
18044         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18045                             (const_int 2))
18046                  (match_operand:SI 3 "register_operand" "0")))
18047    (set (mem:BLK (match_dup 3))
18048         (const_int 0))
18049    (use (match_operand:SI 2 "register_operand" "a"))
18050    (use (match_dup 4))
18051    (use (reg:SI DIRFLAG_REG))]
18052   "!TARGET_64BIT"
18053   "{rep\;stosl|rep stosd}"
18054   [(set_attr "type" "str")
18055    (set_attr "prefix_rep" "1")
18056    (set_attr "memory" "store")
18057    (set_attr "mode" "SI")])
18059 (define_insn "*rep_stossi_rex64"
18060   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18061    (set (match_operand:DI 0 "register_operand" "=D") 
18062         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18063                             (const_int 2))
18064                  (match_operand:DI 3 "register_operand" "0")))
18065    (set (mem:BLK (match_dup 3))
18066         (const_int 0))
18067    (use (match_operand:SI 2 "register_operand" "a"))
18068    (use (match_dup 4))
18069    (use (reg:SI DIRFLAG_REG))]
18070   "TARGET_64BIT"
18071   "{rep\;stosl|rep stosd}"
18072   [(set_attr "type" "str")
18073    (set_attr "prefix_rep" "1")
18074    (set_attr "memory" "store")
18075    (set_attr "mode" "SI")])
18077 (define_insn "*rep_stosqi"
18078   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18079    (set (match_operand:SI 0 "register_operand" "=D") 
18080         (plus:SI (match_operand:SI 3 "register_operand" "0")
18081                  (match_operand:SI 4 "register_operand" "1")))
18082    (set (mem:BLK (match_dup 3))
18083         (const_int 0))
18084    (use (match_operand:QI 2 "register_operand" "a"))
18085    (use (match_dup 4))
18086    (use (reg:SI DIRFLAG_REG))]
18087   "!TARGET_64BIT"
18088   "{rep\;stosb|rep stosb}"
18089   [(set_attr "type" "str")
18090    (set_attr "prefix_rep" "1")
18091    (set_attr "memory" "store")
18092    (set_attr "mode" "QI")])
18094 (define_insn "*rep_stosqi_rex64"
18095   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18096    (set (match_operand:DI 0 "register_operand" "=D") 
18097         (plus:DI (match_operand:DI 3 "register_operand" "0")
18098                  (match_operand:DI 4 "register_operand" "1")))
18099    (set (mem:BLK (match_dup 3))
18100         (const_int 0))
18101    (use (match_operand:QI 2 "register_operand" "a"))
18102    (use (match_dup 4))
18103    (use (reg:SI DIRFLAG_REG))]
18104   "TARGET_64BIT"
18105   "{rep\;stosb|rep stosb}"
18106   [(set_attr "type" "str")
18107    (set_attr "prefix_rep" "1")
18108    (set_attr "memory" "store")
18109    (set_attr "mode" "QI")])
18111 (define_expand "cmpstrnsi"
18112   [(set (match_operand:SI 0 "register_operand" "")
18113         (compare:SI (match_operand:BLK 1 "general_operand" "")
18114                     (match_operand:BLK 2 "general_operand" "")))
18115    (use (match_operand 3 "general_operand" ""))
18116    (use (match_operand 4 "immediate_operand" ""))]
18117   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18119   rtx addr1, addr2, out, outlow, count, countreg, align;
18121   /* Can't use this if the user has appropriated esi or edi.  */
18122   if (global_regs[4] || global_regs[5])
18123     FAIL;
18125   out = operands[0];
18126   if (GET_CODE (out) != REG)
18127     out = gen_reg_rtx (SImode);
18129   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18130   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18131   if (addr1 != XEXP (operands[1], 0))
18132     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18133   if (addr2 != XEXP (operands[2], 0))
18134     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18136   count = operands[3];
18137   countreg = ix86_zero_extend_to_Pmode (count);
18139   /* %%% Iff we are testing strict equality, we can use known alignment
18140      to good advantage.  This may be possible with combine, particularly
18141      once cc0 is dead.  */
18142   align = operands[4];
18144   emit_insn (gen_cld ());
18145   if (GET_CODE (count) == CONST_INT)
18146     {
18147       if (INTVAL (count) == 0)
18148         {
18149           emit_move_insn (operands[0], const0_rtx);
18150           DONE;
18151         }
18152       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18153                                      operands[1], operands[2]));
18154     }
18155   else
18156     {
18157       if (TARGET_64BIT)
18158         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18159       else
18160         emit_insn (gen_cmpsi_1 (countreg, countreg));
18161       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18162                                   operands[1], operands[2]));
18163     }
18165   outlow = gen_lowpart (QImode, out);
18166   emit_insn (gen_cmpintqi (outlow));
18167   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18169   if (operands[0] != out)
18170     emit_move_insn (operands[0], out);
18172   DONE;
18175 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18177 (define_expand "cmpintqi"
18178   [(set (match_dup 1)
18179         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18180    (set (match_dup 2)
18181         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18182    (parallel [(set (match_operand:QI 0 "register_operand" "")
18183                    (minus:QI (match_dup 1)
18184                              (match_dup 2)))
18185               (clobber (reg:CC FLAGS_REG))])]
18186   ""
18187   "operands[1] = gen_reg_rtx (QImode);
18188    operands[2] = gen_reg_rtx (QImode);")
18190 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18191 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18193 (define_expand "cmpstrnqi_nz_1"
18194   [(parallel [(set (reg:CC FLAGS_REG)
18195                    (compare:CC (match_operand 4 "memory_operand" "")
18196                                (match_operand 5 "memory_operand" "")))
18197               (use (match_operand 2 "register_operand" ""))
18198               (use (match_operand:SI 3 "immediate_operand" ""))
18199               (use (reg:SI DIRFLAG_REG))
18200               (clobber (match_operand 0 "register_operand" ""))
18201               (clobber (match_operand 1 "register_operand" ""))
18202               (clobber (match_dup 2))])]
18203   ""
18204   "")
18206 (define_insn "*cmpstrnqi_nz_1"
18207   [(set (reg:CC FLAGS_REG)
18208         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18209                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18210    (use (match_operand:SI 6 "register_operand" "2"))
18211    (use (match_operand:SI 3 "immediate_operand" "i"))
18212    (use (reg:SI DIRFLAG_REG))
18213    (clobber (match_operand:SI 0 "register_operand" "=S"))
18214    (clobber (match_operand:SI 1 "register_operand" "=D"))
18215    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18216   "!TARGET_64BIT"
18217   "repz{\;| }cmpsb"
18218   [(set_attr "type" "str")
18219    (set_attr "mode" "QI")
18220    (set_attr "prefix_rep" "1")])
18222 (define_insn "*cmpstrnqi_nz_rex_1"
18223   [(set (reg:CC FLAGS_REG)
18224         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18225                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18226    (use (match_operand:DI 6 "register_operand" "2"))
18227    (use (match_operand:SI 3 "immediate_operand" "i"))
18228    (use (reg:SI DIRFLAG_REG))
18229    (clobber (match_operand:DI 0 "register_operand" "=S"))
18230    (clobber (match_operand:DI 1 "register_operand" "=D"))
18231    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18232   "TARGET_64BIT"
18233   "repz{\;| }cmpsb"
18234   [(set_attr "type" "str")
18235    (set_attr "mode" "QI")
18236    (set_attr "prefix_rep" "1")])
18238 ;; The same, but the count is not known to not be zero.
18240 (define_expand "cmpstrnqi_1"
18241   [(parallel [(set (reg:CC FLAGS_REG)
18242                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18243                                      (const_int 0))
18244                   (compare:CC (match_operand 4 "memory_operand" "")
18245                               (match_operand 5 "memory_operand" ""))
18246                   (const_int 0)))
18247               (use (match_operand:SI 3 "immediate_operand" ""))
18248               (use (reg:CC FLAGS_REG))
18249               (use (reg:SI DIRFLAG_REG))
18250               (clobber (match_operand 0 "register_operand" ""))
18251               (clobber (match_operand 1 "register_operand" ""))
18252               (clobber (match_dup 2))])]
18253   ""
18254   "")
18256 (define_insn "*cmpstrnqi_1"
18257   [(set (reg:CC FLAGS_REG)
18258         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18259                              (const_int 0))
18260           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18261                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18262           (const_int 0)))
18263    (use (match_operand:SI 3 "immediate_operand" "i"))
18264    (use (reg:CC FLAGS_REG))
18265    (use (reg:SI DIRFLAG_REG))
18266    (clobber (match_operand:SI 0 "register_operand" "=S"))
18267    (clobber (match_operand:SI 1 "register_operand" "=D"))
18268    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18269   "!TARGET_64BIT"
18270   "repz{\;| }cmpsb"
18271   [(set_attr "type" "str")
18272    (set_attr "mode" "QI")
18273    (set_attr "prefix_rep" "1")])
18275 (define_insn "*cmpstrnqi_rex_1"
18276   [(set (reg:CC FLAGS_REG)
18277         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18278                              (const_int 0))
18279           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18280                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18281           (const_int 0)))
18282    (use (match_operand:SI 3 "immediate_operand" "i"))
18283    (use (reg:CC FLAGS_REG))
18284    (use (reg:SI DIRFLAG_REG))
18285    (clobber (match_operand:DI 0 "register_operand" "=S"))
18286    (clobber (match_operand:DI 1 "register_operand" "=D"))
18287    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18288   "TARGET_64BIT"
18289   "repz{\;| }cmpsb"
18290   [(set_attr "type" "str")
18291    (set_attr "mode" "QI")
18292    (set_attr "prefix_rep" "1")])
18294 (define_expand "strlensi"
18295   [(set (match_operand:SI 0 "register_operand" "")
18296         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18297                     (match_operand:QI 2 "immediate_operand" "")
18298                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18299   ""
18301  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18302    DONE;
18303  else
18304    FAIL;
18307 (define_expand "strlendi"
18308   [(set (match_operand:DI 0 "register_operand" "")
18309         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18310                     (match_operand:QI 2 "immediate_operand" "")
18311                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18312   ""
18314  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18315    DONE;
18316  else
18317    FAIL;
18320 (define_expand "strlenqi_1"
18321   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18322               (use (reg:SI DIRFLAG_REG))
18323               (clobber (match_operand 1 "register_operand" ""))
18324               (clobber (reg:CC FLAGS_REG))])]
18325   ""
18326   "")
18328 (define_insn "*strlenqi_1"
18329   [(set (match_operand:SI 0 "register_operand" "=&c")
18330         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18331                     (match_operand:QI 2 "register_operand" "a")
18332                     (match_operand:SI 3 "immediate_operand" "i")
18333                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18334    (use (reg:SI DIRFLAG_REG))
18335    (clobber (match_operand:SI 1 "register_operand" "=D"))
18336    (clobber (reg:CC FLAGS_REG))]
18337   "!TARGET_64BIT"
18338   "repnz{\;| }scasb"
18339   [(set_attr "type" "str")
18340    (set_attr "mode" "QI")
18341    (set_attr "prefix_rep" "1")])
18343 (define_insn "*strlenqi_rex_1"
18344   [(set (match_operand:DI 0 "register_operand" "=&c")
18345         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18346                     (match_operand:QI 2 "register_operand" "a")
18347                     (match_operand:DI 3 "immediate_operand" "i")
18348                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18349    (use (reg:SI DIRFLAG_REG))
18350    (clobber (match_operand:DI 1 "register_operand" "=D"))
18351    (clobber (reg:CC FLAGS_REG))]
18352   "TARGET_64BIT"
18353   "repnz{\;| }scasb"
18354   [(set_attr "type" "str")
18355    (set_attr "mode" "QI")
18356    (set_attr "prefix_rep" "1")])
18358 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18359 ;; handled in combine, but it is not currently up to the task.
18360 ;; When used for their truth value, the cmpstrn* expanders generate
18361 ;; code like this:
18363 ;;   repz cmpsb
18364 ;;   seta       %al
18365 ;;   setb       %dl
18366 ;;   cmpb       %al, %dl
18367 ;;   jcc        label
18369 ;; The intermediate three instructions are unnecessary.
18371 ;; This one handles cmpstrn*_nz_1...
18372 (define_peephole2
18373   [(parallel[
18374      (set (reg:CC FLAGS_REG)
18375           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18376                       (mem:BLK (match_operand 5 "register_operand" ""))))
18377      (use (match_operand 6 "register_operand" ""))
18378      (use (match_operand:SI 3 "immediate_operand" ""))
18379      (use (reg:SI DIRFLAG_REG))
18380      (clobber (match_operand 0 "register_operand" ""))
18381      (clobber (match_operand 1 "register_operand" ""))
18382      (clobber (match_operand 2 "register_operand" ""))])
18383    (set (match_operand:QI 7 "register_operand" "")
18384         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18385    (set (match_operand:QI 8 "register_operand" "")
18386         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18387    (set (reg FLAGS_REG)
18388         (compare (match_dup 7) (match_dup 8)))
18389   ]
18390   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18391   [(parallel[
18392      (set (reg:CC FLAGS_REG)
18393           (compare:CC (mem:BLK (match_dup 4))
18394                       (mem:BLK (match_dup 5))))
18395      (use (match_dup 6))
18396      (use (match_dup 3))
18397      (use (reg:SI DIRFLAG_REG))
18398      (clobber (match_dup 0))
18399      (clobber (match_dup 1))
18400      (clobber (match_dup 2))])]
18401   "")
18403 ;; ...and this one handles cmpstrn*_1.
18404 (define_peephole2
18405   [(parallel[
18406      (set (reg:CC FLAGS_REG)
18407           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18408                                (const_int 0))
18409             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18410                         (mem:BLK (match_operand 5 "register_operand" "")))
18411             (const_int 0)))
18412      (use (match_operand:SI 3 "immediate_operand" ""))
18413      (use (reg:CC FLAGS_REG))
18414      (use (reg:SI DIRFLAG_REG))
18415      (clobber (match_operand 0 "register_operand" ""))
18416      (clobber (match_operand 1 "register_operand" ""))
18417      (clobber (match_operand 2 "register_operand" ""))])
18418    (set (match_operand:QI 7 "register_operand" "")
18419         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18420    (set (match_operand:QI 8 "register_operand" "")
18421         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18422    (set (reg FLAGS_REG)
18423         (compare (match_dup 7) (match_dup 8)))
18424   ]
18425   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18426   [(parallel[
18427      (set (reg:CC FLAGS_REG)
18428           (if_then_else:CC (ne (match_dup 6)
18429                                (const_int 0))
18430             (compare:CC (mem:BLK (match_dup 4))
18431                         (mem:BLK (match_dup 5)))
18432             (const_int 0)))
18433      (use (match_dup 3))
18434      (use (reg:CC FLAGS_REG))
18435      (use (reg:SI DIRFLAG_REG))
18436      (clobber (match_dup 0))
18437      (clobber (match_dup 1))
18438      (clobber (match_dup 2))])]
18439   "")
18443 ;; Conditional move instructions.
18445 (define_expand "movdicc"
18446   [(set (match_operand:DI 0 "register_operand" "")
18447         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18448                          (match_operand:DI 2 "general_operand" "")
18449                          (match_operand:DI 3 "general_operand" "")))]
18450   "TARGET_64BIT"
18451   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18453 (define_insn "x86_movdicc_0_m1_rex64"
18454   [(set (match_operand:DI 0 "register_operand" "=r")
18455         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18456           (const_int -1)
18457           (const_int 0)))
18458    (clobber (reg:CC FLAGS_REG))]
18459   "TARGET_64BIT"
18460   "sbb{q}\t%0, %0"
18461   ; Since we don't have the proper number of operands for an alu insn,
18462   ; fill in all the blanks.
18463   [(set_attr "type" "alu")
18464    (set_attr "pent_pair" "pu")
18465    (set_attr "memory" "none")
18466    (set_attr "imm_disp" "false")
18467    (set_attr "mode" "DI")
18468    (set_attr "length_immediate" "0")])
18470 (define_insn "*movdicc_c_rex64"
18471   [(set (match_operand:DI 0 "register_operand" "=r,r")
18472         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18473                                 [(reg FLAGS_REG) (const_int 0)])
18474                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18475                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18476   "TARGET_64BIT && TARGET_CMOVE
18477    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18478   "@
18479    cmov%O2%C1\t{%2, %0|%0, %2}
18480    cmov%O2%c1\t{%3, %0|%0, %3}"
18481   [(set_attr "type" "icmov")
18482    (set_attr "mode" "DI")])
18484 (define_expand "movsicc"
18485   [(set (match_operand:SI 0 "register_operand" "")
18486         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18487                          (match_operand:SI 2 "general_operand" "")
18488                          (match_operand:SI 3 "general_operand" "")))]
18489   ""
18490   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18492 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18493 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18494 ;; So just document what we're doing explicitly.
18496 (define_insn "x86_movsicc_0_m1"
18497   [(set (match_operand:SI 0 "register_operand" "=r")
18498         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18499           (const_int -1)
18500           (const_int 0)))
18501    (clobber (reg:CC FLAGS_REG))]
18502   ""
18503   "sbb{l}\t%0, %0"
18504   ; Since we don't have the proper number of operands for an alu insn,
18505   ; fill in all the blanks.
18506   [(set_attr "type" "alu")
18507    (set_attr "pent_pair" "pu")
18508    (set_attr "memory" "none")
18509    (set_attr "imm_disp" "false")
18510    (set_attr "mode" "SI")
18511    (set_attr "length_immediate" "0")])
18513 (define_insn "*movsicc_noc"
18514   [(set (match_operand:SI 0 "register_operand" "=r,r")
18515         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18516                                 [(reg FLAGS_REG) (const_int 0)])
18517                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18518                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18519   "TARGET_CMOVE
18520    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18521   "@
18522    cmov%O2%C1\t{%2, %0|%0, %2}
18523    cmov%O2%c1\t{%3, %0|%0, %3}"
18524   [(set_attr "type" "icmov")
18525    (set_attr "mode" "SI")])
18527 (define_expand "movhicc"
18528   [(set (match_operand:HI 0 "register_operand" "")
18529         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18530                          (match_operand:HI 2 "general_operand" "")
18531                          (match_operand:HI 3 "general_operand" "")))]
18532   "TARGET_HIMODE_MATH"
18533   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18535 (define_insn "*movhicc_noc"
18536   [(set (match_operand:HI 0 "register_operand" "=r,r")
18537         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18538                                 [(reg FLAGS_REG) (const_int 0)])
18539                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18540                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18541   "TARGET_CMOVE
18542    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18543   "@
18544    cmov%O2%C1\t{%2, %0|%0, %2}
18545    cmov%O2%c1\t{%3, %0|%0, %3}"
18546   [(set_attr "type" "icmov")
18547    (set_attr "mode" "HI")])
18549 (define_expand "movqicc"
18550   [(set (match_operand:QI 0 "register_operand" "")
18551         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18552                          (match_operand:QI 2 "general_operand" "")
18553                          (match_operand:QI 3 "general_operand" "")))]
18554   "TARGET_QIMODE_MATH"
18555   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18557 (define_insn_and_split "*movqicc_noc"
18558   [(set (match_operand:QI 0 "register_operand" "=r,r")
18559         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18560                                 [(match_operand 4 "flags_reg_operand" "")
18561                                  (const_int 0)])
18562                       (match_operand:QI 2 "register_operand" "r,0")
18563                       (match_operand:QI 3 "register_operand" "0,r")))]
18564   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18565   "#"
18566   "&& reload_completed"
18567   [(set (match_dup 0)
18568         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18569                       (match_dup 2)
18570                       (match_dup 3)))]
18571   "operands[0] = gen_lowpart (SImode, operands[0]);
18572    operands[2] = gen_lowpart (SImode, operands[2]);
18573    operands[3] = gen_lowpart (SImode, operands[3]);"
18574   [(set_attr "type" "icmov")
18575    (set_attr "mode" "SI")])
18577 (define_expand "movsfcc"
18578   [(set (match_operand:SF 0 "register_operand" "")
18579         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18580                          (match_operand:SF 2 "register_operand" "")
18581                          (match_operand:SF 3 "register_operand" "")))]
18582   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18583   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18585 (define_insn "*movsfcc_1_387"
18586   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18587         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18588                                 [(reg FLAGS_REG) (const_int 0)])
18589                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18590                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18591   "TARGET_80387 && TARGET_CMOVE
18592    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18593   "@
18594    fcmov%F1\t{%2, %0|%0, %2}
18595    fcmov%f1\t{%3, %0|%0, %3}
18596    cmov%O2%C1\t{%2, %0|%0, %2}
18597    cmov%O2%c1\t{%3, %0|%0, %3}"
18598   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18599    (set_attr "mode" "SF,SF,SI,SI")])
18601 (define_expand "movdfcc"
18602   [(set (match_operand:DF 0 "register_operand" "")
18603         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18604                          (match_operand:DF 2 "register_operand" "")
18605                          (match_operand:DF 3 "register_operand" "")))]
18606   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18607   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18609 (define_insn "*movdfcc_1"
18610   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18611         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18612                                 [(reg FLAGS_REG) (const_int 0)])
18613                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18614                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18615   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18616    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18617   "@
18618    fcmov%F1\t{%2, %0|%0, %2}
18619    fcmov%f1\t{%3, %0|%0, %3}
18620    #
18621    #"
18622   [(set_attr "type" "fcmov,fcmov,multi,multi")
18623    (set_attr "mode" "DF")])
18625 (define_insn "*movdfcc_1_rex64"
18626   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18627         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18628                                 [(reg FLAGS_REG) (const_int 0)])
18629                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18630                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18631   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18632    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18633   "@
18634    fcmov%F1\t{%2, %0|%0, %2}
18635    fcmov%f1\t{%3, %0|%0, %3}
18636    cmov%O2%C1\t{%2, %0|%0, %2}
18637    cmov%O2%c1\t{%3, %0|%0, %3}"
18638   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18639    (set_attr "mode" "DF")])
18641 (define_split
18642   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18643         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18644                                 [(match_operand 4 "flags_reg_operand" "")
18645                                  (const_int 0)])
18646                       (match_operand:DF 2 "nonimmediate_operand" "")
18647                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18648   "!TARGET_64BIT && reload_completed"
18649   [(set (match_dup 2)
18650         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18651                       (match_dup 5)
18652                       (match_dup 7)))
18653    (set (match_dup 3)
18654         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18655                       (match_dup 6)
18656                       (match_dup 8)))]
18657   "split_di (operands+2, 1, operands+5, operands+6);
18658    split_di (operands+3, 1, operands+7, operands+8);
18659    split_di (operands, 1, operands+2, operands+3);")
18661 (define_expand "movxfcc"
18662   [(set (match_operand:XF 0 "register_operand" "")
18663         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18664                          (match_operand:XF 2 "register_operand" "")
18665                          (match_operand:XF 3 "register_operand" "")))]
18666   "TARGET_80387 && TARGET_CMOVE"
18667   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18669 (define_insn "*movxfcc_1"
18670   [(set (match_operand:XF 0 "register_operand" "=f,f")
18671         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18672                                 [(reg FLAGS_REG) (const_int 0)])
18673                       (match_operand:XF 2 "register_operand" "f,0")
18674                       (match_operand:XF 3 "register_operand" "0,f")))]
18675   "TARGET_80387 && TARGET_CMOVE"
18676   "@
18677    fcmov%F1\t{%2, %0|%0, %2}
18678    fcmov%f1\t{%3, %0|%0, %3}"
18679   [(set_attr "type" "fcmov")
18680    (set_attr "mode" "XF")])
18682 ;; These versions of the min/max patterns are intentionally ignorant of
18683 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18684 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18685 ;; are undefined in this condition, we're certain this is correct.
18687 (define_insn "sminsf3"
18688   [(set (match_operand:SF 0 "register_operand" "=x")
18689         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18690                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18691   "TARGET_SSE_MATH"
18692   "minss\t{%2, %0|%0, %2}"
18693   [(set_attr "type" "sseadd")
18694    (set_attr "mode" "SF")])
18696 (define_insn "smaxsf3"
18697   [(set (match_operand:SF 0 "register_operand" "=x")
18698         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18699                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18700   "TARGET_SSE_MATH"
18701   "maxss\t{%2, %0|%0, %2}"
18702   [(set_attr "type" "sseadd")
18703    (set_attr "mode" "SF")])
18705 (define_insn "smindf3"
18706   [(set (match_operand:DF 0 "register_operand" "=x")
18707         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18708                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18709   "TARGET_SSE2 && TARGET_SSE_MATH"
18710   "minsd\t{%2, %0|%0, %2}"
18711   [(set_attr "type" "sseadd")
18712    (set_attr "mode" "DF")])
18714 (define_insn "smaxdf3"
18715   [(set (match_operand:DF 0 "register_operand" "=x")
18716         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18717                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18718   "TARGET_SSE2 && TARGET_SSE_MATH"
18719   "maxsd\t{%2, %0|%0, %2}"
18720   [(set_attr "type" "sseadd")
18721    (set_attr "mode" "DF")])
18723 ;; These versions of the min/max patterns implement exactly the operations
18724 ;;   min = (op1 < op2 ? op1 : op2)
18725 ;;   max = (!(op1 < op2) ? op1 : op2)
18726 ;; Their operands are not commutative, and thus they may be used in the
18727 ;; presence of -0.0 and NaN.
18729 (define_insn "*ieee_sminsf3"
18730   [(set (match_operand:SF 0 "register_operand" "=x")
18731         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18732                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18733                    UNSPEC_IEEE_MIN))]
18734   "TARGET_SSE_MATH"
18735   "minss\t{%2, %0|%0, %2}"
18736   [(set_attr "type" "sseadd")
18737    (set_attr "mode" "SF")])
18739 (define_insn "*ieee_smaxsf3"
18740   [(set (match_operand:SF 0 "register_operand" "=x")
18741         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18742                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18743                    UNSPEC_IEEE_MAX))]
18744   "TARGET_SSE_MATH"
18745   "maxss\t{%2, %0|%0, %2}"
18746   [(set_attr "type" "sseadd")
18747    (set_attr "mode" "SF")])
18749 (define_insn "*ieee_smindf3"
18750   [(set (match_operand:DF 0 "register_operand" "=x")
18751         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18752                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18753                    UNSPEC_IEEE_MIN))]
18754   "TARGET_SSE2 && TARGET_SSE_MATH"
18755   "minsd\t{%2, %0|%0, %2}"
18756   [(set_attr "type" "sseadd")
18757    (set_attr "mode" "DF")])
18759 (define_insn "*ieee_smaxdf3"
18760   [(set (match_operand:DF 0 "register_operand" "=x")
18761         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18762                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18763                    UNSPEC_IEEE_MAX))]
18764   "TARGET_SSE2 && TARGET_SSE_MATH"
18765   "maxsd\t{%2, %0|%0, %2}"
18766   [(set_attr "type" "sseadd")
18767    (set_attr "mode" "DF")])
18769 ;; Conditional addition patterns
18770 (define_expand "addqicc"
18771   [(match_operand:QI 0 "register_operand" "")
18772    (match_operand 1 "comparison_operator" "")
18773    (match_operand:QI 2 "register_operand" "")
18774    (match_operand:QI 3 "const_int_operand" "")]
18775   ""
18776   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18778 (define_expand "addhicc"
18779   [(match_operand:HI 0 "register_operand" "")
18780    (match_operand 1 "comparison_operator" "")
18781    (match_operand:HI 2 "register_operand" "")
18782    (match_operand:HI 3 "const_int_operand" "")]
18783   ""
18784   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18786 (define_expand "addsicc"
18787   [(match_operand:SI 0 "register_operand" "")
18788    (match_operand 1 "comparison_operator" "")
18789    (match_operand:SI 2 "register_operand" "")
18790    (match_operand:SI 3 "const_int_operand" "")]
18791   ""
18792   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18794 (define_expand "adddicc"
18795   [(match_operand:DI 0 "register_operand" "")
18796    (match_operand 1 "comparison_operator" "")
18797    (match_operand:DI 2 "register_operand" "")
18798    (match_operand:DI 3 "const_int_operand" "")]
18799   "TARGET_64BIT"
18800   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18803 ;; Misc patterns (?)
18805 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18806 ;; Otherwise there will be nothing to keep
18807 ;; 
18808 ;; [(set (reg ebp) (reg esp))]
18809 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18810 ;;  (clobber (eflags)]
18811 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18813 ;; in proper program order.
18814 (define_insn "pro_epilogue_adjust_stack_1"
18815   [(set (match_operand:SI 0 "register_operand" "=r,r")
18816         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18817                  (match_operand:SI 2 "immediate_operand" "i,i")))
18818    (clobber (reg:CC FLAGS_REG))
18819    (clobber (mem:BLK (scratch)))]
18820   "!TARGET_64BIT"
18822   switch (get_attr_type (insn))
18823     {
18824     case TYPE_IMOV:
18825       return "mov{l}\t{%1, %0|%0, %1}";
18827     case TYPE_ALU:
18828       if (GET_CODE (operands[2]) == CONST_INT
18829           && (INTVAL (operands[2]) == 128
18830               || (INTVAL (operands[2]) < 0
18831                   && INTVAL (operands[2]) != -128)))
18832         {
18833           operands[2] = GEN_INT (-INTVAL (operands[2]));
18834           return "sub{l}\t{%2, %0|%0, %2}";
18835         }
18836       return "add{l}\t{%2, %0|%0, %2}";
18838     case TYPE_LEA:
18839       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18840       return "lea{l}\t{%a2, %0|%0, %a2}";
18842     default:
18843       gcc_unreachable ();
18844     }
18846   [(set (attr "type")
18847         (cond [(eq_attr "alternative" "0")
18848                  (const_string "alu")
18849                (match_operand:SI 2 "const0_operand" "")
18850                  (const_string "imov")
18851               ]
18852               (const_string "lea")))
18853    (set_attr "mode" "SI")])
18855 (define_insn "pro_epilogue_adjust_stack_rex64"
18856   [(set (match_operand:DI 0 "register_operand" "=r,r")
18857         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18858                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18859    (clobber (reg:CC FLAGS_REG))
18860    (clobber (mem:BLK (scratch)))]
18861   "TARGET_64BIT"
18863   switch (get_attr_type (insn))
18864     {
18865     case TYPE_IMOV:
18866       return "mov{q}\t{%1, %0|%0, %1}";
18868     case TYPE_ALU:
18869       if (GET_CODE (operands[2]) == CONST_INT
18870           /* Avoid overflows.  */
18871           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18872           && (INTVAL (operands[2]) == 128
18873               || (INTVAL (operands[2]) < 0
18874                   && INTVAL (operands[2]) != -128)))
18875         {
18876           operands[2] = GEN_INT (-INTVAL (operands[2]));
18877           return "sub{q}\t{%2, %0|%0, %2}";
18878         }
18879       return "add{q}\t{%2, %0|%0, %2}";
18881     case TYPE_LEA:
18882       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18883       return "lea{q}\t{%a2, %0|%0, %a2}";
18885     default:
18886       gcc_unreachable ();
18887     }
18889   [(set (attr "type")
18890         (cond [(eq_attr "alternative" "0")
18891                  (const_string "alu")
18892                (match_operand:DI 2 "const0_operand" "")
18893                  (const_string "imov")
18894               ]
18895               (const_string "lea")))
18896    (set_attr "mode" "DI")])
18898 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18899   [(set (match_operand:DI 0 "register_operand" "=r,r")
18900         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18901                  (match_operand:DI 3 "immediate_operand" "i,i")))
18902    (use (match_operand:DI 2 "register_operand" "r,r"))
18903    (clobber (reg:CC FLAGS_REG))
18904    (clobber (mem:BLK (scratch)))]
18905   "TARGET_64BIT"
18907   switch (get_attr_type (insn))
18908     {
18909     case TYPE_ALU:
18910       return "add{q}\t{%2, %0|%0, %2}";
18912     case TYPE_LEA:
18913       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18914       return "lea{q}\t{%a2, %0|%0, %a2}";
18916     default:
18917       gcc_unreachable ();
18918     }
18920   [(set_attr "type" "alu,lea")
18921    (set_attr "mode" "DI")])
18923 (define_expand "allocate_stack_worker"
18924   [(match_operand:SI 0 "register_operand" "")]
18925   "TARGET_STACK_PROBE"
18927   if (reload_completed)
18928     {
18929       if (TARGET_64BIT)
18930         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18931       else
18932         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18933     }
18934   else
18935     {
18936       if (TARGET_64BIT)
18937         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18938       else
18939         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18940     }
18941   DONE;
18944 (define_insn "allocate_stack_worker_1"
18945   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18946     UNSPECV_STACK_PROBE)
18947    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18948    (clobber (match_scratch:SI 1 "=0"))
18949    (clobber (reg:CC FLAGS_REG))]
18950   "!TARGET_64BIT && TARGET_STACK_PROBE"
18951   "call\t__alloca"
18952   [(set_attr "type" "multi")
18953    (set_attr "length" "5")])
18955 (define_expand "allocate_stack_worker_postreload"
18956   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18957                                     UNSPECV_STACK_PROBE)
18958               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18959               (clobber (match_dup 0))
18960               (clobber (reg:CC FLAGS_REG))])]
18961   ""
18962   "")
18964 (define_insn "allocate_stack_worker_rex64"
18965   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18966     UNSPECV_STACK_PROBE)
18967    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18968    (clobber (match_scratch:DI 1 "=0"))
18969    (clobber (reg:CC FLAGS_REG))]
18970   "TARGET_64BIT && TARGET_STACK_PROBE"
18971   "call\t__alloca"
18972   [(set_attr "type" "multi")
18973    (set_attr "length" "5")])
18975 (define_expand "allocate_stack_worker_rex64_postreload"
18976   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18977                                     UNSPECV_STACK_PROBE)
18978               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18979               (clobber (match_dup 0))
18980               (clobber (reg:CC FLAGS_REG))])]
18981   ""
18982   "")
18984 (define_expand "allocate_stack"
18985   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18986                    (minus:SI (reg:SI SP_REG)
18987                              (match_operand:SI 1 "general_operand" "")))
18988               (clobber (reg:CC FLAGS_REG))])
18989    (parallel [(set (reg:SI SP_REG)
18990                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18991               (clobber (reg:CC FLAGS_REG))])]
18992   "TARGET_STACK_PROBE"
18994 #ifdef CHECK_STACK_LIMIT
18995   if (GET_CODE (operands[1]) == CONST_INT
18996       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18997     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18998                            operands[1]));
18999   else 
19000 #endif
19001     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19002                                                             operands[1])));
19004   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19005   DONE;
19008 (define_expand "builtin_setjmp_receiver"
19009   [(label_ref (match_operand 0 "" ""))]
19010   "!TARGET_64BIT && flag_pic"
19012   if (TARGET_MACHO)
19013     {
19014       rtx xops[3];
19015       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19016       rtx label_rtx = gen_label_rtx ();
19017       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19018       xops[0] = xops[1] = picreg;
19019       xops[2] = gen_rtx_CONST (SImode,
19020                   gen_rtx_MINUS (SImode,
19021                     gen_rtx_LABEL_REF (SImode, label_rtx),
19022                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19023       ix86_expand_binary_operator (MINUS, SImode, xops);
19024     }
19025   else
19026     emit_insn (gen_set_got (pic_offset_table_rtx));
19027   DONE;
19030 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19032 (define_split
19033   [(set (match_operand 0 "register_operand" "")
19034         (match_operator 3 "promotable_binary_operator"
19035            [(match_operand 1 "register_operand" "")
19036             (match_operand 2 "aligned_operand" "")]))
19037    (clobber (reg:CC FLAGS_REG))]
19038   "! TARGET_PARTIAL_REG_STALL && reload_completed
19039    && ((GET_MODE (operands[0]) == HImode 
19040         && ((!optimize_size && !TARGET_FAST_PREFIX)
19041             || GET_CODE (operands[2]) != CONST_INT
19042             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19043        || (GET_MODE (operands[0]) == QImode 
19044            && (TARGET_PROMOTE_QImode || optimize_size)))"
19045   [(parallel [(set (match_dup 0)
19046                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19047               (clobber (reg:CC FLAGS_REG))])]
19048   "operands[0] = gen_lowpart (SImode, operands[0]);
19049    operands[1] = gen_lowpart (SImode, operands[1]);
19050    if (GET_CODE (operands[3]) != ASHIFT)
19051      operands[2] = gen_lowpart (SImode, operands[2]);
19052    PUT_MODE (operands[3], SImode);")
19054 ; Promote the QImode tests, as i386 has encoding of the AND
19055 ; instruction with 32-bit sign-extended immediate and thus the
19056 ; instruction size is unchanged, except in the %eax case for
19057 ; which it is increased by one byte, hence the ! optimize_size.
19058 (define_split
19059   [(set (match_operand 0 "flags_reg_operand" "")
19060         (match_operator 2 "compare_operator"
19061           [(and (match_operand 3 "aligned_operand" "")
19062                 (match_operand 4 "const_int_operand" ""))
19063            (const_int 0)]))
19064    (set (match_operand 1 "register_operand" "")
19065         (and (match_dup 3) (match_dup 4)))]
19066   "! TARGET_PARTIAL_REG_STALL && reload_completed
19067    /* Ensure that the operand will remain sign-extended immediate.  */
19068    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19069    && ! optimize_size
19070    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19071        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19072   [(parallel [(set (match_dup 0)
19073                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19074                                     (const_int 0)]))
19075               (set (match_dup 1)
19076                    (and:SI (match_dup 3) (match_dup 4)))])]
19078   operands[4]
19079     = gen_int_mode (INTVAL (operands[4])
19080                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19081   operands[1] = gen_lowpart (SImode, operands[1]);
19082   operands[3] = gen_lowpart (SImode, operands[3]);
19085 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19086 ; the TEST instruction with 32-bit sign-extended immediate and thus
19087 ; the instruction size would at least double, which is not what we
19088 ; want even with ! optimize_size.
19089 (define_split
19090   [(set (match_operand 0 "flags_reg_operand" "")
19091         (match_operator 1 "compare_operator"
19092           [(and (match_operand:HI 2 "aligned_operand" "")
19093                 (match_operand:HI 3 "const_int_operand" ""))
19094            (const_int 0)]))]
19095   "! TARGET_PARTIAL_REG_STALL && reload_completed
19096    /* Ensure that the operand will remain sign-extended immediate.  */
19097    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19098    && ! TARGET_FAST_PREFIX
19099    && ! optimize_size"
19100   [(set (match_dup 0)
19101         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19102                          (const_int 0)]))]
19104   operands[3]
19105     = gen_int_mode (INTVAL (operands[3])
19106                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19107   operands[2] = gen_lowpart (SImode, operands[2]);
19110 (define_split
19111   [(set (match_operand 0 "register_operand" "")
19112         (neg (match_operand 1 "register_operand" "")))
19113    (clobber (reg:CC FLAGS_REG))]
19114   "! TARGET_PARTIAL_REG_STALL && reload_completed
19115    && (GET_MODE (operands[0]) == HImode
19116        || (GET_MODE (operands[0]) == QImode 
19117            && (TARGET_PROMOTE_QImode || optimize_size)))"
19118   [(parallel [(set (match_dup 0)
19119                    (neg:SI (match_dup 1)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "operands[0] = gen_lowpart (SImode, operands[0]);
19122    operands[1] = gen_lowpart (SImode, operands[1]);")
19124 (define_split
19125   [(set (match_operand 0 "register_operand" "")
19126         (not (match_operand 1 "register_operand" "")))]
19127   "! TARGET_PARTIAL_REG_STALL && reload_completed
19128    && (GET_MODE (operands[0]) == HImode
19129        || (GET_MODE (operands[0]) == QImode 
19130            && (TARGET_PROMOTE_QImode || optimize_size)))"
19131   [(set (match_dup 0)
19132         (not:SI (match_dup 1)))]
19133   "operands[0] = gen_lowpart (SImode, operands[0]);
19134    operands[1] = gen_lowpart (SImode, operands[1]);")
19136 (define_split 
19137   [(set (match_operand 0 "register_operand" "")
19138         (if_then_else (match_operator 1 "comparison_operator" 
19139                                 [(reg FLAGS_REG) (const_int 0)])
19140                       (match_operand 2 "register_operand" "")
19141                       (match_operand 3 "register_operand" "")))]
19142   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19143    && (GET_MODE (operands[0]) == HImode
19144        || (GET_MODE (operands[0]) == QImode 
19145            && (TARGET_PROMOTE_QImode || optimize_size)))"
19146   [(set (match_dup 0)
19147         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19148   "operands[0] = gen_lowpart (SImode, operands[0]);
19149    operands[2] = gen_lowpart (SImode, operands[2]);
19150    operands[3] = gen_lowpart (SImode, operands[3]);")
19151                         
19153 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19154 ;; transform a complex memory operation into two memory to register operations.
19156 ;; Don't push memory operands
19157 (define_peephole2
19158   [(set (match_operand:SI 0 "push_operand" "")
19159         (match_operand:SI 1 "memory_operand" ""))
19160    (match_scratch:SI 2 "r")]
19161   "!optimize_size && !TARGET_PUSH_MEMORY
19162    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19163   [(set (match_dup 2) (match_dup 1))
19164    (set (match_dup 0) (match_dup 2))]
19165   "")
19167 (define_peephole2
19168   [(set (match_operand:DI 0 "push_operand" "")
19169         (match_operand:DI 1 "memory_operand" ""))
19170    (match_scratch:DI 2 "r")]
19171   "!optimize_size && !TARGET_PUSH_MEMORY
19172    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19173   [(set (match_dup 2) (match_dup 1))
19174    (set (match_dup 0) (match_dup 2))]
19175   "")
19177 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19178 ;; SImode pushes.
19179 (define_peephole2
19180   [(set (match_operand:SF 0 "push_operand" "")
19181         (match_operand:SF 1 "memory_operand" ""))
19182    (match_scratch:SF 2 "r")]
19183   "!optimize_size && !TARGET_PUSH_MEMORY
19184    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19185   [(set (match_dup 2) (match_dup 1))
19186    (set (match_dup 0) (match_dup 2))]
19187   "")
19189 (define_peephole2
19190   [(set (match_operand:HI 0 "push_operand" "")
19191         (match_operand:HI 1 "memory_operand" ""))
19192    (match_scratch:HI 2 "r")]
19193   "!optimize_size && !TARGET_PUSH_MEMORY
19194    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19195   [(set (match_dup 2) (match_dup 1))
19196    (set (match_dup 0) (match_dup 2))]
19197   "")
19199 (define_peephole2
19200   [(set (match_operand:QI 0 "push_operand" "")
19201         (match_operand:QI 1 "memory_operand" ""))
19202    (match_scratch:QI 2 "q")]
19203   "!optimize_size && !TARGET_PUSH_MEMORY
19204    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19205   [(set (match_dup 2) (match_dup 1))
19206    (set (match_dup 0) (match_dup 2))]
19207   "")
19209 ;; Don't move an immediate directly to memory when the instruction
19210 ;; gets too big.
19211 (define_peephole2
19212   [(match_scratch:SI 1 "r")
19213    (set (match_operand:SI 0 "memory_operand" "")
19214         (const_int 0))]
19215   "! optimize_size
19216    && ! TARGET_USE_MOV0
19217    && TARGET_SPLIT_LONG_MOVES
19218    && get_attr_length (insn) >= ix86_cost->large_insn
19219    && peep2_regno_dead_p (0, FLAGS_REG)"
19220   [(parallel [(set (match_dup 1) (const_int 0))
19221               (clobber (reg:CC FLAGS_REG))])
19222    (set (match_dup 0) (match_dup 1))]
19223   "")
19225 (define_peephole2
19226   [(match_scratch:HI 1 "r")
19227    (set (match_operand:HI 0 "memory_operand" "")
19228         (const_int 0))]
19229   "! optimize_size
19230    && ! TARGET_USE_MOV0
19231    && TARGET_SPLIT_LONG_MOVES
19232    && get_attr_length (insn) >= ix86_cost->large_insn
19233    && peep2_regno_dead_p (0, FLAGS_REG)"
19234   [(parallel [(set (match_dup 2) (const_int 0))
19235               (clobber (reg:CC FLAGS_REG))])
19236    (set (match_dup 0) (match_dup 1))]
19237   "operands[2] = gen_lowpart (SImode, operands[1]);")
19239 (define_peephole2
19240   [(match_scratch:QI 1 "q")
19241    (set (match_operand:QI 0 "memory_operand" "")
19242         (const_int 0))]
19243   "! optimize_size
19244    && ! TARGET_USE_MOV0
19245    && TARGET_SPLIT_LONG_MOVES
19246    && get_attr_length (insn) >= ix86_cost->large_insn
19247    && peep2_regno_dead_p (0, FLAGS_REG)"
19248   [(parallel [(set (match_dup 2) (const_int 0))
19249               (clobber (reg:CC FLAGS_REG))])
19250    (set (match_dup 0) (match_dup 1))]
19251   "operands[2] = gen_lowpart (SImode, operands[1]);")
19253 (define_peephole2
19254   [(match_scratch:SI 2 "r")
19255    (set (match_operand:SI 0 "memory_operand" "")
19256         (match_operand:SI 1 "immediate_operand" ""))]
19257   "! optimize_size
19258    && get_attr_length (insn) >= ix86_cost->large_insn
19259    && TARGET_SPLIT_LONG_MOVES"
19260   [(set (match_dup 2) (match_dup 1))
19261    (set (match_dup 0) (match_dup 2))]
19262   "")
19264 (define_peephole2
19265   [(match_scratch:HI 2 "r")
19266    (set (match_operand:HI 0 "memory_operand" "")
19267         (match_operand:HI 1 "immediate_operand" ""))]
19268   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19269   && TARGET_SPLIT_LONG_MOVES"
19270   [(set (match_dup 2) (match_dup 1))
19271    (set (match_dup 0) (match_dup 2))]
19272   "")
19274 (define_peephole2
19275   [(match_scratch:QI 2 "q")
19276    (set (match_operand:QI 0 "memory_operand" "")
19277         (match_operand:QI 1 "immediate_operand" ""))]
19278   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19279   && TARGET_SPLIT_LONG_MOVES"
19280   [(set (match_dup 2) (match_dup 1))
19281    (set (match_dup 0) (match_dup 2))]
19282   "")
19284 ;; Don't compare memory with zero, load and use a test instead.
19285 (define_peephole2
19286   [(set (match_operand 0 "flags_reg_operand" "")
19287         (match_operator 1 "compare_operator"
19288           [(match_operand:SI 2 "memory_operand" "")
19289            (const_int 0)]))
19290    (match_scratch:SI 3 "r")]
19291   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19292   [(set (match_dup 3) (match_dup 2))
19293    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19294   "")
19296 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19297 ;; Don't split NOTs with a displacement operand, because resulting XOR
19298 ;; will not be pairable anyway.
19300 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19301 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19302 ;; so this split helps here as well.
19304 ;; Note: Can't do this as a regular split because we can't get proper
19305 ;; lifetime information then.
19307 (define_peephole2
19308   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19309         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19310   "!optimize_size
19311    && peep2_regno_dead_p (0, FLAGS_REG)
19312    && ((TARGET_PENTIUM 
19313         && (GET_CODE (operands[0]) != MEM
19314             || !memory_displacement_operand (operands[0], SImode)))
19315        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19316   [(parallel [(set (match_dup 0)
19317                    (xor:SI (match_dup 1) (const_int -1)))
19318               (clobber (reg:CC FLAGS_REG))])]
19319   "")
19321 (define_peephole2
19322   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19323         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19324   "!optimize_size
19325    && peep2_regno_dead_p (0, FLAGS_REG)
19326    && ((TARGET_PENTIUM 
19327         && (GET_CODE (operands[0]) != MEM
19328             || !memory_displacement_operand (operands[0], HImode)))
19329        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19330   [(parallel [(set (match_dup 0)
19331                    (xor:HI (match_dup 1) (const_int -1)))
19332               (clobber (reg:CC FLAGS_REG))])]
19333   "")
19335 (define_peephole2
19336   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19337         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19338   "!optimize_size
19339    && peep2_regno_dead_p (0, FLAGS_REG)
19340    && ((TARGET_PENTIUM 
19341         && (GET_CODE (operands[0]) != MEM
19342             || !memory_displacement_operand (operands[0], QImode)))
19343        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19344   [(parallel [(set (match_dup 0)
19345                    (xor:QI (match_dup 1) (const_int -1)))
19346               (clobber (reg:CC FLAGS_REG))])]
19347   "")
19349 ;; Non pairable "test imm, reg" instructions can be translated to
19350 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19351 ;; byte opcode instead of two, have a short form for byte operands),
19352 ;; so do it for other CPUs as well.  Given that the value was dead,
19353 ;; this should not create any new dependencies.  Pass on the sub-word
19354 ;; versions if we're concerned about partial register stalls.
19356 (define_peephole2
19357   [(set (match_operand 0 "flags_reg_operand" "")
19358         (match_operator 1 "compare_operator"
19359           [(and:SI (match_operand:SI 2 "register_operand" "")
19360                    (match_operand:SI 3 "immediate_operand" ""))
19361            (const_int 0)]))]
19362   "ix86_match_ccmode (insn, CCNOmode)
19363    && (true_regnum (operands[2]) != 0
19364        || (GET_CODE (operands[3]) == CONST_INT
19365            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19366    && peep2_reg_dead_p (1, operands[2])"
19367   [(parallel
19368      [(set (match_dup 0)
19369            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19370                             (const_int 0)]))
19371       (set (match_dup 2)
19372            (and:SI (match_dup 2) (match_dup 3)))])]
19373   "")
19375 ;; We don't need to handle HImode case, because it will be promoted to SImode
19376 ;; on ! TARGET_PARTIAL_REG_STALL
19378 (define_peephole2
19379   [(set (match_operand 0 "flags_reg_operand" "")
19380         (match_operator 1 "compare_operator"
19381           [(and:QI (match_operand:QI 2 "register_operand" "")
19382                    (match_operand:QI 3 "immediate_operand" ""))
19383            (const_int 0)]))]
19384   "! TARGET_PARTIAL_REG_STALL
19385    && ix86_match_ccmode (insn, CCNOmode)
19386    && true_regnum (operands[2]) != 0
19387    && peep2_reg_dead_p (1, operands[2])"
19388   [(parallel
19389      [(set (match_dup 0)
19390            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19391                             (const_int 0)]))
19392       (set (match_dup 2)
19393            (and:QI (match_dup 2) (match_dup 3)))])]
19394   "")
19396 (define_peephole2
19397   [(set (match_operand 0 "flags_reg_operand" "")
19398         (match_operator 1 "compare_operator"
19399           [(and:SI
19400              (zero_extract:SI
19401                (match_operand 2 "ext_register_operand" "")
19402                (const_int 8)
19403                (const_int 8))
19404              (match_operand 3 "const_int_operand" ""))
19405            (const_int 0)]))]
19406   "! TARGET_PARTIAL_REG_STALL
19407    && ix86_match_ccmode (insn, CCNOmode)
19408    && true_regnum (operands[2]) != 0
19409    && peep2_reg_dead_p (1, operands[2])"
19410   [(parallel [(set (match_dup 0)
19411                    (match_op_dup 1
19412                      [(and:SI
19413                         (zero_extract:SI
19414                           (match_dup 2)
19415                           (const_int 8)
19416                           (const_int 8))
19417                         (match_dup 3))
19418                       (const_int 0)]))
19419               (set (zero_extract:SI (match_dup 2)
19420                                     (const_int 8)
19421                                     (const_int 8))
19422                    (and:SI 
19423                      (zero_extract:SI
19424                        (match_dup 2)
19425                        (const_int 8)
19426                        (const_int 8))
19427                      (match_dup 3)))])]
19428   "")
19430 ;; Don't do logical operations with memory inputs.
19431 (define_peephole2
19432   [(match_scratch:SI 2 "r")
19433    (parallel [(set (match_operand:SI 0 "register_operand" "")
19434                    (match_operator:SI 3 "arith_or_logical_operator"
19435                      [(match_dup 0)
19436                       (match_operand:SI 1 "memory_operand" "")]))
19437               (clobber (reg:CC FLAGS_REG))])]
19438   "! optimize_size && ! TARGET_READ_MODIFY"
19439   [(set (match_dup 2) (match_dup 1))
19440    (parallel [(set (match_dup 0)
19441                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19442               (clobber (reg:CC FLAGS_REG))])]
19443   "")
19445 (define_peephole2
19446   [(match_scratch:SI 2 "r")
19447    (parallel [(set (match_operand:SI 0 "register_operand" "")
19448                    (match_operator:SI 3 "arith_or_logical_operator"
19449                      [(match_operand:SI 1 "memory_operand" "")
19450                       (match_dup 0)]))
19451               (clobber (reg:CC FLAGS_REG))])]
19452   "! optimize_size && ! TARGET_READ_MODIFY"
19453   [(set (match_dup 2) (match_dup 1))
19454    (parallel [(set (match_dup 0)
19455                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19456               (clobber (reg:CC FLAGS_REG))])]
19457   "")
19459 ; Don't do logical operations with memory outputs
19461 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19462 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19463 ; the same decoder scheduling characteristics as the original.
19465 (define_peephole2
19466   [(match_scratch:SI 2 "r")
19467    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19468                    (match_operator:SI 3 "arith_or_logical_operator"
19469                      [(match_dup 0)
19470                       (match_operand:SI 1 "nonmemory_operand" "")]))
19471               (clobber (reg:CC FLAGS_REG))])]
19472   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19473   [(set (match_dup 2) (match_dup 0))
19474    (parallel [(set (match_dup 2)
19475                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19476               (clobber (reg:CC FLAGS_REG))])
19477    (set (match_dup 0) (match_dup 2))]
19478   "")
19480 (define_peephole2
19481   [(match_scratch:SI 2 "r")
19482    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19483                    (match_operator:SI 3 "arith_or_logical_operator"
19484                      [(match_operand:SI 1 "nonmemory_operand" "")
19485                       (match_dup 0)]))
19486               (clobber (reg:CC FLAGS_REG))])]
19487   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19488   [(set (match_dup 2) (match_dup 0))
19489    (parallel [(set (match_dup 2)
19490                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19491               (clobber (reg:CC FLAGS_REG))])
19492    (set (match_dup 0) (match_dup 2))]
19493   "")
19495 ;; Attempt to always use XOR for zeroing registers.
19496 (define_peephole2
19497   [(set (match_operand 0 "register_operand" "")
19498         (match_operand 1 "const0_operand" ""))]
19499   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19500    && (! TARGET_USE_MOV0 || optimize_size)
19501    && GENERAL_REG_P (operands[0])
19502    && peep2_regno_dead_p (0, FLAGS_REG)"
19503   [(parallel [(set (match_dup 0) (const_int 0))
19504               (clobber (reg:CC FLAGS_REG))])]
19506   operands[0] = gen_lowpart (word_mode, operands[0]);
19509 (define_peephole2
19510   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19511         (const_int 0))]
19512   "(GET_MODE (operands[0]) == QImode
19513     || GET_MODE (operands[0]) == HImode)
19514    && (! TARGET_USE_MOV0 || optimize_size)
19515    && peep2_regno_dead_p (0, FLAGS_REG)"
19516   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19517               (clobber (reg:CC FLAGS_REG))])])
19519 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19520 (define_peephole2
19521   [(set (match_operand 0 "register_operand" "")
19522         (const_int -1))]
19523   "(GET_MODE (operands[0]) == HImode
19524     || GET_MODE (operands[0]) == SImode 
19525     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19526    && (optimize_size || TARGET_PENTIUM)
19527    && peep2_regno_dead_p (0, FLAGS_REG)"
19528   [(parallel [(set (match_dup 0) (const_int -1))
19529               (clobber (reg:CC FLAGS_REG))])]
19530   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19531                               operands[0]);")
19533 ;; Attempt to convert simple leas to adds. These can be created by
19534 ;; move expanders.
19535 (define_peephole2
19536   [(set (match_operand:SI 0 "register_operand" "")
19537         (plus:SI (match_dup 0)
19538                  (match_operand:SI 1 "nonmemory_operand" "")))]
19539   "peep2_regno_dead_p (0, FLAGS_REG)"
19540   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19541               (clobber (reg:CC FLAGS_REG))])]
19542   "")
19544 (define_peephole2
19545   [(set (match_operand:SI 0 "register_operand" "")
19546         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19547                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19548   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19549   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19550               (clobber (reg:CC FLAGS_REG))])]
19551   "operands[2] = gen_lowpart (SImode, operands[2]);")
19553 (define_peephole2
19554   [(set (match_operand:DI 0 "register_operand" "")
19555         (plus:DI (match_dup 0)
19556                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19557   "peep2_regno_dead_p (0, FLAGS_REG)"
19558   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19559               (clobber (reg:CC FLAGS_REG))])]
19560   "")
19562 (define_peephole2
19563   [(set (match_operand:SI 0 "register_operand" "")
19564         (mult:SI (match_dup 0)
19565                  (match_operand:SI 1 "const_int_operand" "")))]
19566   "exact_log2 (INTVAL (operands[1])) >= 0
19567    && peep2_regno_dead_p (0, FLAGS_REG)"
19568   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19569               (clobber (reg:CC FLAGS_REG))])]
19570   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19572 (define_peephole2
19573   [(set (match_operand:DI 0 "register_operand" "")
19574         (mult:DI (match_dup 0)
19575                  (match_operand:DI 1 "const_int_operand" "")))]
19576   "exact_log2 (INTVAL (operands[1])) >= 0
19577    && peep2_regno_dead_p (0, FLAGS_REG)"
19578   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19579               (clobber (reg:CC FLAGS_REG))])]
19580   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19582 (define_peephole2
19583   [(set (match_operand:SI 0 "register_operand" "")
19584         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19585                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19586   "exact_log2 (INTVAL (operands[2])) >= 0
19587    && REGNO (operands[0]) == REGNO (operands[1])
19588    && peep2_regno_dead_p (0, FLAGS_REG)"
19589   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19590               (clobber (reg:CC FLAGS_REG))])]
19591   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19593 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19594 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19595 ;; many CPUs it is also faster, since special hardware to avoid esp
19596 ;; dependencies is present.
19598 ;; While some of these conversions may be done using splitters, we use peepholes
19599 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19601 ;; Convert prologue esp subtractions to push.
19602 ;; We need register to push.  In order to keep verify_flow_info happy we have
19603 ;; two choices
19604 ;; - use scratch and clobber it in order to avoid dependencies
19605 ;; - use already live register
19606 ;; We can't use the second way right now, since there is no reliable way how to
19607 ;; verify that given register is live.  First choice will also most likely in
19608 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19609 ;; call clobbered registers are dead.  We may want to use base pointer as an
19610 ;; alternative when no register is available later.
19612 (define_peephole2
19613   [(match_scratch:SI 0 "r")
19614    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19615               (clobber (reg:CC FLAGS_REG))
19616               (clobber (mem:BLK (scratch)))])]
19617   "optimize_size || !TARGET_SUB_ESP_4"
19618   [(clobber (match_dup 0))
19619    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19620               (clobber (mem:BLK (scratch)))])])
19622 (define_peephole2
19623   [(match_scratch:SI 0 "r")
19624    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19625               (clobber (reg:CC FLAGS_REG))
19626               (clobber (mem:BLK (scratch)))])]
19627   "optimize_size || !TARGET_SUB_ESP_8"
19628   [(clobber (match_dup 0))
19629    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19630    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631               (clobber (mem:BLK (scratch)))])])
19633 ;; Convert esp subtractions to push.
19634 (define_peephole2
19635   [(match_scratch:SI 0 "r")
19636    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19637               (clobber (reg:CC FLAGS_REG))])]
19638   "optimize_size || !TARGET_SUB_ESP_4"
19639   [(clobber (match_dup 0))
19640    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19642 (define_peephole2
19643   [(match_scratch:SI 0 "r")
19644    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19645               (clobber (reg:CC FLAGS_REG))])]
19646   "optimize_size || !TARGET_SUB_ESP_8"
19647   [(clobber (match_dup 0))
19648    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19649    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19651 ;; Convert epilogue deallocator to pop.
19652 (define_peephole2
19653   [(match_scratch:SI 0 "r")
19654    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19655               (clobber (reg:CC FLAGS_REG))
19656               (clobber (mem:BLK (scratch)))])]
19657   "optimize_size || !TARGET_ADD_ESP_4"
19658   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19659               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19660               (clobber (mem:BLK (scratch)))])]
19661   "")
19663 ;; Two pops case is tricky, since pop causes dependency on destination register.
19664 ;; We use two registers if available.
19665 (define_peephole2
19666   [(match_scratch:SI 0 "r")
19667    (match_scratch:SI 1 "r")
19668    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19669               (clobber (reg:CC FLAGS_REG))
19670               (clobber (mem:BLK (scratch)))])]
19671   "optimize_size || !TARGET_ADD_ESP_8"
19672   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19673               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19674               (clobber (mem:BLK (scratch)))])
19675    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19676               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19677   "")
19679 (define_peephole2
19680   [(match_scratch:SI 0 "r")
19681    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19682               (clobber (reg:CC FLAGS_REG))
19683               (clobber (mem:BLK (scratch)))])]
19684   "optimize_size"
19685   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19686               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19687               (clobber (mem:BLK (scratch)))])
19688    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19689               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19690   "")
19692 ;; Convert esp additions to pop.
19693 (define_peephole2
19694   [(match_scratch:SI 0 "r")
19695    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19696               (clobber (reg:CC FLAGS_REG))])]
19697   ""
19698   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19699               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19700   "")
19702 ;; Two pops case is tricky, since pop causes dependency on destination register.
19703 ;; We use two registers if available.
19704 (define_peephole2
19705   [(match_scratch:SI 0 "r")
19706    (match_scratch:SI 1 "r")
19707    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19708               (clobber (reg:CC FLAGS_REG))])]
19709   ""
19710   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19711               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19712    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19713               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19714   "")
19716 (define_peephole2
19717   [(match_scratch:SI 0 "r")
19718    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19719               (clobber (reg:CC FLAGS_REG))])]
19720   "optimize_size"
19721   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19722               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19723    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19724               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19725   "")
19727 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19728 ;; required and register dies.  Similarly for 128 to plus -128.
19729 (define_peephole2
19730   [(set (match_operand 0 "flags_reg_operand" "")
19731         (match_operator 1 "compare_operator"
19732           [(match_operand 2 "register_operand" "")
19733            (match_operand 3 "const_int_operand" "")]))]
19734   "(INTVAL (operands[3]) == -1
19735     || INTVAL (operands[3]) == 1
19736     || INTVAL (operands[3]) == 128)
19737    && ix86_match_ccmode (insn, CCGCmode)
19738    && peep2_reg_dead_p (1, operands[2])"
19739   [(parallel [(set (match_dup 0)
19740                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19741               (clobber (match_dup 2))])]
19742   "")
19744 (define_peephole2
19745   [(match_scratch:DI 0 "r")
19746    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19747               (clobber (reg:CC FLAGS_REG))
19748               (clobber (mem:BLK (scratch)))])]
19749   "optimize_size || !TARGET_SUB_ESP_4"
19750   [(clobber (match_dup 0))
19751    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19752               (clobber (mem:BLK (scratch)))])])
19754 (define_peephole2
19755   [(match_scratch:DI 0 "r")
19756    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19757               (clobber (reg:CC FLAGS_REG))
19758               (clobber (mem:BLK (scratch)))])]
19759   "optimize_size || !TARGET_SUB_ESP_8"
19760   [(clobber (match_dup 0))
19761    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19762    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763               (clobber (mem:BLK (scratch)))])])
19765 ;; Convert esp subtractions to push.
19766 (define_peephole2
19767   [(match_scratch:DI 0 "r")
19768    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19769               (clobber (reg:CC FLAGS_REG))])]
19770   "optimize_size || !TARGET_SUB_ESP_4"
19771   [(clobber (match_dup 0))
19772    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19774 (define_peephole2
19775   [(match_scratch:DI 0 "r")
19776    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "optimize_size || !TARGET_SUB_ESP_8"
19779   [(clobber (match_dup 0))
19780    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19781    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19783 ;; Convert epilogue deallocator to pop.
19784 (define_peephole2
19785   [(match_scratch:DI 0 "r")
19786    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19787               (clobber (reg:CC FLAGS_REG))
19788               (clobber (mem:BLK (scratch)))])]
19789   "optimize_size || !TARGET_ADD_ESP_4"
19790   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19791               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19792               (clobber (mem:BLK (scratch)))])]
19793   "")
19795 ;; Two pops case is tricky, since pop causes dependency on destination register.
19796 ;; We use two registers if available.
19797 (define_peephole2
19798   [(match_scratch:DI 0 "r")
19799    (match_scratch:DI 1 "r")
19800    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19801               (clobber (reg:CC FLAGS_REG))
19802               (clobber (mem:BLK (scratch)))])]
19803   "optimize_size || !TARGET_ADD_ESP_8"
19804   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19805               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19806               (clobber (mem:BLK (scratch)))])
19807    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19808               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19809   "")
19811 (define_peephole2
19812   [(match_scratch:DI 0 "r")
19813    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19814               (clobber (reg:CC FLAGS_REG))
19815               (clobber (mem:BLK (scratch)))])]
19816   "optimize_size"
19817   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19818               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19819               (clobber (mem:BLK (scratch)))])
19820    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19821               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19822   "")
19824 ;; Convert esp additions to pop.
19825 (define_peephole2
19826   [(match_scratch:DI 0 "r")
19827    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19828               (clobber (reg:CC FLAGS_REG))])]
19829   ""
19830   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19831               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19832   "")
19834 ;; Two pops case is tricky, since pop causes dependency on destination register.
19835 ;; We use two registers if available.
19836 (define_peephole2
19837   [(match_scratch:DI 0 "r")
19838    (match_scratch:DI 1 "r")
19839    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19840               (clobber (reg:CC FLAGS_REG))])]
19841   ""
19842   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19843               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19844    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19845               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19846   "")
19848 (define_peephole2
19849   [(match_scratch:DI 0 "r")
19850    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19851               (clobber (reg:CC FLAGS_REG))])]
19852   "optimize_size"
19853   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19855    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19856               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19857   "")
19859 ;; Convert imul by three, five and nine into lea
19860 (define_peephole2
19861   [(parallel
19862     [(set (match_operand:SI 0 "register_operand" "")
19863           (mult:SI (match_operand:SI 1 "register_operand" "")
19864                    (match_operand:SI 2 "const_int_operand" "")))
19865      (clobber (reg:CC FLAGS_REG))])]
19866   "INTVAL (operands[2]) == 3
19867    || INTVAL (operands[2]) == 5
19868    || INTVAL (operands[2]) == 9"
19869   [(set (match_dup 0)
19870         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19871                  (match_dup 1)))]
19872   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19874 (define_peephole2
19875   [(parallel
19876     [(set (match_operand:SI 0 "register_operand" "")
19877           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19878                    (match_operand:SI 2 "const_int_operand" "")))
19879      (clobber (reg:CC FLAGS_REG))])]
19880   "!optimize_size 
19881    && (INTVAL (operands[2]) == 3
19882        || INTVAL (operands[2]) == 5
19883        || INTVAL (operands[2]) == 9)"
19884   [(set (match_dup 0) (match_dup 1))
19885    (set (match_dup 0)
19886         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19887                  (match_dup 0)))]
19888   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19890 (define_peephole2
19891   [(parallel
19892     [(set (match_operand:DI 0 "register_operand" "")
19893           (mult:DI (match_operand:DI 1 "register_operand" "")
19894                    (match_operand:DI 2 "const_int_operand" "")))
19895      (clobber (reg:CC FLAGS_REG))])]
19896   "TARGET_64BIT
19897    && (INTVAL (operands[2]) == 3
19898        || INTVAL (operands[2]) == 5
19899        || INTVAL (operands[2]) == 9)"
19900   [(set (match_dup 0)
19901         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19902                  (match_dup 1)))]
19903   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19905 (define_peephole2
19906   [(parallel
19907     [(set (match_operand:DI 0 "register_operand" "")
19908           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19909                    (match_operand:DI 2 "const_int_operand" "")))
19910      (clobber (reg:CC FLAGS_REG))])]
19911   "TARGET_64BIT
19912    && !optimize_size 
19913    && (INTVAL (operands[2]) == 3
19914        || INTVAL (operands[2]) == 5
19915        || INTVAL (operands[2]) == 9)"
19916   [(set (match_dup 0) (match_dup 1))
19917    (set (match_dup 0)
19918         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19919                  (match_dup 0)))]
19920   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19922 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19923 ;; imul $32bit_imm, reg, reg is direct decoded.
19924 (define_peephole2
19925   [(match_scratch:DI 3 "r")
19926    (parallel [(set (match_operand:DI 0 "register_operand" "")
19927                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19928                             (match_operand:DI 2 "immediate_operand" "")))
19929               (clobber (reg:CC FLAGS_REG))])]
19930   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19931    && (GET_CODE (operands[2]) != CONST_INT
19932        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
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    && (GET_CODE (operands[2]) != CONST_INT
19946        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19947   [(set (match_dup 3) (match_dup 1))
19948    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19949               (clobber (reg:CC FLAGS_REG))])]
19952 (define_peephole2
19953   [(match_scratch:SI 3 "r")
19954    (parallel [(set (match_operand:DI 0 "register_operand" "")
19955                    (zero_extend:DI
19956                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19957                               (match_operand:SI 2 "immediate_operand" ""))))
19958               (clobber (reg:CC FLAGS_REG))])]
19959   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19960    && (GET_CODE (operands[2]) != CONST_INT
19961        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19962   [(set (match_dup 3) (match_dup 1))
19963    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19964               (clobber (reg:CC FLAGS_REG))])]
19967 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19968 ;; Convert it into imul reg, reg
19969 ;; It would be better to force assembler to encode instruction using long
19970 ;; immediate, but there is apparently no way to do so.
19971 (define_peephole2
19972   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19973                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19974                             (match_operand:DI 2 "const_int_operand" "")))
19975               (clobber (reg:CC FLAGS_REG))])
19976    (match_scratch:DI 3 "r")]
19977   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19978    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19979   [(set (match_dup 3) (match_dup 2))
19980    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19981               (clobber (reg:CC FLAGS_REG))])]
19983   if (!rtx_equal_p (operands[0], operands[1]))
19984     emit_move_insn (operands[0], operands[1]);
19987 (define_peephole2
19988   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19989                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19990                             (match_operand:SI 2 "const_int_operand" "")))
19991               (clobber (reg:CC FLAGS_REG))])
19992    (match_scratch:SI 3 "r")]
19993   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19994    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19995   [(set (match_dup 3) (match_dup 2))
19996    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19997               (clobber (reg:CC FLAGS_REG))])]
19999   if (!rtx_equal_p (operands[0], operands[1]))
20000     emit_move_insn (operands[0], operands[1]);
20003 (define_peephole2
20004   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20005                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20006                             (match_operand:HI 2 "immediate_operand" "")))
20007               (clobber (reg:CC FLAGS_REG))])
20008    (match_scratch:HI 3 "r")]
20009   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20010   [(set (match_dup 3) (match_dup 2))
20011    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20012               (clobber (reg:CC FLAGS_REG))])]
20014   if (!rtx_equal_p (operands[0], operands[1]))
20015     emit_move_insn (operands[0], operands[1]);
20018 ;; After splitting up read-modify operations, array accesses with memory
20019 ;; operands might end up in form:
20020 ;;  sall    $2, %eax
20021 ;;  movl    4(%esp), %edx
20022 ;;  addl    %edx, %eax
20023 ;; instead of pre-splitting:
20024 ;;  sall    $2, %eax
20025 ;;  addl    4(%esp), %eax
20026 ;; Turn it into:
20027 ;;  movl    4(%esp), %edx
20028 ;;  leal    (%edx,%eax,4), %eax
20030 (define_peephole2
20031   [(parallel [(set (match_operand 0 "register_operand" "")
20032                    (ashift (match_operand 1 "register_operand" "")
20033                            (match_operand 2 "const_int_operand" "")))
20034                (clobber (reg:CC FLAGS_REG))])
20035    (set (match_operand 3 "register_operand")
20036         (match_operand 4 "x86_64_general_operand" ""))
20037    (parallel [(set (match_operand 5 "register_operand" "")
20038                    (plus (match_operand 6 "register_operand" "")
20039                          (match_operand 7 "register_operand" "")))
20040                    (clobber (reg:CC FLAGS_REG))])]
20041   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20042    /* Validate MODE for lea.  */
20043    && ((!TARGET_PARTIAL_REG_STALL
20044         && (GET_MODE (operands[0]) == QImode
20045             || GET_MODE (operands[0]) == HImode))
20046        || GET_MODE (operands[0]) == SImode 
20047        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20048    /* We reorder load and the shift.  */
20049    && !rtx_equal_p (operands[1], operands[3])
20050    && !reg_overlap_mentioned_p (operands[0], operands[4])
20051    /* Last PLUS must consist of operand 0 and 3.  */
20052    && !rtx_equal_p (operands[0], operands[3])
20053    && (rtx_equal_p (operands[3], operands[6])
20054        || rtx_equal_p (operands[3], operands[7]))
20055    && (rtx_equal_p (operands[0], operands[6])
20056        || rtx_equal_p (operands[0], operands[7]))
20057    /* The intermediate operand 0 must die or be same as output.  */
20058    && (rtx_equal_p (operands[0], operands[5])
20059        || peep2_reg_dead_p (3, operands[0]))"
20060   [(set (match_dup 3) (match_dup 4))
20061    (set (match_dup 0) (match_dup 1))]
20063   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20064   int scale = 1 << INTVAL (operands[2]);
20065   rtx index = gen_lowpart (Pmode, operands[1]);
20066   rtx base = gen_lowpart (Pmode, operands[3]);
20067   rtx dest = gen_lowpart (mode, operands[5]);
20069   operands[1] = gen_rtx_PLUS (Pmode, base,
20070                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20071   if (mode != Pmode)
20072     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20073   operands[0] = dest;
20076 ;; Call-value patterns last so that the wildcard operand does not
20077 ;; disrupt insn-recog's switch tables.
20079 (define_insn "*call_value_pop_0"
20080   [(set (match_operand 0 "" "")
20081         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20082               (match_operand:SI 2 "" "")))
20083    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20084                             (match_operand:SI 3 "immediate_operand" "")))]
20085   "!TARGET_64BIT"
20087   if (SIBLING_CALL_P (insn))
20088     return "jmp\t%P1";
20089   else
20090     return "call\t%P1";
20092   [(set_attr "type" "callv")])
20094 (define_insn "*call_value_pop_1"
20095   [(set (match_operand 0 "" "")
20096         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20097               (match_operand:SI 2 "" "")))
20098    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20099                             (match_operand:SI 3 "immediate_operand" "i")))]
20100   "!TARGET_64BIT"
20102   if (constant_call_address_operand (operands[1], Pmode))
20103     {
20104       if (SIBLING_CALL_P (insn))
20105         return "jmp\t%P1";
20106       else
20107         return "call\t%P1";
20108     }
20109   if (SIBLING_CALL_P (insn))
20110     return "jmp\t%A1";
20111   else
20112     return "call\t%A1";
20114   [(set_attr "type" "callv")])
20116 (define_insn "*call_value_0"
20117   [(set (match_operand 0 "" "")
20118         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20119               (match_operand:SI 2 "" "")))]
20120   "!TARGET_64BIT"
20122   if (SIBLING_CALL_P (insn))
20123     return "jmp\t%P1";
20124   else
20125     return "call\t%P1";
20127   [(set_attr "type" "callv")])
20129 (define_insn "*call_value_0_rex64"
20130   [(set (match_operand 0 "" "")
20131         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20132               (match_operand:DI 2 "const_int_operand" "")))]
20133   "TARGET_64BIT"
20135   if (SIBLING_CALL_P (insn))
20136     return "jmp\t%P1";
20137   else
20138     return "call\t%P1";
20140   [(set_attr "type" "callv")])
20142 (define_insn "*call_value_1"
20143   [(set (match_operand 0 "" "")
20144         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20145               (match_operand:SI 2 "" "")))]
20146   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20148   if (constant_call_address_operand (operands[1], Pmode))
20149     return "call\t%P1";
20150   return "call\t%A1";
20152   [(set_attr "type" "callv")])
20154 (define_insn "*sibcall_value_1"
20155   [(set (match_operand 0 "" "")
20156         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20157               (match_operand:SI 2 "" "")))]
20158   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20160   if (constant_call_address_operand (operands[1], Pmode))
20161     return "jmp\t%P1";
20162   return "jmp\t%A1";
20164   [(set_attr "type" "callv")])
20166 (define_insn "*call_value_1_rex64"
20167   [(set (match_operand 0 "" "")
20168         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20169               (match_operand:DI 2 "" "")))]
20170   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20172   if (constant_call_address_operand (operands[1], Pmode))
20173     return "call\t%P1";
20174   return "call\t%A1";
20176   [(set_attr "type" "callv")])
20178 (define_insn "*sibcall_value_1_rex64"
20179   [(set (match_operand 0 "" "")
20180         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20181               (match_operand:DI 2 "" "")))]
20182   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20183   "jmp\t%P1"
20184   [(set_attr "type" "callv")])
20186 (define_insn "*sibcall_value_1_rex64_v"
20187   [(set (match_operand 0 "" "")
20188         (call (mem:QI (reg:DI 40))
20189               (match_operand:DI 1 "" "")))]
20190   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20191   "jmp\t*%%r11"
20192   [(set_attr "type" "callv")])
20194 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20195 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20196 ;; caught for use by garbage collectors and the like.  Using an insn that
20197 ;; maps to SIGILL makes it more likely the program will rightfully die.
20198 ;; Keeping with tradition, "6" is in honor of #UD.
20199 (define_insn "trap"
20200   [(trap_if (const_int 1) (const_int 6))]
20201   ""
20202   { return ASM_SHORT "0x0b0f"; }
20203   [(set_attr "length" "2")])
20205 (define_expand "sse_prologue_save"
20206   [(parallel [(set (match_operand:BLK 0 "" "")
20207                    (unspec:BLK [(reg:DI 21)
20208                                 (reg:DI 22)
20209                                 (reg:DI 23)
20210                                 (reg:DI 24)
20211                                 (reg:DI 25)
20212                                 (reg:DI 26)
20213                                 (reg:DI 27)
20214                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20215               (use (match_operand:DI 1 "register_operand" ""))
20216               (use (match_operand:DI 2 "immediate_operand" ""))
20217               (use (label_ref:DI (match_operand 3 "" "")))])]
20218   "TARGET_64BIT"
20219   "")
20221 (define_insn "*sse_prologue_save_insn"
20222   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20223                           (match_operand:DI 4 "const_int_operand" "n")))
20224         (unspec:BLK [(reg:DI 21)
20225                      (reg:DI 22)
20226                      (reg:DI 23)
20227                      (reg:DI 24)
20228                      (reg:DI 25)
20229                      (reg:DI 26)
20230                      (reg:DI 27)
20231                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20232    (use (match_operand:DI 1 "register_operand" "r"))
20233    (use (match_operand:DI 2 "const_int_operand" "i"))
20234    (use (label_ref:DI (match_operand 3 "" "X")))]
20235   "TARGET_64BIT
20236    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20237    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20238   "*
20240   int i;
20241   operands[0] = gen_rtx_MEM (Pmode,
20242                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20243   output_asm_insn (\"jmp\\t%A1\", operands);
20244   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20245     {
20246       operands[4] = adjust_address (operands[0], DImode, i*16);
20247       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20248       PUT_MODE (operands[4], TImode);
20249       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20250         output_asm_insn (\"rex\", operands);
20251       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20252     }
20253   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20254                              CODE_LABEL_NUMBER (operands[3]));
20255   RET;
20257   "
20258   [(set_attr "type" "other")
20259    (set_attr "length_immediate" "0")
20260    (set_attr "length_address" "0")
20261    (set_attr "length" "135")
20262    (set_attr "memory" "store")
20263    (set_attr "modrm" "0")
20264    (set_attr "mode" "DI")])
20266 (define_expand "prefetch"
20267   [(prefetch (match_operand 0 "address_operand" "")
20268              (match_operand:SI 1 "const_int_operand" "")
20269              (match_operand:SI 2 "const_int_operand" ""))]
20270   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20272   int rw = INTVAL (operands[1]);
20273   int locality = INTVAL (operands[2]);
20275   gcc_assert (rw == 0 || rw == 1);
20276   gcc_assert (locality >= 0 && locality <= 3);
20277   gcc_assert (GET_MODE (operands[0]) == Pmode
20278               || GET_MODE (operands[0]) == VOIDmode);
20280   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20281      supported by SSE counterpart or the SSE prefetch is not available
20282      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20283      of locality.  */
20284   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20285     operands[2] = GEN_INT (3);
20286   else
20287     operands[1] = const0_rtx;
20290 (define_insn "*prefetch_sse"
20291   [(prefetch (match_operand:SI 0 "address_operand" "p")
20292              (const_int 0)
20293              (match_operand:SI 1 "const_int_operand" ""))]
20294   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20296   static const char * const patterns[4] = {
20297    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20298   };
20300   int locality = INTVAL (operands[1]);
20301   gcc_assert (locality >= 0 && locality <= 3);
20303   return patterns[locality];  
20305   [(set_attr "type" "sse")
20306    (set_attr "memory" "none")])
20308 (define_insn "*prefetch_sse_rex"
20309   [(prefetch (match_operand:DI 0 "address_operand" "p")
20310              (const_int 0)
20311              (match_operand:SI 1 "const_int_operand" ""))]
20312   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20314   static const char * const patterns[4] = {
20315    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20316   };
20318   int locality = INTVAL (operands[1]);
20319   gcc_assert (locality >= 0 && locality <= 3);
20321   return patterns[locality];  
20323   [(set_attr "type" "sse")
20324    (set_attr "memory" "none")])
20326 (define_insn "*prefetch_3dnow"
20327   [(prefetch (match_operand:SI 0 "address_operand" "p")
20328              (match_operand:SI 1 "const_int_operand" "n")
20329              (const_int 3))]
20330   "TARGET_3DNOW && !TARGET_64BIT"
20332   if (INTVAL (operands[1]) == 0)
20333     return "prefetch\t%a0";
20334   else
20335     return "prefetchw\t%a0";
20337   [(set_attr "type" "mmx")
20338    (set_attr "memory" "none")])
20340 (define_insn "*prefetch_3dnow_rex"
20341   [(prefetch (match_operand:DI 0 "address_operand" "p")
20342              (match_operand:SI 1 "const_int_operand" "n")
20343              (const_int 3))]
20344   "TARGET_3DNOW && TARGET_64BIT"
20346   if (INTVAL (operands[1]) == 0)
20347     return "prefetch\t%a0";
20348   else
20349     return "prefetchw\t%a0";
20351   [(set_attr "type" "mmx")
20352    (set_attr "memory" "none")])
20354 (define_expand "stack_protect_set"
20355   [(match_operand 0 "memory_operand" "")
20356    (match_operand 1 "memory_operand" "")]
20357   ""
20359 #ifdef TARGET_THREAD_SSP_OFFSET
20360   if (TARGET_64BIT)
20361     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20362                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20363   else
20364     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20365                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20366 #else
20367   if (TARGET_64BIT)
20368     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20369   else
20370     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20371 #endif
20372   DONE;
20375 (define_insn "stack_protect_set_si"
20376   [(set (match_operand:SI 0 "memory_operand" "=m")
20377         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20378    (set (match_scratch:SI 2 "=&r") (const_int 0))
20379    (clobber (reg:CC FLAGS_REG))]
20380   ""
20381   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20382   [(set_attr "type" "multi")])
20384 (define_insn "stack_protect_set_di"
20385   [(set (match_operand:DI 0 "memory_operand" "=m")
20386         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20387    (set (match_scratch:DI 2 "=&r") (const_int 0))
20388    (clobber (reg:CC FLAGS_REG))]
20389   "TARGET_64BIT"
20390   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20391   [(set_attr "type" "multi")])
20393 (define_insn "stack_tls_protect_set_si"
20394   [(set (match_operand:SI 0 "memory_operand" "=m")
20395         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20396    (set (match_scratch:SI 2 "=&r") (const_int 0))
20397    (clobber (reg:CC FLAGS_REG))]
20398   ""
20399   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20400   [(set_attr "type" "multi")])
20402 (define_insn "stack_tls_protect_set_di"
20403   [(set (match_operand:DI 0 "memory_operand" "=m")
20404         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20405    (set (match_scratch:DI 2 "=&r") (const_int 0))
20406    (clobber (reg:CC FLAGS_REG))]
20407   "TARGET_64BIT"
20408   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20409   [(set_attr "type" "multi")])
20411 (define_expand "stack_protect_test"
20412   [(match_operand 0 "memory_operand" "")
20413    (match_operand 1 "memory_operand" "")
20414    (match_operand 2 "" "")]
20415   ""
20417   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20418   ix86_compare_op0 = operands[0];
20419   ix86_compare_op1 = operands[1];
20420   ix86_compare_emitted = flags;
20422 #ifdef TARGET_THREAD_SSP_OFFSET
20423   if (TARGET_64BIT)
20424     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20425                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20426   else
20427     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20428                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20429 #else
20430   if (TARGET_64BIT)
20431     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20432   else
20433     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20434 #endif
20435   emit_jump_insn (gen_beq (operands[2]));
20436   DONE;
20439 (define_insn "stack_protect_test_si"
20440   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20441         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20442                      (match_operand:SI 2 "memory_operand" "m")]
20443                     UNSPEC_SP_TEST))
20444    (clobber (match_scratch:SI 3 "=&r"))]
20445   ""
20446   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20447   [(set_attr "type" "multi")])
20449 (define_insn "stack_protect_test_di"
20450   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20451         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20452                      (match_operand:DI 2 "memory_operand" "m")]
20453                     UNSPEC_SP_TEST))
20454    (clobber (match_scratch:DI 3 "=&r"))]
20455   "TARGET_64BIT"
20456   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20457   [(set_attr "type" "multi")])
20459 (define_insn "stack_tls_protect_test_si"
20460   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20461         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20462                      (match_operand:SI 2 "const_int_operand" "i")]
20463                     UNSPEC_SP_TLS_TEST))
20464    (clobber (match_scratch:SI 3 "=r"))]
20465   ""
20466   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20467   [(set_attr "type" "multi")])
20469 (define_insn "stack_tls_protect_test_di"
20470   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20471         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20472                      (match_operand:DI 2 "const_int_operand" "i")]
20473                     UNSPEC_SP_TLS_TEST))
20474    (clobber (match_scratch:DI 3 "=r"))]
20475   "TARGET_64BIT"
20476   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20477   [(set_attr "type" "multi")])
20479 (include "sse.md")
20480 (include "mmx.md")
20481 (include "sync.md")