PR target/19398
[official-gcc.git] / gcc / config / i386 / i386.md
blob997f051414932075c258a843d3ae45656f080594
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151   ])
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191   (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates and constraints
480 (include "predicates.md")
481 (include "constraints.md")
484 ;; Compare instructions.
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
490 (define_expand "cmpti"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493                     (match_operand:TI 1 "x86_64_general_operand" "")))]
494   "TARGET_64BIT"
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (TImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
503 (define_expand "cmpdi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506                     (match_operand:DI 1 "x86_64_general_operand" "")))]
507   ""
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (DImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
516 (define_expand "cmpsi"
517   [(set (reg:CC FLAGS_REG)
518         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519                     (match_operand:SI 1 "general_operand" "")))]
520   ""
522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523     operands[0] = force_reg (SImode, operands[0]);
524   ix86_compare_op0 = operands[0];
525   ix86_compare_op1 = operands[1];
526   DONE;
529 (define_expand "cmphi"
530   [(set (reg:CC FLAGS_REG)
531         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532                     (match_operand:HI 1 "general_operand" "")))]
533   ""
535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536     operands[0] = force_reg (HImode, operands[0]);
537   ix86_compare_op0 = operands[0];
538   ix86_compare_op1 = operands[1];
539   DONE;
542 (define_expand "cmpqi"
543   [(set (reg:CC FLAGS_REG)
544         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545                     (match_operand:QI 1 "general_operand" "")))]
546   "TARGET_QIMODE_MATH"
548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549     operands[0] = force_reg (QImode, operands[0]);
550   ix86_compare_op0 = operands[0];
551   ix86_compare_op1 = operands[1];
552   DONE;
555 (define_insn "cmpdi_ccno_1_rex64"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:DI 1 "const0_operand" "n,n")))]
559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{q}\t{%0, %0|%0, %0}
562    cmp{q}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "DI")])
567 (define_insn "*cmpdi_minus_1_rex64"
568   [(set (reg FLAGS_REG)
569         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571                  (const_int 0)))]
572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{q}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "DI")])
577 (define_expand "cmpdi_1_rex64"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580                     (match_operand:DI 1 "general_operand" "")))]
581   "TARGET_64BIT"
582   "")
584 (define_insn "cmpdi_1_insn_rex64"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589   "cmp{q}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "DI")])
594 (define_insn "*cmpsi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:SI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{l}\t{%0, %0|%0, %0}
601    cmp{l}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "SI")])
606 (define_insn "*cmpsi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:SI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{l}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "SI")])
616 (define_expand "cmpsi_1"
617   [(set (reg:CC FLAGS_REG)
618         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                     (match_operand:SI 1 "general_operand" "ri,mr")))]
620   ""
621   "")
623 (define_insn "*cmpsi_1_insn"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:SI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628     && ix86_match_ccmode (insn, CCmode)"
629   "cmp{l}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "SI")])
633 (define_insn "*cmphi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636                  (match_operand:HI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{w}\t{%0, %0|%0, %0}
640    cmp{w}\t{%1, %0|%0, %1}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "HI")])
645 (define_insn "*cmphi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648                            (match_operand:HI 1 "general_operand" "ri,mr"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{w}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "HI")])
655 (define_insn "*cmphi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658                  (match_operand:HI 1 "general_operand" "ri,mr")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660    && ix86_match_ccmode (insn, CCmode)"
661   "cmp{w}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "HI")])
665 (define_insn "*cmpqi_ccno_1"
666   [(set (reg FLAGS_REG)
667         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668                  (match_operand:QI 1 "const0_operand" "n,n")))]
669   "ix86_match_ccmode (insn, CCNOmode)"
670   "@
671    test{b}\t{%0, %0|%0, %0}
672    cmp{b}\t{$0, %0|%0, 0}"
673   [(set_attr "type" "test,icmp")
674    (set_attr "length_immediate" "0,1")
675    (set_attr "mode" "QI")])
677 (define_insn "*cmpqi_1"
678   [(set (reg FLAGS_REG)
679         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680                  (match_operand:QI 1 "general_operand" "qi,mq")))]
681   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682     && ix86_match_ccmode (insn, CCmode)"
683   "cmp{b}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "QI")])
687 (define_insn "*cmpqi_minus_1"
688   [(set (reg FLAGS_REG)
689         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690                            (match_operand:QI 1 "general_operand" "qi,mq"))
691                  (const_int 0)))]
692   "ix86_match_ccmode (insn, CCGOCmode)"
693   "cmp{b}\t{%1, %0|%0, %1}"
694   [(set_attr "type" "icmp")
695    (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_1"
698   [(set (reg FLAGS_REG)
699         (compare
700           (match_operand:QI 0 "general_operand" "Qm")
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 1 "ext_register_operand" "Q")
704               (const_int 8)
705               (const_int 8)) 0)))]
706   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707   "cmp{b}\t{%h1, %0|%0, %h1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1_rex64"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "register_operand" "Q")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_2"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "const0_operand" "n")))]
734   "ix86_match_ccmode (insn, CCNOmode)"
735   "test{b}\t%h0, %h0"
736   [(set_attr "type" "test")
737    (set_attr "length_immediate" "0")
738    (set_attr "mode" "QI")])
740 (define_expand "cmpqi_ext_3"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "general_operand" "")))]
749   ""
750   "")
752 (define_insn "cmpqi_ext_3_insn"
753   [(set (reg FLAGS_REG)
754         (compare
755           (subreg:QI
756             (zero_extract:SI
757               (match_operand 0 "ext_register_operand" "Q")
758               (const_int 8)
759               (const_int 8)) 0)
760           (match_operand:QI 1 "general_operand" "Qmn")))]
761   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%1, %h0|%h0, %1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
766 (define_insn "cmpqi_ext_3_insn_rex64"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
780 (define_insn "*cmpqi_ext_4"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (subreg:QI
789             (zero_extract:SI
790               (match_operand 1 "ext_register_operand" "Q")
791               (const_int 8)
792               (const_int 8)) 0)))]
793   "ix86_match_ccmode (insn, CCmode)"
794   "cmp{b}\t{%h1, %h0|%h0, %h1}"
795   [(set_attr "type" "icmp")
796    (set_attr "mode" "QI")])
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares.  Which is what
801 ;; the old patterns did, but with many more of them.
803 (define_expand "cmpxf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806                     (match_operand:XF 1 "nonmemory_operand" "")))]
807   "TARGET_80387"
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
814 (define_expand "cmpdf"
815   [(set (reg:CC FLAGS_REG)
816         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820   ix86_compare_op0 = operands[0];
821   ix86_compare_op1 = operands[1];
822   DONE;
825 (define_expand "cmpsf"
826   [(set (reg:CC FLAGS_REG)
827         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829   "TARGET_80387 || TARGET_SSE_MATH"
831   ix86_compare_op0 = operands[0];
832   ix86_compare_op1 = operands[1];
833   DONE;
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
839 ;; CCFPmode     compare with exceptions
840 ;; CCFPUmode    compare with no exceptions
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
845 (define_insn "*cmpfp_0"
846   [(set (match_operand:HI 0 "register_operand" "=a")
847         (unspec:HI
848           [(compare:CCFP
849              (match_operand 1 "register_operand" "f")
850              (match_operand 2 "const0_operand" "X"))]
851         UNSPEC_FNSTSW))]
852   "TARGET_80387
853    && FLOAT_MODE_P (GET_MODE (operands[1]))
854    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "unit" "i387")
858    (set (attr "mode")
859      (cond [(match_operand:SF 1 "" "")
860               (const_string "SF")
861             (match_operand:DF 1 "" "")
862               (const_string "DF")
863            ]
864            (const_string "XF")))])
866 (define_insn "*cmpfp_sf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:SF 1 "register_operand" "f")
871              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "unit" "i387")
877    (set_attr "mode" "SF")])
879 (define_insn "*cmpfp_df"
880   [(set (match_operand:HI 0 "register_operand" "=a")
881         (unspec:HI
882           [(compare:CCFP
883              (match_operand:DF 1 "register_operand" "f")
884              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885           UNSPEC_FNSTSW))]
886   "TARGET_80387"
887   "* return output_fp_compare (insn, operands, 0, 0);"
888   [(set_attr "type" "multi")
889    (set_attr "unit" "i387")
890    (set_attr "mode" "DF")])
892 (define_insn "*cmpfp_xf"
893   [(set (match_operand:HI 0 "register_operand" "=a")
894         (unspec:HI
895           [(compare:CCFP
896              (match_operand:XF 1 "register_operand" "f")
897              (match_operand:XF 2 "register_operand" "f"))]
898           UNSPEC_FNSTSW))]
899   "TARGET_80387"
900   "* return output_fp_compare (insn, operands, 0, 0);"
901   [(set_attr "type" "multi")
902    (set_attr "unit" "i387")
903    (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_u"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFPU
909              (match_operand 1 "register_operand" "f")
910              (match_operand 2 "register_operand" "f"))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915   "* return output_fp_compare (insn, operands, 0, 1);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set (attr "mode")
919      (cond [(match_operand:SF 1 "" "")
920               (const_string "SF")
921             (match_operand:DF 1 "" "")
922               (const_string "DF")
923            ]
924            (const_string "XF")))])
926 (define_insn "*cmpfp_<mode>"
927   [(set (match_operand:HI 0 "register_operand" "=a")
928         (unspec:HI
929           [(compare:CCFP
930              (match_operand 1 "register_operand" "f")
931              (match_operator 3 "float_operator"
932                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933           UNSPEC_FNSTSW))]
934   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935    && FLOAT_MODE_P (GET_MODE (operands[1]))
936    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937   "* return output_fp_compare (insn, operands, 0, 0);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set_attr "fp_int_src" "true")
941    (set_attr "mode" "<MODE>")])
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
946 (define_insn "x86_fnstsw_1"
947   [(set (match_operand:HI 0 "register_operand" "=a")
948         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949   "TARGET_80387"
950   "fnstsw\t%0"
951   [(set_attr "length" "2")
952    (set_attr "mode" "SI")
953    (set_attr "unit" "i387")])
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
958 (define_insn "x86_sahf_1"
959   [(set (reg:CC FLAGS_REG)
960         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961   "!TARGET_64BIT"
962   "sahf"
963   [(set_attr "length" "1")
964    (set_attr "athlon_decode" "vector")
965    (set_attr "mode" "SI")])
967 ;; Pentium Pro can do steps 1 through 3 in one go.
969 (define_insn "*cmpfp_i_mixed"
970   [(set (reg:CCFP FLAGS_REG)
971         (compare:CCFP (match_operand 0 "register_operand" "f,x")
972                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
973   "TARGET_MIX_SSE_I387
974    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp,ssecomi")
978    (set (attr "mode")
979      (if_then_else (match_operand:SF 1 "" "")
980         (const_string "SF")
981         (const_string "DF")))
982    (set_attr "athlon_decode" "vector")])
984 (define_insn "*cmpfp_i_sse"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "x")
987                       (match_operand 1 "nonimmediate_operand" "xm")))]
988   "TARGET_SSE_MATH
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_i387"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "f")
1002                       (match_operand 1 "register_operand" "f")))]
1003   "TARGET_80387 && TARGET_CMOVE
1004    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005    && FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "fcmp")
1009    (set (attr "mode")
1010      (cond [(match_operand:SF 1 "" "")
1011               (const_string "SF")
1012             (match_operand:DF 1 "" "")
1013               (const_string "DF")
1014            ]
1015            (const_string "XF")))
1016    (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_iu_mixed"
1019   [(set (reg:CCFPU FLAGS_REG)
1020         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022   "TARGET_MIX_SSE_I387
1023    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp,ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_sse"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "x")
1036                        (match_operand 1 "nonimmediate_operand" "xm")))]
1037   "TARGET_SSE_MATH
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_387"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "f")
1051                        (match_operand 1 "register_operand" "f")))]
1052   "TARGET_80387 && TARGET_CMOVE
1053    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054    && FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "fcmp")
1058    (set (attr "mode")
1059      (cond [(match_operand:SF 1 "" "")
1060               (const_string "SF")
1061             (match_operand:DF 1 "" "")
1062               (const_string "DF")
1063            ]
1064            (const_string "XF")))
1065    (set_attr "athlon_decode" "vector")])
1067 ;; Move instructions.
1069 ;; General case of fullword move.
1071 (define_expand "movsi"
1072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073         (match_operand:SI 1 "general_operand" ""))]
1074   ""
1075   "ix86_expand_move (SImode, operands); DONE;")
1077 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1078 ;; general_operand.
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1086 (define_insn "*pushsi2"
1087   [(set (match_operand:SI 0 "push_operand" "=<")
1088         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089   "!TARGET_64BIT"
1090   "push{l}\t%1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096   [(set (match_operand:SI 0 "push_operand" "=X")
1097         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098   "TARGET_64BIT"
1099   "push{q}\t%q1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1103 (define_insn "*pushsi2_prologue"
1104   [(set (match_operand:SI 0 "push_operand" "=<")
1105         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "push{l}\t%1"
1109   [(set_attr "type" "push")
1110    (set_attr "mode" "SI")])
1112 (define_insn "*popsi1_epilogue"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI SP_REG)))
1115    (set (reg:SI SP_REG)
1116         (plus:SI (reg:SI SP_REG) (const_int 4)))
1117    (clobber (mem:BLK (scratch)))]
1118   "!TARGET_64BIT"
1119   "pop{l}\t%0"
1120   [(set_attr "type" "pop")
1121    (set_attr "mode" "SI")])
1123 (define_insn "popsi1"
1124   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125         (mem:SI (reg:SI SP_REG)))
1126    (set (reg:SI SP_REG)
1127         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1128   "!TARGET_64BIT"
1129   "pop{l}\t%0"
1130   [(set_attr "type" "pop")
1131    (set_attr "mode" "SI")])
1133 (define_insn "*movsi_xor"
1134   [(set (match_operand:SI 0 "register_operand" "=r")
1135         (match_operand:SI 1 "const0_operand" "i"))
1136    (clobber (reg:CC FLAGS_REG))]
1137   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138   "xor{l}\t{%0, %0|%0, %0}"
1139   [(set_attr "type" "alu1")
1140    (set_attr "mode" "SI")
1141    (set_attr "length_immediate" "0")])
1143 (define_insn "*movsi_or"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (match_operand:SI 1 "immediate_operand" "i"))
1146    (clobber (reg:CC FLAGS_REG))]
1147   "reload_completed
1148    && operands[1] == constm1_rtx
1149    && (TARGET_PENTIUM || optimize_size)"
1151   operands[1] = constm1_rtx;
1152   return "or{l}\t{%1, %0|%0, %1}";
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "1")])
1158 (define_insn "*movsi_1"
1159   [(set (match_operand:SI 0 "nonimmediate_operand"
1160                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161         (match_operand:SI 1 "general_operand"
1162                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165   switch (get_attr_type (insn))
1166     {
1167     case TYPE_SSELOG1:
1168       if (get_attr_mode (insn) == MODE_TI)
1169         return "pxor\t%0, %0";
1170       return "xorps\t%0, %0";
1172     case TYPE_SSEMOV:
1173       switch (get_attr_mode (insn))
1174         {
1175         case MODE_TI:
1176           return "movdqa\t{%1, %0|%0, %1}";
1177         case MODE_V4SF:
1178           return "movaps\t{%1, %0|%0, %1}";
1179         case MODE_SI:
1180           return "movd\t{%1, %0|%0, %1}";
1181         case MODE_SF:
1182           return "movss\t{%1, %0|%0, %1}";
1183         default:
1184           gcc_unreachable ();
1185         }
1187     case TYPE_MMXADD:
1188       return "pxor\t%0, %0";
1190     case TYPE_MMXMOV:
1191       if (get_attr_mode (insn) == MODE_DI)
1192         return "movq\t{%1, %0|%0, %1}";
1193       return "movd\t{%1, %0|%0, %1}";
1195     case TYPE_LEA:
1196       return "lea{l}\t{%1, %0|%0, %1}";
1198     default:
1199       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200       return "mov{l}\t{%1, %0|%0, %1}";
1201     }
1203   [(set (attr "type")
1204      (cond [(eq_attr "alternative" "2")
1205               (const_string "mmxadd")
1206             (eq_attr "alternative" "3,4,5")
1207               (const_string "mmxmov")
1208             (eq_attr "alternative" "6")
1209               (const_string "sselog1")
1210             (eq_attr "alternative" "7,8,9,10,11")
1211               (const_string "ssemov")
1212             (match_operand:DI 1 "pic_32bit_operand" "")
1213               (const_string "lea")
1214            ]
1215            (const_string "imov")))
1216    (set (attr "mode")
1217      (cond [(eq_attr "alternative" "2,3")
1218               (const_string "DI")
1219             (eq_attr "alternative" "6,7")
1220               (if_then_else
1221                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222                 (const_string "V4SF")
1223                 (const_string "TI"))
1224             (and (eq_attr "alternative" "8,9,10,11")
1225                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226               (const_string "SF")
1227            ]
1228            (const_string "SI")))])
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237   "@
1238    movabs{l}\t{%1, %P0|%P0, %1}
1239    mov{l}\t{%1, %a0|%a0, %1}"
1240   [(set_attr "type" "imov")
1241    (set_attr "modrm" "0,*")
1242    (set_attr "length_address" "8,0")
1243    (set_attr "length_immediate" "0,*")
1244    (set_attr "memory" "store")
1245    (set_attr "mode" "SI")])
1247 (define_insn "*movabssi_2_rex64"
1248   [(set (match_operand:SI 0 "register_operand" "=a,r")
1249         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251   "@
1252    movabs{l}\t{%P1, %0|%0, %P1}
1253    mov{l}\t{%a1, %0|%0, %a1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0")
1258    (set_attr "memory" "load")
1259    (set_attr "mode" "SI")])
1261 (define_insn "*swapsi"
1262   [(set (match_operand:SI 0 "register_operand" "+r")
1263         (match_operand:SI 1 "register_operand" "+r"))
1264    (set (match_dup 1)
1265         (match_dup 0))]
1266   ""
1267   "xchg{l}\t%1, %0"
1268   [(set_attr "type" "imov")
1269    (set_attr "mode" "SI")
1270    (set_attr "pent_pair" "np")
1271    (set_attr "athlon_decode" "vector")])
1273 (define_expand "movhi"
1274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275         (match_operand:HI 1 "general_operand" ""))]
1276   ""
1277   "ix86_expand_move (HImode, operands); DONE;")
1279 (define_insn "*pushhi2"
1280   [(set (match_operand:HI 0 "push_operand" "=X")
1281         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282   "!TARGET_64BIT"
1283   "push{l}\t%k1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "SI")])
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289   [(set (match_operand:HI 0 "push_operand" "=X")
1290         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291   "TARGET_64BIT"
1292   "push{q}\t%q1"
1293   [(set_attr "type" "push")
1294    (set_attr "mode" "DI")])
1296 (define_insn "*movhi_1"
1297   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301   switch (get_attr_type (insn))
1302     {
1303     case TYPE_IMOVX:
1304       /* movzwl is faster than movw on p2 due to partial word stalls,
1305          though not as fast as an aligned movl.  */
1306       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307     default:
1308       if (get_attr_mode (insn) == MODE_SI)
1309         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310       else
1311         return "mov{w}\t{%1, %0|%0, %1}";
1312     }
1314   [(set (attr "type")
1315      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316               (const_string "imov")
1317             (and (eq_attr "alternative" "0")
1318                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319                           (const_int 0))
1320                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1321                           (const_int 0))))
1322               (const_string "imov")
1323             (and (eq_attr "alternative" "1,2")
1324                  (match_operand:HI 1 "aligned_operand" ""))
1325               (const_string "imov")
1326             (and (ne (symbol_ref "TARGET_MOVX")
1327                      (const_int 0))
1328                  (eq_attr "alternative" "0,2"))
1329               (const_string "imovx")
1330            ]
1331            (const_string "imov")))
1332     (set (attr "mode")
1333       (cond [(eq_attr "type" "imovx")
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "1,2")
1336                   (match_operand:HI 1 "aligned_operand" ""))
1337                (const_string "SI")
1338              (and (eq_attr "alternative" "0")
1339                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                            (const_int 0))
1341                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                            (const_int 0))))
1343                (const_string "SI")
1344             ]
1345             (const_string "HI")))])
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354   "@
1355    movabs{w}\t{%1, %P0|%P0, %1}
1356    mov{w}\t{%1, %a0|%a0, %1}"
1357   [(set_attr "type" "imov")
1358    (set_attr "modrm" "0,*")
1359    (set_attr "length_address" "8,0")
1360    (set_attr "length_immediate" "0,*")
1361    (set_attr "memory" "store")
1362    (set_attr "mode" "HI")])
1364 (define_insn "*movabshi_2_rex64"
1365   [(set (match_operand:HI 0 "register_operand" "=a,r")
1366         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368   "@
1369    movabs{w}\t{%P1, %0|%0, %P1}
1370    mov{w}\t{%a1, %0|%0, %a1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0")
1375    (set_attr "memory" "load")
1376    (set_attr "mode" "HI")])
1378 (define_insn "*swaphi_1"
1379   [(set (match_operand:HI 0 "register_operand" "+r")
1380         (match_operand:HI 1 "register_operand" "+r"))
1381    (set (match_dup 1)
1382         (match_dup 0))]
1383   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384   "xchg{l}\t%k1, %k0"
1385   [(set_attr "type" "imov")
1386    (set_attr "mode" "SI")
1387    (set_attr "pent_pair" "np")
1388    (set_attr "athlon_decode" "vector")])
1390 (define_insn "*swaphi_2"
1391   [(set (match_operand:HI 0 "register_operand" "+r")
1392         (match_operand:HI 1 "register_operand" "+r"))
1393    (set (match_dup 1)
1394         (match_dup 0))]
1395   "TARGET_PARTIAL_REG_STALL"
1396   "xchg{w}\t%1, %0"
1397   [(set_attr "type" "imov")
1398    (set_attr "mode" "HI")
1399    (set_attr "pent_pair" "np")
1400    (set_attr "athlon_decode" "vector")])
1402 (define_expand "movstricthi"
1403   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404         (match_operand:HI 1 "general_operand" ""))]
1405   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407   /* Don't generate memory->memory moves, go through a register */
1408   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409     operands[1] = force_reg (HImode, operands[1]);
1412 (define_insn "*movstricthi_1"
1413   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414         (match_operand:HI 1 "general_operand" "rn,m"))]
1415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417   "mov{w}\t{%1, %0|%0, %1}"
1418   [(set_attr "type" "imov")
1419    (set_attr "mode" "HI")])
1421 (define_insn "*movstricthi_xor"
1422   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423         (match_operand:HI 1 "const0_operand" "i"))
1424    (clobber (reg:CC FLAGS_REG))]
1425   "reload_completed
1426    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427   "xor{w}\t{%0, %0|%0, %0}"
1428   [(set_attr "type" "alu1")
1429    (set_attr "mode" "HI")
1430    (set_attr "length_immediate" "0")])
1432 (define_expand "movqi"
1433   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434         (match_operand:QI 1 "general_operand" ""))]
1435   ""
1436   "ix86_expand_move (QImode, operands); DONE;")
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte".  But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1442 (define_insn "*pushqi2"
1443   [(set (match_operand:QI 0 "push_operand" "=X")
1444         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445   "!TARGET_64BIT"
1446   "push{l}\t%k1"
1447   [(set_attr "type" "push")
1448    (set_attr "mode" "SI")])
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452   [(set (match_operand:QI 0 "push_operand" "=X")
1453         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454   "TARGET_64BIT"
1455   "push{q}\t%q1"
1456   [(set_attr "type" "push")
1457    (set_attr "mode" "DI")])
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1464 ;; instruction).
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there.  Then we use movzx.
1469 (define_insn "*movqi_1"
1470   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474   switch (get_attr_type (insn))
1475     {
1476     case TYPE_IMOVX:
1477       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479     default:
1480       if (get_attr_mode (insn) == MODE_SI)
1481         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482       else
1483         return "mov{b}\t{%1, %0|%0, %1}";
1484     }
1486   [(set (attr "type")
1487      (cond [(and (eq_attr "alternative" "5")
1488                  (not (match_operand:QI 1 "aligned_operand" "")))
1489               (const_string "imovx")
1490             (ne (symbol_ref "optimize_size") (const_int 0))
1491               (const_string "imov")
1492             (and (eq_attr "alternative" "3")
1493                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494                           (const_int 0))
1495                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1496                           (const_int 0))))
1497               (const_string "imov")
1498             (eq_attr "alternative" "3,5")
1499               (const_string "imovx")
1500             (and (ne (symbol_ref "TARGET_MOVX")
1501                      (const_int 0))
1502                  (eq_attr "alternative" "2"))
1503               (const_string "imovx")
1504            ]
1505            (const_string "imov")))
1506    (set (attr "mode")
1507       (cond [(eq_attr "alternative" "3,4,5")
1508                (const_string "SI")
1509              (eq_attr "alternative" "6")
1510                (const_string "QI")
1511              (eq_attr "type" "imovx")
1512                (const_string "SI")
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                                 (const_int 0))
1517                             (and (eq (symbol_ref "optimize_size")
1518                                      (const_int 0))
1519                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520                                      (const_int 0))))))
1521                (const_string "SI")
1522              ;; Avoid partial register stalls when not using QImode arithmetic
1523              (and (eq_attr "type" "imov")
1524                   (and (eq_attr "alternative" "0,1")
1525                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                                 (const_int 0))
1527                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1528                                 (const_int 0)))))
1529                (const_string "SI")
1530            ]
1531            (const_string "QI")))])
1533 (define_expand "reload_outqi"
1534   [(parallel [(match_operand:QI 0 "" "=m")
1535               (match_operand:QI 1 "register_operand" "r")
1536               (match_operand:QI 2 "register_operand" "=&q")])]
1537   ""
1539   rtx op0, op1, op2;
1540   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543   if (! q_regs_operand (op1, QImode))
1544     {
1545       emit_insn (gen_movqi (op2, op1));
1546       op1 = op2;
1547     }
1548   emit_insn (gen_movqi (op0, op1));
1549   DONE;
1552 (define_insn "*swapqi_1"
1553   [(set (match_operand:QI 0 "register_operand" "+r")
1554         (match_operand:QI 1 "register_operand" "+r"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558   "xchg{l}\t%k1, %k0"
1559   [(set_attr "type" "imov")
1560    (set_attr "mode" "SI")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "athlon_decode" "vector")])
1564 (define_insn "*swapqi_2"
1565   [(set (match_operand:QI 0 "register_operand" "+q")
1566         (match_operand:QI 1 "register_operand" "+q"))
1567    (set (match_dup 1)
1568         (match_dup 0))]
1569   "TARGET_PARTIAL_REG_STALL"
1570   "xchg{b}\t%1, %0"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")
1573    (set_attr "pent_pair" "np")
1574    (set_attr "athlon_decode" "vector")])
1576 (define_expand "movstrictqi"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578         (match_operand:QI 1 "general_operand" ""))]
1579   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581   /* Don't generate memory->memory moves, go through a register.  */
1582   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583     operands[1] = force_reg (QImode, operands[1]);
1586 (define_insn "*movstrictqi_1"
1587   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588         (match_operand:QI 1 "general_operand" "*qn,m"))]
1589   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591   "mov{b}\t{%1, %0|%0, %1}"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "QI")])
1595 (define_insn "*movstrictqi_xor"
1596   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597         (match_operand:QI 1 "const0_operand" "i"))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600   "xor{b}\t{%0, %0|%0, %0}"
1601   [(set_attr "type" "alu1")
1602    (set_attr "mode" "QI")
1603    (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_extv_1"
1606   [(set (match_operand:SI 0 "register_operand" "=R")
1607         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1615 (define_insn "*movhi_extv_1"
1616   [(set (match_operand:HI 0 "register_operand" "=R")
1617         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   ""
1621   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622   [(set_attr "type" "imovx")
1623    (set_attr "mode" "SI")])
1625 (define_insn "*movqi_extv_1"
1626   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628                          (const_int 8)
1629                          (const_int 8)))]
1630   "!TARGET_64BIT"
1632   switch (get_attr_type (insn))
1633     {
1634     case TYPE_IMOVX:
1635       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636     default:
1637       return "mov{b}\t{%h1, %0|%0, %h1}";
1638     }
1640   [(set (attr "type")
1641      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643                              (ne (symbol_ref "TARGET_MOVX")
1644                                  (const_int 0))))
1645         (const_string "imovx")
1646         (const_string "imov")))
1647    (set (attr "mode")
1648      (if_then_else (eq_attr "type" "imovx")
1649         (const_string "SI")
1650         (const_string "QI")))])
1652 (define_insn "*movqi_extv_1_rex64"
1653   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "TARGET_64BIT"
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686   "@
1687    movabs{b}\t{%1, %P0|%P0, %1}
1688    mov{b}\t{%1, %a0|%a0, %1}"
1689   [(set_attr "type" "imov")
1690    (set_attr "modrm" "0,*")
1691    (set_attr "length_address" "8,0")
1692    (set_attr "length_immediate" "0,*")
1693    (set_attr "memory" "store")
1694    (set_attr "mode" "QI")])
1696 (define_insn "*movabsqi_2_rex64"
1697   [(set (match_operand:QI 0 "register_operand" "=a,r")
1698         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700   "@
1701    movabs{b}\t{%P1, %0|%0, %P1}
1702    mov{b}\t{%a1, %0|%0, %a1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0")
1707    (set_attr "memory" "load")
1708    (set_attr "mode" "QI")])
1710 (define_insn "*movdi_extzv_1"
1711   [(set (match_operand:DI 0 "register_operand" "=R")
1712         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   "TARGET_64BIT"
1716   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "DI")])
1720 (define_insn "*movsi_extzv_1"
1721   [(set (match_operand:SI 0 "register_operand" "=R")
1722         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723                          (const_int 8)
1724                          (const_int 8)))]
1725   ""
1726   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727   [(set_attr "type" "imovx")
1728    (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "!TARGET_64BIT"
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1745   [(set (attr "type")
1746      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748                              (ne (symbol_ref "TARGET_MOVX")
1749                                  (const_int 0))))
1750         (const_string "imovx")
1751         (const_string "imov")))
1752    (set (attr "mode")
1753      (if_then_else (eq_attr "type" "imovx")
1754         (const_string "SI")
1755         (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760                                     (const_int 8)
1761                                     (const_int 8)) 0))]
1762   "TARGET_64BIT"
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768     default:
1769       return "mov{b}\t{%h1, %0|%0, %h1}";
1770     }
1772   [(set (attr "type")
1773      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                         (ne (symbol_ref "TARGET_MOVX")
1775                             (const_int 0)))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:SI 1 "general_operand" "Qmn"))]
1788   "!TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1793 (define_insn "movdi_insv_1_rex64"
1794   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798   "TARGET_64BIT"
1799   "mov{b}\t{%b1, %h0|%h0, %b1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805                          (const_int 8)
1806                          (const_int 8))
1807         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808                      (const_int 8)))]
1809   ""
1810   "mov{b}\t{%h1, %h0|%h0, %h1}"
1811   [(set_attr "type" "imov")
1812    (set_attr "mode" "QI")])
1814 (define_expand "movdi"
1815   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816         (match_operand:DI 1 "general_operand" ""))]
1817   ""
1818   "ix86_expand_move (DImode, operands); DONE;")
1820 (define_insn "*pushdi"
1821   [(set (match_operand:DI 0 "push_operand" "=<")
1822         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823   "!TARGET_64BIT"
1824   "#")
1826 (define_insn "*pushdi2_rex64"
1827   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829   "TARGET_64BIT"
1830   "@
1831    push{q}\t%1
1832    #"
1833   [(set_attr "type" "push,multi")
1834    (set_attr "mode" "DI")])
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it.  In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1840 (define_peephole2
1841   [(match_scratch:DI 2 "r")
1842    (set (match_operand:DI 0 "push_operand" "")
1843         (match_operand:DI 1 "immediate_operand" ""))]
1844   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845    && !x86_64_immediate_operand (operands[1], DImode)"
1846   [(set (match_dup 2) (match_dup 1))
1847    (set (match_dup 0) (match_dup 2))]
1848   "")
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 (define_peephole2
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "immediate_operand" ""))]
1856   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858   [(set (match_dup 0) (match_dup 1))
1859    (set (match_dup 2) (match_dup 3))]
1860   "split_di (operands + 1, 1, operands + 2, operands + 3);
1861    operands[1] = gen_lowpart (DImode, operands[2]);
1862    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863                                                     GEN_INT (4)));
1864   ")
1866 (define_split
1867   [(set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870                     ? flow2_completed : reload_completed)
1871    && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode)"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1881 (define_insn "*pushdi2_prologue_rex64"
1882   [(set (match_operand:DI 0 "push_operand" "=<")
1883         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "push{q}\t%1"
1887   [(set_attr "type" "push")
1888    (set_attr "mode" "DI")])
1890 (define_insn "*popdi1_epilogue_rex64"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))
1895    (clobber (mem:BLK (scratch)))]
1896   "TARGET_64BIT"
1897   "pop{q}\t%0"
1898   [(set_attr "type" "pop")
1899    (set_attr "mode" "DI")])
1901 (define_insn "popdi1"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903         (mem:DI (reg:DI SP_REG)))
1904    (set (reg:DI SP_REG)
1905         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1906   "TARGET_64BIT"
1907   "pop{q}\t%0"
1908   [(set_attr "type" "pop")
1909    (set_attr "mode" "DI")])
1911 (define_insn "*movdi_xor_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const0_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916    && reload_completed"
1917   "xor{l}\t{%k0, %k0|%k0, %k0}"
1918   [(set_attr "type" "alu1")
1919    (set_attr "mode" "SI")
1920    (set_attr "length_immediate" "0")])
1922 (define_insn "*movdi_or_rex64"
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (match_operand:DI 1 "const_int_operand" "i"))
1925    (clobber (reg:CC FLAGS_REG))]
1926   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927    && reload_completed
1928    && operands[1] == constm1_rtx"
1930   operands[1] = constm1_rtx;
1931   return "or{q}\t{%1, %0|%0, %1}";
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "DI")
1935    (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940         (match_operand:DI 1 "general_operand"
1941                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943   "@
1944    #
1945    #
1946    pxor\t%0, %0
1947    movq\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    pxor\t%0, %0
1950    movq\t{%1, %0|%0, %1}
1951    movdqa\t{%1, %0|%0, %1}
1952    movq\t{%1, %0|%0, %1}
1953    xorps\t%0, %0
1954    movlps\t{%1, %0|%0, %1}
1955    movaps\t{%1, %0|%0, %1}
1956    movlps\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1960 (define_split
1961   [(set (match_operand:DI 0 "push_operand" "")
1962         (match_operand:DI 1 "general_operand" ""))]
1963   "!TARGET_64BIT && reload_completed
1964    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965   [(const_int 0)]
1966   "ix86_split_long_move (operands); DONE;")
1968 ;; %%% This multiword shite has got to go.
1969 (define_split
1970   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971         (match_operand:DI 1 "general_operand" ""))]
1972   "!TARGET_64BIT && reload_completed
1973    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975   [(const_int 0)]
1976   "ix86_split_long_move (operands); DONE;")
1978 (define_insn "*movdi_1_rex64"
1979   [(set (match_operand:DI 0 "nonimmediate_operand"
1980                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981         (match_operand:DI 1 "general_operand"
1982                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985   switch (get_attr_type (insn))
1986     {
1987     case TYPE_SSECVT:
1988       if (which_alternative == 13)
1989         return "movq2dq\t{%1, %0|%0, %1}";
1990       else
1991         return "movdq2q\t{%1, %0|%0, %1}";
1992     case TYPE_SSEMOV:
1993       if (get_attr_mode (insn) == MODE_TI)
1994           return "movdqa\t{%1, %0|%0, %1}";
1995       /* FALLTHRU */
1996     case TYPE_MMXMOV:
1997       /* Moves from and into integer register is done using movd opcode with
1998          REX prefix.  */
1999       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000           return "movd\t{%1, %0|%0, %1}";
2001       return "movq\t{%1, %0|%0, %1}";
2002     case TYPE_SSELOG1:
2003     case TYPE_MMXADD:
2004       return "pxor\t%0, %0";
2005     case TYPE_MULTI:
2006       return "#";
2007     case TYPE_LEA:
2008       return "lea{q}\t{%a1, %0|%0, %a1}";
2009     default:
2010       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011       if (get_attr_mode (insn) == MODE_SI)
2012         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013       else if (which_alternative == 2)
2014         return "movabs{q}\t{%1, %0|%0, %1}";
2015       else
2016         return "mov{q}\t{%1, %0|%0, %1}";
2017     }
2019   [(set (attr "type")
2020      (cond [(eq_attr "alternative" "5")
2021               (const_string "mmxadd")
2022             (eq_attr "alternative" "6,7,8")
2023               (const_string "mmxmov")
2024             (eq_attr "alternative" "9")
2025               (const_string "sselog1")
2026             (eq_attr "alternative" "10,11,12")
2027               (const_string "ssemov")
2028             (eq_attr "alternative" "13,14")
2029               (const_string "ssecvt")
2030             (eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (match_operand:DI 1 "pic_32bit_operand" "")
2033               (const_string "lea")
2034            ]
2035            (const_string "imov")))
2036    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047   "@
2048    movabs{q}\t{%1, %P0|%P0, %1}
2049    mov{q}\t{%1, %a0|%a0, %1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "modrm" "0,*")
2052    (set_attr "length_address" "8,0")
2053    (set_attr "length_immediate" "0,*")
2054    (set_attr "memory" "store")
2055    (set_attr "mode" "DI")])
2057 (define_insn "*movabsdi_2_rex64"
2058   [(set (match_operand:DI 0 "register_operand" "=a,r")
2059         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061   "@
2062    movabs{q}\t{%P1, %0|%0, %P1}
2063    mov{q}\t{%a1, %0|%0, %a1}"
2064   [(set_attr "type" "imov")
2065    (set_attr "modrm" "0,*")
2066    (set_attr "length_address" "8,0")
2067    (set_attr "length_immediate" "0")
2068    (set_attr "memory" "load")
2069    (set_attr "mode" "DI")])
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it.  In case this
2073 ;; fails, move by 32bit parts.
2074 (define_peephole2
2075   [(match_scratch:DI 2 "r")
2076    (set (match_operand:DI 0 "memory_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode)"
2080   [(set (match_dup 2) (match_dup 1))
2081    (set (match_dup 0) (match_dup 2))]
2082   "")
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088   [(set (match_operand:DI 0 "memory_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2096 (define_split
2097   [(set (match_operand:DI 0 "memory_operand" "")
2098         (match_operand:DI 1 "immediate_operand" ""))]
2099   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100                     ? flow2_completed : reload_completed)
2101    && !symbolic_operand (operands[1], DImode)
2102    && !x86_64_immediate_operand (operands[1], DImode)"
2103   [(set (match_dup 2) (match_dup 3))
2104    (set (match_dup 4) (match_dup 5))]
2105   "split_di (operands, 2, operands + 2, operands + 4);")
2107 (define_insn "*swapdi_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "+r")
2109         (match_operand:DI 1 "register_operand" "+r"))
2110    (set (match_dup 1)
2111         (match_dup 0))]
2112   "TARGET_64BIT"
2113   "xchg{q}\t%1, %0"
2114   [(set_attr "type" "imov")
2115    (set_attr "mode" "DI")
2116    (set_attr "pent_pair" "np")
2117    (set_attr "athlon_decode" "vector")])
2119 (define_expand "movti"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121         (match_operand:TI 1 "nonimmediate_operand" ""))]
2122   "TARGET_SSE || TARGET_64BIT"
2124   if (TARGET_64BIT)
2125     ix86_expand_move (TImode, operands);
2126   else
2127     ix86_expand_vector_move (TImode, operands);
2128   DONE;
2131 (define_insn "*movti_internal"
2132   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134   "TARGET_SSE && !TARGET_64BIT
2135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137   switch (which_alternative)
2138     {
2139     case 0:
2140       if (get_attr_mode (insn) == MODE_V4SF)
2141         return "xorps\t%0, %0";
2142       else
2143         return "pxor\t%0, %0";
2144     case 1:
2145     case 2:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "movaps\t{%1, %0|%0, %1}";
2148       else
2149         return "movdqa\t{%1, %0|%0, %1}";
2150     default:
2151       gcc_unreachable ();
2152     }
2154   [(set_attr "type" "sselog1,ssemov,ssemov")
2155    (set (attr "mode")
2156         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157                     (ne (symbol_ref "optimize_size") (const_int 0)))
2158                  (const_string "V4SF")
2159                (and (eq_attr "alternative" "2")
2160                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161                         (const_int 0)))
2162                  (const_string "V4SF")]
2163               (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168   "TARGET_64BIT
2169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171   switch (which_alternative)
2172     {
2173     case 0:
2174     case 1:
2175       return "#";
2176     case 2:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "xorps\t%0, %0";
2179       else
2180         return "pxor\t%0, %0";
2181     case 3:
2182     case 4:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "movaps\t{%1, %0|%0, %1}";
2185       else
2186         return "movdqa\t{%1, %0|%0, %1}";
2187     default:
2188       gcc_unreachable ();
2189     }
2191   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192    (set (attr "mode")
2193         (cond [(eq_attr "alternative" "2,3")
2194                  (if_then_else
2195                    (ne (symbol_ref "optimize_size")
2196                        (const_int 0))
2197                    (const_string "V4SF")
2198                    (const_string "TI"))
2199                (eq_attr "alternative" "4")
2200                  (if_then_else
2201                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202                             (const_int 0))
2203                         (ne (symbol_ref "optimize_size")
2204                             (const_int 0)))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))]
2207                (const_string "DI")))])
2209 (define_split
2210   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211         (match_operand:TI 1 "general_operand" ""))]
2212   "reload_completed && !SSE_REG_P (operands[0])
2213    && !SSE_REG_P (operands[1])"
2214   [(const_int 0)]
2215   "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219         (match_operand:SF 1 "general_operand" ""))]
2220   ""
2221   "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226   "!TARGET_64BIT"
2228   /* Anything else should be already split before reg-stack.  */
2229   gcc_assert (which_alternative == 1);
2230   return "push{l}\t%1";
2232   [(set_attr "type" "multi,push,multi")
2233    (set_attr "unit" "i387,*,*")
2234    (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239   "TARGET_64BIT"
2241   /* Anything else should be already split before reg-stack.  */
2242   gcc_assert (which_alternative == 1);
2243   return "push{q}\t%q1";
2245   [(set_attr "type" "multi,push,multi")
2246    (set_attr "unit" "i387,*,*")
2247    (set_attr "mode" "SF,DI,SF")])
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "memory_operand" ""))]
2252   "reload_completed
2253    && GET_CODE (operands[1]) == MEM
2254    && constant_pool_reference_p (operands[1])"
2255   [(set (match_dup 0)
2256         (match_dup 1))]
2257   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "!TARGET_64BIT"
2265   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268 (define_split
2269   [(set (match_operand:SF 0 "push_operand" "")
2270         (match_operand:SF 1 "any_fp_register_operand" ""))]
2271   "TARGET_64BIT"
2272   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276   [(set (match_operand:SF 0 "nonimmediate_operand"
2277           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2278         (match_operand:SF 1 "general_operand"
2279           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281    && (reload_in_progress || reload_completed
2282        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283        || GET_CODE (operands[1]) != CONST_DOUBLE
2284        || memory_operand (operands[0], SFmode))" 
2286   switch (which_alternative)
2287     {
2288     case 0:
2289       return output_387_reg_move (insn, operands);
2291     case 1:
2292       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293         return "fstp%z0\t%y0";
2294       else
2295         return "fst%z0\t%y0";
2297     case 2:
2298       return standard_80387_constant_opcode (operands[1]);
2300     case 3:
2301     case 4:
2302       return "mov{l}\t{%1, %0|%0, %1}";
2303     case 5:
2304       if (get_attr_mode (insn) == MODE_TI)
2305         return "pxor\t%0, %0";
2306       else
2307         return "xorps\t%0, %0";
2308     case 6:
2309       if (get_attr_mode (insn) == MODE_V4SF)
2310         return "movaps\t{%1, %0|%0, %1}";
2311       else
2312         return "movss\t{%1, %0|%0, %1}";
2313     case 7:
2314     case 8:
2315       return "movss\t{%1, %0|%0, %1}";
2317     case 9:
2318     case 10:
2319       return "movd\t{%1, %0|%0, %1}";
2321     case 11:
2322       return "movq\t{%1, %0|%0, %1}";
2324     default:
2325       gcc_unreachable ();
2326     }
2328   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329    (set (attr "mode")
2330         (cond [(eq_attr "alternative" "3,4,9,10")
2331                  (const_string "SI")
2332                (eq_attr "alternative" "5")
2333                  (if_then_else
2334                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335                                  (const_int 0))
2336                              (ne (symbol_ref "TARGET_SSE2")
2337                                  (const_int 0)))
2338                         (eq (symbol_ref "optimize_size")
2339                             (const_int 0)))
2340                    (const_string "TI")
2341                    (const_string "V4SF"))
2342                /* For architectures resolving dependencies on
2343                   whole SSE registers use APS move to break dependency
2344                   chains, otherwise use short move to avoid extra work. 
2346                   Do the same for architectures resolving dependencies on
2347                   the parts.  While in DF mode it is better to always handle
2348                   just register parts, the SF mode is different due to lack
2349                   of instructions to load just part of the register.  It is
2350                   better to maintain the whole registers in single format
2351                   to avoid problems on using packed logical operations.  */
2352                (eq_attr "alternative" "6")
2353                  (if_then_else
2354                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355                             (const_int 0))
2356                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357                             (const_int 0)))
2358                    (const_string "V4SF")
2359                    (const_string "SF"))
2360                (eq_attr "alternative" "11")
2361                  (const_string "DI")]
2362                (const_string "SF")))])
2364 (define_insn "*swapsf"
2365   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366         (match_operand:SF 1 "fp_register_operand" "+f"))
2367    (set (match_dup 1)
2368         (match_dup 0))]
2369   "reload_completed || TARGET_80387"
2371   if (STACK_TOP_P (operands[0]))
2372     return "fxch\t%1";
2373   else
2374     return "fxch\t%0";
2376   [(set_attr "type" "fxch")
2377    (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381         (match_operand:DF 1 "general_operand" ""))]
2382   ""
2383   "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter.  Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395   /* This insn should be already split before reg-stack.  */
2396   gcc_unreachable ();
2398   [(set_attr "type" "multi")
2399    (set_attr "unit" "i387,*,*,*")
2400    (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407   /* This insn should be already split before reg-stack.  */
2408   gcc_unreachable ();
2410   [(set_attr "type" "multi")
2411    (set_attr "unit" "i387,*,*")
2412    (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416   [(set (match_operand:DF 0 "push_operand" "")
2417         (match_operand:DF 1 "any_fp_register_operand" ""))]
2418   "!TARGET_64BIT && reload_completed"
2419   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421   "")
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "TARGET_64BIT && reload_completed"
2427   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429   "")
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "general_operand" ""))]
2434   "reload_completed"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443   [(set (match_operand:DF 0 "nonimmediate_operand"
2444                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2445         (match_operand:DF 1 "general_operand"
2446                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2447   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449    && (reload_in_progress || reload_completed
2450        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451        || GET_CODE (operands[1]) != CONST_DOUBLE
2452        || memory_operand (operands[0], DFmode))" 
2454   switch (which_alternative)
2455     {
2456     case 0:
2457       return output_387_reg_move (insn, operands);
2459     case 1:
2460       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461         return "fstp%z0\t%y0";
2462       else
2463         return "fst%z0\t%y0";
2465     case 2:
2466       return standard_80387_constant_opcode (operands[1]);
2468     case 3:
2469     case 4:
2470       return "#";
2471     case 5:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "xorps\t%0, %0";
2476         case MODE_V2DF:
2477           return "xorpd\t%0, %0";
2478         case MODE_TI:
2479           return "pxor\t%0, %0";
2480         default:
2481           gcc_unreachable ();
2482         }
2483     case 6:
2484     case 7:
2485     case 8:
2486       switch (get_attr_mode (insn))
2487         {
2488         case MODE_V4SF:
2489           return "movaps\t{%1, %0|%0, %1}";
2490         case MODE_V2DF:
2491           return "movapd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "movdqa\t{%1, %0|%0, %1}";
2494         case MODE_DI:
2495           return "movq\t{%1, %0|%0, %1}";
2496         case MODE_DF:
2497           return "movsd\t{%1, %0|%0, %1}";
2498         case MODE_V1DF:
2499           return "movlpd\t{%1, %0|%0, %1}";
2500         case MODE_V2SF:
2501           return "movlps\t{%1, %0|%0, %1}";
2502         default:
2503           gcc_unreachable ();
2504         }
2506     default:
2507       gcc_unreachable ();
2508     }
2510   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511    (set (attr "mode")
2512         (cond [(eq_attr "alternative" "0,1,2")
2513                  (const_string "DF")
2514                (eq_attr "alternative" "3,4")
2515                  (const_string "SI")
2517                /* For SSE1, we have many fewer alternatives.  */
2518                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519                  (cond [(eq_attr "alternative" "5,6")
2520                           (const_string "V4SF")
2521                        ]
2522                    (const_string "V2SF"))
2524                /* xorps is one byte shorter.  */
2525                (eq_attr "alternative" "5")
2526                  (cond [(ne (symbol_ref "optimize_size")
2527                             (const_int 0))
2528                           (const_string "V4SF")
2529                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530                             (const_int 0))
2531                           (const_string "TI")
2532                        ]
2533                        (const_string "V2DF"))
2535                /* For architectures resolving dependencies on
2536                   whole SSE registers use APD move to break dependency
2537                   chains, otherwise use short move to avoid extra work.
2539                   movaps encodes one byte shorter.  */
2540                (eq_attr "alternative" "6")
2541                  (cond
2542                    [(ne (symbol_ref "optimize_size")
2543                         (const_int 0))
2544                       (const_string "V4SF")
2545                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546                         (const_int 0))
2547                       (const_string "V2DF")
2548                    ]
2549                    (const_string "DF"))
2550                /* For architectures resolving dependencies on register
2551                   parts we may avoid extra work to zero out upper part
2552                   of register.  */
2553                (eq_attr "alternative" "7")
2554                  (if_then_else
2555                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556                        (const_int 0))
2557                    (const_string "V1DF")
2558                    (const_string "DF"))
2559               ]
2560               (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand"
2564                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2565         (match_operand:DF 1 "general_operand"
2566                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2567   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569    && (reload_in_progress || reload_completed
2570        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571        || GET_CODE (operands[1]) != CONST_DOUBLE
2572        || memory_operand (operands[0], DFmode))" 
2574   switch (which_alternative)
2575     {
2576     case 0:
2577       return output_387_reg_move (insn, operands);
2579     case 1:
2580       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581         return "fstp%z0\t%y0";
2582       else
2583         return "fst%z0\t%y0";
2585     case 2:
2586       return standard_80387_constant_opcode (operands[1]);
2588     case 3:
2589     case 4:
2590       return "#";
2592     case 5:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "xorps\t%0, %0";
2597         case MODE_V2DF:
2598           return "xorpd\t%0, %0";
2599         case MODE_TI:
2600           return "pxor\t%0, %0";
2601         default:
2602           gcc_unreachable ();
2603         }
2604     case 6:
2605     case 7:
2606     case 8:
2607       switch (get_attr_mode (insn))
2608         {
2609         case MODE_V4SF:
2610           return "movaps\t{%1, %0|%0, %1}";
2611         case MODE_V2DF:
2612           return "movapd\t{%1, %0|%0, %1}";
2613         case MODE_TI:
2614           return "movdqa\t{%1, %0|%0, %1}";
2615         case MODE_DI:
2616           return "movq\t{%1, %0|%0, %1}";
2617         case MODE_DF:
2618           return "movsd\t{%1, %0|%0, %1}";
2619         case MODE_V1DF:
2620           return "movlpd\t{%1, %0|%0, %1}";
2621         case MODE_V2SF:
2622           return "movlps\t{%1, %0|%0, %1}";
2623         default:
2624           gcc_unreachable ();
2625         }
2627     default:
2628       gcc_unreachable();
2629     }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "0,1,2")
2634                  (const_string "DF")
2635                (eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2638                /* For SSE1, we have many fewer alternatives.  */
2639                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640                  (cond [(eq_attr "alternative" "5,6")
2641                           (const_string "V4SF")
2642                        ]
2643                    (const_string "V2SF"))
2645                /* xorps is one byte shorter.  */
2646                (eq_attr "alternative" "5")
2647                  (cond [(ne (symbol_ref "optimize_size")
2648                             (const_int 0))
2649                           (const_string "V4SF")
2650                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                             (const_int 0))
2652                           (const_string "TI")
2653                        ]
2654                        (const_string "V2DF"))
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                    [(ne (symbol_ref "optimize_size")
2664                         (const_int 0))
2665                       (const_string "V4SF")
2666                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                         (const_int 0))
2668                       (const_string "V2DF")
2669                    ]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                        (const_int 0))
2678                    (const_string "V1DF")
2679                    (const_string "DF"))
2680               ]
2681               (const_string "DF")))])
2683 (define_split
2684   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685         (match_operand:DF 1 "general_operand" ""))]
2686   "reload_completed
2687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688    && ! (ANY_FP_REG_P (operands[0]) || 
2689          (GET_CODE (operands[0]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691    && ! (ANY_FP_REG_P (operands[1]) || 
2692          (GET_CODE (operands[1]) == SUBREG
2693           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699         (match_operand:DF 1 "fp_register_operand" "+f"))
2700    (set (match_dup 1)
2701         (match_dup 0))]
2702   "reload_completed || TARGET_80387"
2704   if (STACK_TOP_P (operands[0]))
2705     return "fxch\t%1";
2706   else
2707     return "fxch\t%0";
2709   [(set_attr "type" "fxch")
2710    (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714         (match_operand:XF 1 "general_operand" ""))]
2715   ""
2716   "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;;  handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728   "optimize_size"
2730   /* This insn should be already split before reg-stack.  */
2731   gcc_unreachable ();
2733   [(set_attr "type" "multi")
2734    (set_attr "unit" "i387,*,*")
2735    (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740   "!optimize_size"
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       return output_387_reg_move (insn, operands);
2790     case 1:
2791       /* There is no non-popping store to memory for XFmode.  So if
2792          we need one, follow the store with a load.  */
2793       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794         return "fstp%z0\t%y0\;fld%z0\t%y0";
2795       else
2796         return "fstp%z0\t%y0";
2798     case 2:
2799       return standard_80387_constant_opcode (operands[1]);
2801     case 3: case 4:
2802       return "#";
2803     default:
2804       gcc_unreachable ();
2805     }
2807   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808    (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813   "!optimize_size
2814    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815    && (reload_in_progress || reload_completed
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], XFmode))" 
2819   switch (which_alternative)
2820     {
2821     case 0:
2822       return output_387_reg_move (insn, operands);
2824     case 1:
2825       /* There is no non-popping store to memory for XFmode.  So if
2826          we need one, follow the store with a load.  */
2827       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828         return "fstp%z0\t%y0\;fld%z0\t%y0";
2829       else
2830         return "fstp%z0\t%y0";
2832     case 2:
2833       return standard_80387_constant_opcode (operands[1]);
2835     case 3: case 4:
2836       return "#";
2838     default:
2839       gcc_unreachable ();
2840     }
2842   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843    (set_attr "mode" "XF,XF,XF,SI,SI")])
2845 (define_split
2846   [(set (match_operand 0 "nonimmediate_operand" "")
2847         (match_operand 1 "general_operand" ""))]
2848   "reload_completed
2849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850    && GET_MODE (operands[0]) == XFmode
2851    && ! (ANY_FP_REG_P (operands[0]) || 
2852          (GET_CODE (operands[0]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854    && ! (ANY_FP_REG_P (operands[1]) || 
2855          (GET_CODE (operands[1]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857   [(const_int 0)]
2858   "ix86_split_long_move (operands); DONE;")
2860 (define_split
2861   [(set (match_operand 0 "register_operand" "")
2862         (match_operand 1 "memory_operand" ""))]
2863   "reload_completed
2864    && GET_CODE (operands[1]) == MEM
2865    && (GET_MODE (operands[0]) == XFmode
2866        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867    && constant_pool_reference_p (operands[1])"
2868   [(set (match_dup 0) (match_dup 1))]
2870   rtx c = avoid_constant_pool_reference (operands[1]);
2871   rtx r = operands[0];
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2889   operands[1] = c;
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2942   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037   [(set (match_operand:HI 0 "register_operand" "=r")
3038      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041   [(set_attr "type" "imovx")
3042    (set_attr "mode" "SI")])
3044 ;; For the movzbw case strip only the clobber
3045 (define_split
3046   [(set (match_operand:HI 0 "register_operand" "")
3047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048    (clobber (reg:CC FLAGS_REG))]
3049   "reload_completed 
3050    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3057 (define_split
3058   [(set (match_operand:HI 0 "register_operand" "")
3059         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060    (clobber (reg:CC FLAGS_REG))]
3061   "reload_completed
3062    && ANY_QI_REG_P (operands[0])
3063    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065   [(set (match_dup 0) (const_int 0))
3066    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067   "operands[2] = gen_lowpart (QImode, operands[0]);")
3069 ;; Rest is handled by single and.
3070 (define_split
3071   [(set (match_operand:HI 0 "register_operand" "")
3072         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && true_regnum (operands[0]) == true_regnum (operands[1])"
3076   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077               (clobber (reg:CC FLAGS_REG))])]
3078   "")
3080 (define_expand "zero_extendqisi2"
3081   [(parallel
3082     [(set (match_operand:SI 0 "register_operand" "")
3083        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084      (clobber (reg:CC FLAGS_REG))])]
3085   ""
3086   "")
3088 (define_insn "*zero_extendqisi2_and"
3089   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091    (clobber (reg:CC FLAGS_REG))]
3092   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093   "#"
3094   [(set_attr "type" "alu1")
3095    (set_attr "mode" "SI")])
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098   [(set (match_operand:SI 0 "register_operand" "=r,r")
3099      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102   "#"
3103   [(set_attr "type" "imovx,alu1")
3104    (set_attr "mode" "SI")])
3106 (define_insn "*zero_extendqisi2_movzbw"
3107   [(set (match_operand:SI 0 "register_operand" "=r")
3108      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110   "movz{bl|x}\t{%1, %0|%0, %1}"
3111   [(set_attr "type" "imovx")
3112    (set_attr "mode" "SI")])
3114 ;; For the movzbl case strip only the clobber
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed 
3120    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122   [(set (match_dup 0)
3123         (zero_extend:SI (match_dup 1)))])
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3127 (define_split
3128   [(set (match_operand:SI 0 "register_operand" "")
3129         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "reload_completed
3132    && ANY_QI_REG_P (operands[0])
3133    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136   [(set (match_dup 0) (const_int 0))
3137    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138   "operands[2] = gen_lowpart (QImode, operands[0]);")
3140 ;; Rest is handled by single and.
3141 (define_split
3142   [(set (match_operand:SI 0 "register_operand" "")
3143         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144    (clobber (reg:CC FLAGS_REG))]
3145   "reload_completed
3146    && true_regnum (operands[0]) == true_regnum (operands[1])"
3147   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148               (clobber (reg:CC FLAGS_REG))])]
3149   "")
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153   [(set (match_operand:DI 0 "register_operand" "=r")
3154      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155   ""
3156   "if (!TARGET_64BIT)
3157      {
3158        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159        DONE;
3160      }
3161   ")
3163 (define_insn "zero_extendsidi2_32"
3164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166    (clobber (reg:CC FLAGS_REG))]
3167   "!TARGET_64BIT"
3168   "@
3169    #
3170    #
3171    #
3172    movd\t{%1, %0|%0, %1}
3173    movd\t{%1, %0|%0, %1}"
3174   [(set_attr "mode" "SI,SI,SI,DI,TI")
3175    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177 (define_insn "zero_extendsidi2_rex64"
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180   "TARGET_64BIT"
3181   "@
3182    mov\t{%k1, %k0|%k0, %k1}
3183    #
3184    movd\t{%1, %0|%0, %1}
3185    movd\t{%1, %0|%0, %1}"
3186   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187    (set_attr "mode" "SI,DI,SI,SI")])
3189 (define_split
3190   [(set (match_operand:DI 0 "memory_operand" "")
3191      (zero_extend:DI (match_dup 0)))]
3192   "TARGET_64BIT"
3193   [(set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 (define_split 
3197   [(set (match_operand:DI 0 "register_operand" "")
3198         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "!TARGET_64BIT && reload_completed
3201    && true_regnum (operands[0]) == true_regnum (operands[1])"
3202   [(set (match_dup 4) (const_int 0))]
3203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 (define_split 
3206   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208    (clobber (reg:CC FLAGS_REG))]
3209   "!TARGET_64BIT && reload_completed
3210    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211   [(set (match_dup 3) (match_dup 1))
3212    (set (match_dup 4) (const_int 0))]
3213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215 (define_insn "zero_extendhidi2"
3216   [(set (match_operand:DI 0 "register_operand" "=r")
3217      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218   "TARGET_64BIT"
3219   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220   [(set_attr "type" "imovx")
3221    (set_attr "mode" "DI")])
3223 (define_insn "zero_extendqidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3231 ;; Sign extension instructions
3233 (define_expand "extendsidi2"
3234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236               (clobber (reg:CC FLAGS_REG))
3237               (clobber (match_scratch:SI 2 ""))])]
3238   ""
3240   if (TARGET_64BIT)
3241     {
3242       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243       DONE;
3244     }
3247 (define_insn "*extendsidi2_1"
3248   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250    (clobber (reg:CC FLAGS_REG))
3251    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252   "!TARGET_64BIT"
3253   "#")
3255 (define_insn "extendsidi2_rex64"
3256   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258   "TARGET_64BIT"
3259   "@
3260    {cltq|cdqe}
3261    movs{lq|x}\t{%1,%0|%0, %1}"
3262   [(set_attr "type" "imovx")
3263    (set_attr "mode" "DI")
3264    (set_attr "prefix_0f" "0")
3265    (set_attr "modrm" "0,1")])
3267 (define_insn "extendhidi2"
3268   [(set (match_operand:DI 0 "register_operand" "=r")
3269         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270   "TARGET_64BIT"
3271   "movs{wq|x}\t{%1,%0|%0, %1}"
3272   [(set_attr "type" "imovx")
3273    (set_attr "mode" "DI")])
3275 (define_insn "extendqidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "TARGET_64BIT"
3279   "movs{bq|x}\t{%1,%0|%0, %1}"
3280    [(set_attr "type" "imovx")
3281     (set_attr "mode" "DI")])
3283 ;; Extend to memory case when source register does die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "(reload_completed
3290     && dead_or_set_p (insn, operands[1])
3291     && !reg_mentioned_p (operands[1], operands[0]))"
3292   [(set (match_dup 3) (match_dup 1))
3293    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294               (clobber (reg:CC FLAGS_REG))])
3295    (set (match_dup 4) (match_dup 1))]
3296   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298 ;; Extend to memory case when source register does not die.
3299 (define_split 
3300   [(set (match_operand:DI 0 "memory_operand" "")
3301         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302    (clobber (reg:CC FLAGS_REG))
3303    (clobber (match_operand:SI 2 "register_operand" ""))]
3304   "reload_completed"
3305   [(const_int 0)]
3307   split_di (&operands[0], 1, &operands[3], &operands[4]);
3309   emit_move_insn (operands[3], operands[1]);
3311   /* Generate a cltd if possible and doing so it profitable.  */
3312   if (true_regnum (operands[1]) == 0
3313       && true_regnum (operands[2]) == 1
3314       && (optimize_size || TARGET_USE_CLTD))
3315     {
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317     }
3318   else
3319     {
3320       emit_move_insn (operands[2], operands[1]);
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322     }
3323   emit_move_insn (operands[4], operands[2]);
3324   DONE;
3327 ;; Extend to register case.  Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3329 (define_split 
3330   [(set (match_operand:DI 0 "register_operand" "")
3331         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332    (clobber (reg:CC FLAGS_REG))
3333    (clobber (match_scratch:SI 2 ""))]
3334   "reload_completed"
3335   [(const_int 0)]
3337   split_di (&operands[0], 1, &operands[3], &operands[4]);
3339   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340     emit_move_insn (operands[3], operands[1]);
3342   /* Generate a cltd if possible and doing so it profitable.  */
3343   if (true_regnum (operands[3]) == 0
3344       && (optimize_size || TARGET_USE_CLTD))
3345     {
3346       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347       DONE;
3348     }
3350   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351     emit_move_insn (operands[4], operands[1]);
3353   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354   DONE;
3357 (define_insn "extendhisi2"
3358   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360   ""
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%0|%0, %1}";
3368     }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3383 (define_insn "*extendhisi2_zext"
3384   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385         (zero_extend:DI
3386           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387   "TARGET_64BIT"
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395     }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3410 (define_insn "extendqihi2"
3411   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413   ""
3415   switch (get_attr_prefix_0f (insn))
3416     {
3417     case 0:
3418       return "{cbtw|cbw}";
3419     default:
3420       return "movs{bw|x}\t{%1,%0|%0, %1}";
3421     }
3423   [(set_attr "type" "imovx")
3424    (set_attr "mode" "HI")
3425    (set (attr "prefix_0f")
3426      ;; movsx is short decodable while cwtl is vector decoded.
3427      (if_then_else (and (eq_attr "cpu" "!k6")
3428                         (eq_attr "alternative" "0"))
3429         (const_string "0")
3430         (const_string "1")))
3431    (set (attr "modrm")
3432      (if_then_else (eq_attr "prefix_0f" "0")
3433         (const_string "0")
3434         (const_string "1")))])
3436 (define_insn "extendqisi2"
3437   [(set (match_operand:SI 0 "register_operand" "=r")
3438         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439   ""
3440   "movs{bl|x}\t{%1,%0|%0, %1}"
3441    [(set_attr "type" "imovx")
3442     (set_attr "mode" "SI")])
3444 (define_insn "*extendqisi2_zext"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448   "TARGET_64BIT"
3449   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450    [(set_attr "type" "imovx")
3451     (set_attr "mode" "SI")])
3453 ;; Conversions between float and double.
3455 ;; These are all no-ops in the model used for the 80387.  So just
3456 ;; emit moves.
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3459 (define_insn "*dummy_extendsfdf2"
3460   [(set (match_operand:DF 0 "push_operand" "=<")
3461         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462   "0"
3463   "#")
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "!TARGET_64BIT"
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3472 (define_split
3473   [(set (match_operand:DF 0 "push_operand" "")
3474         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475   "TARGET_64BIT"
3476   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 (define_insn "*dummy_extendsfxf2"
3480   [(set (match_operand:XF 0 "push_operand" "=<")
3481         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482   "0"
3483   "#")
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488   ""
3489   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   "TARGET_64BIT"
3497   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504   ""
3505   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   "TARGET_64BIT"
3513   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_expand "extendsfdf2"
3518   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522   /* ??? Needed for compress_float_constant since all fp constants
3523      are LEGITIMATE_CONSTANT_P.  */
3524   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525     {
3526       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527           && standard_80387_constant_p (operands[1]) > 0)
3528         {
3529           operands[1] = simplify_const_unary_operation
3530             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531           emit_move_insn_1 (operands[0], operands[1]);
3532           DONE;
3533         }
3534       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535     }
3538 (define_insn "*extendsfdf2_mixed"
3539   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3540         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3541   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3543   switch (which_alternative)
3544     {
3545     case 0:
3546       return output_387_reg_move (insn, operands);
3548     case 1:
3549       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3550         return "fstp%z0\t%y0";
3551       else
3552         return "fst%z0\t%y0";
3554     case 2:
3555       return "cvtss2sd\t{%1, %0|%0, %1}";
3557     default:
3558       gcc_unreachable ();
3559     }
3561   [(set_attr "type" "fmov,fmov,ssecvt")
3562    (set_attr "mode" "SF,XF,DF")])
3564 (define_insn "*extendsfdf2_sse"
3565   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3566         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3567   "TARGET_SSE2 && TARGET_SSE_MATH"
3568   "cvtss2sd\t{%1, %0|%0, %1}"
3569   [(set_attr "type" "ssecvt")
3570    (set_attr "mode" "DF")])
3572 (define_insn "*extendsfdf2_i387"
3573   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3574         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3575   "TARGET_80387"
3577   switch (which_alternative)
3578     {
3579     case 0:
3580       return output_387_reg_move (insn, operands);
3582     case 1:
3583       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584         return "fstp%z0\t%y0";
3585       else
3586         return "fst%z0\t%y0";
3588     default:
3589       gcc_unreachable ();
3590     }
3592   [(set_attr "type" "fmov")
3593    (set_attr "mode" "SF,XF")])
3595 (define_expand "extendsfxf2"
3596   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3597         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3598   "TARGET_80387"
3600   /* ??? Needed for compress_float_constant since all fp constants
3601      are LEGITIMATE_CONSTANT_P.  */
3602   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3603     {
3604       if (standard_80387_constant_p (operands[1]) > 0)
3605         {
3606           operands[1] = simplify_const_unary_operation
3607             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3608           emit_move_insn_1 (operands[0], operands[1]);
3609           DONE;
3610         }
3611       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3612     }
3615 (define_insn "*extendsfxf2_i387"
3616   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3618   "TARGET_80387"
3620   switch (which_alternative)
3621     {
3622     case 0:
3623       return output_387_reg_move (insn, operands);
3625     case 1:
3626       /* There is no non-popping store to memory for XFmode.  So if
3627          we need one, follow the store with a load.  */
3628       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629         return "fstp%z0\t%y0";
3630       else
3631         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3633     default:
3634       gcc_unreachable ();
3635     }
3637   [(set_attr "type" "fmov")
3638    (set_attr "mode" "SF,XF")])
3640 (define_expand "extenddfxf2"
3641   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3642         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3643   "TARGET_80387"
3645   /* ??? Needed for compress_float_constant since all fp constants
3646      are LEGITIMATE_CONSTANT_P.  */
3647   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3648     {
3649       if (standard_80387_constant_p (operands[1]) > 0)
3650         {
3651           operands[1] = simplify_const_unary_operation
3652             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3653           emit_move_insn_1 (operands[0], operands[1]);
3654           DONE;
3655         }
3656       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3657     }
3660 (define_insn "*extenddfxf2_i387"
3661   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3662         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3663   "TARGET_80387"
3665   switch (which_alternative)
3666     {
3667     case 0:
3668       return output_387_reg_move (insn, operands);
3670     case 1:
3671       /* There is no non-popping store to memory for XFmode.  So if
3672          we need one, follow the store with a load.  */
3673       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3674         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3675       else
3676         return "fstp%z0\t%y0";
3678     default:
3679       gcc_unreachable ();
3680     }
3682   [(set_attr "type" "fmov")
3683    (set_attr "mode" "DF,XF")])
3685 ;; %%% This seems bad bad news.
3686 ;; This cannot output into an f-reg because there is no way to be sure
3687 ;; of truncating in that case.  Otherwise this is just like a simple move
3688 ;; insn.  So we pretend we can output to a reg in order to get better
3689 ;; register preferencing, but we really use a stack slot.
3691 ;; Conversion from DFmode to SFmode.
3693 (define_expand "truncdfsf2"
3694   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3695         (float_truncate:SF
3696           (match_operand:DF 1 "nonimmediate_operand" "")))]
3697   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3699   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3700     ;
3701   else if (flag_unsafe_math_optimizations)
3702     ;
3703   else
3704     {
3705       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3706       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3707       DONE;
3708     }
3711 (define_expand "truncdfsf2_with_temp"
3712   [(parallel [(set (match_operand:SF 0 "" "")
3713                    (float_truncate:SF (match_operand:DF 1 "" "")))
3714               (clobber (match_operand:SF 2 "" ""))])]
3715   "")
3717 (define_insn "*truncdfsf_fast_mixed"
3718   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3719         (float_truncate:SF
3720           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3721   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3723   switch (which_alternative)
3724     {
3725     case 0:
3726       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3727         return "fstp%z0\t%y0";
3728       else
3729         return "fst%z0\t%y0";
3730     case 1:
3731       return output_387_reg_move (insn, operands);
3732     case 2:
3733       return "cvtsd2ss\t{%1, %0|%0, %1}";
3734     default:
3735       gcc_unreachable ();
3736     }
3738   [(set_attr "type" "fmov,fmov,ssecvt")
3739    (set_attr "mode" "SF")])
3741 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3742 ;; because nothing we do here is unsafe.
3743 (define_insn "*truncdfsf_fast_sse"
3744   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3745         (float_truncate:SF
3746           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3747   "TARGET_SSE2 && TARGET_SSE_MATH"
3748   "cvtsd2ss\t{%1, %0|%0, %1}"
3749   [(set_attr "type" "ssecvt")
3750    (set_attr "mode" "SF")])
3752 (define_insn "*truncdfsf_fast_i387"
3753   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3754         (float_truncate:SF
3755           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3756   "TARGET_80387 && flag_unsafe_math_optimizations"
3757   "* return output_387_reg_move (insn, operands);"
3758   [(set_attr "type" "fmov")
3759    (set_attr "mode" "SF")])
3761 (define_insn "*truncdfsf_mixed"
3762   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3763         (float_truncate:SF
3764           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3765    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3766   "TARGET_MIX_SSE_I387"
3768   switch (which_alternative)
3769     {
3770     case 0:
3771       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3772         return "fstp%z0\t%y0";
3773       else
3774         return "fst%z0\t%y0";
3775     case 1:
3776       return "#";
3777     case 2:
3778       return "cvtsd2ss\t{%1, %0|%0, %1}";
3779     default:
3780       gcc_unreachable ();
3781     }
3783   [(set_attr "type" "fmov,multi,ssecvt")
3784    (set_attr "unit" "*,i387,*")
3785    (set_attr "mode" "SF")])
3787 (define_insn "*truncdfsf_i387"
3788   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3789         (float_truncate:SF
3790           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3791    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3792   "TARGET_80387"
3794   switch (which_alternative)
3795     {
3796     case 0:
3797       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3798         return "fstp%z0\t%y0";
3799       else
3800         return "fst%z0\t%y0";
3801     case 1:
3802       return "#";
3803     default:
3804       gcc_unreachable ();
3805     }
3807   [(set_attr "type" "fmov,multi")
3808    (set_attr "unit" "*,i387")
3809    (set_attr "mode" "SF")])
3811 (define_insn "*truncdfsf2_i387_1"
3812   [(set (match_operand:SF 0 "memory_operand" "=m")
3813         (float_truncate:SF
3814           (match_operand:DF 1 "register_operand" "f")))]
3815   "TARGET_80387
3816    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3817    && !TARGET_MIX_SSE_I387"
3819   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3820     return "fstp%z0\t%y0";
3821   else
3822     return "fst%z0\t%y0";
3824   [(set_attr "type" "fmov")
3825    (set_attr "mode" "SF")])
3827 (define_split
3828   [(set (match_operand:SF 0 "register_operand" "")
3829         (float_truncate:SF
3830          (match_operand:DF 1 "fp_register_operand" "")))
3831    (clobber (match_operand 2 "" ""))]
3832   "reload_completed"
3833   [(set (match_dup 2) (match_dup 1))
3834    (set (match_dup 0) (match_dup 2))]
3836   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3839 ;; Conversion from XFmode to SFmode.
3841 (define_expand "truncxfsf2"
3842   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3843                    (float_truncate:SF
3844                     (match_operand:XF 1 "register_operand" "")))
3845               (clobber (match_dup 2))])]
3846   "TARGET_80387"
3848   if (flag_unsafe_math_optimizations)
3849     {
3850       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3851       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3852       if (reg != operands[0])
3853         emit_move_insn (operands[0], reg);
3854       DONE;
3855     }
3856   else
3857     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3860 (define_insn "*truncxfsf2_mixed"
3861   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3862         (float_truncate:SF
3863          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3864    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3865   "TARGET_MIX_SSE_I387"
3867   gcc_assert (!which_alternative);
3868   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3869     return "fstp%z0\t%y0";
3870   else
3871     return "fst%z0\t%y0";
3873   [(set_attr "type" "fmov,multi,multi,multi")
3874    (set_attr "unit" "*,i387,i387,i387")
3875    (set_attr "mode" "SF")])
3877 (define_insn "truncxfsf2_i387_noop"
3878   [(set (match_operand:SF 0 "register_operand" "=f")
3879         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3880   "TARGET_80387 && flag_unsafe_math_optimizations"
3882   return output_387_reg_move (insn, operands);
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF")])
3887 (define_insn "*truncxfsf2_i387"
3888   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3889         (float_truncate:SF
3890          (match_operand:XF 1 "register_operand" "f,f,f")))
3891    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3892   "TARGET_80387"
3894   gcc_assert (!which_alternative);
3895   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896     return "fstp%z0\t%y0";
3897    else
3898      return "fst%z0\t%y0";
3900   [(set_attr "type" "fmov,multi,multi")
3901    (set_attr "unit" "*,i387,i387")
3902    (set_attr "mode" "SF")])
3904 (define_insn "*truncxfsf2_i387_1"
3905   [(set (match_operand:SF 0 "memory_operand" "=m")
3906         (float_truncate:SF
3907          (match_operand:XF 1 "register_operand" "f")))]
3908   "TARGET_80387"
3910   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911     return "fstp%z0\t%y0";
3912   else
3913     return "fst%z0\t%y0";
3915   [(set_attr "type" "fmov")
3916    (set_attr "mode" "SF")])
3918 (define_split
3919   [(set (match_operand:SF 0 "register_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387 && reload_completed"
3924   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3925    (set (match_dup 0) (match_dup 2))]
3926   "")
3928 (define_split
3929   [(set (match_operand:SF 0 "memory_operand" "")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "")))
3932    (clobber (match_operand:SF 2 "memory_operand" ""))]
3933   "TARGET_80387"
3934   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3935   "")
3937 ;; Conversion from XFmode to DFmode.
3939 (define_expand "truncxfdf2"
3940   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3941                    (float_truncate:DF
3942                     (match_operand:XF 1 "register_operand" "")))
3943               (clobber (match_dup 2))])]
3944   "TARGET_80387"
3946   if (flag_unsafe_math_optimizations)
3947     {
3948       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3949       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3950       if (reg != operands[0])
3951         emit_move_insn (operands[0], reg);
3952       DONE;
3953     }
3954   else
3955     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3958 (define_insn "*truncxfdf2_mixed"
3959   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3960         (float_truncate:DF
3961          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3962    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3963   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3965   gcc_assert (!which_alternative);
3966   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3967     return "fstp%z0\t%y0";
3968   else
3969     return "fst%z0\t%y0";
3971   [(set_attr "type" "fmov,multi,multi,multi")
3972    (set_attr "unit" "*,i387,i387,i387")
3973    (set_attr "mode" "DF")])
3975 (define_insn "truncxfdf2_i387_noop"
3976   [(set (match_operand:DF 0 "register_operand" "=f")
3977         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3978   "TARGET_80387 && flag_unsafe_math_optimizations"
3980   return output_387_reg_move (insn, operands);
3982   [(set_attr "type" "fmov")
3983    (set_attr "mode" "DF")])
3985 (define_insn "*truncxfdf2_i387"
3986   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3987         (float_truncate:DF
3988          (match_operand:XF 1 "register_operand" "f,f,f")))
3989    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3990   "TARGET_80387"
3992   gcc_assert (!which_alternative);
3993   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994     return "fstp%z0\t%y0";
3995   else
3996     return "fst%z0\t%y0";
3998   [(set_attr "type" "fmov,multi,multi")
3999    (set_attr "unit" "*,i387,i387")
4000    (set_attr "mode" "DF")])
4002 (define_insn "*truncxfdf2_i387_1"
4003   [(set (match_operand:DF 0 "memory_operand" "=m")
4004         (float_truncate:DF
4005           (match_operand:XF 1 "register_operand" "f")))]
4006   "TARGET_80387"
4008   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4009     return "fstp%z0\t%y0";
4010   else
4011     return "fst%z0\t%y0";
4013   [(set_attr "type" "fmov")
4014    (set_attr "mode" "DF")])
4016 (define_split
4017   [(set (match_operand:DF 0 "register_operand" "")
4018         (float_truncate:DF
4019          (match_operand:XF 1 "register_operand" "")))
4020    (clobber (match_operand:DF 2 "memory_operand" ""))]
4021   "TARGET_80387 && reload_completed"
4022   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4023    (set (match_dup 0) (match_dup 2))]
4024   "")
4026 (define_split
4027   [(set (match_operand:DF 0 "memory_operand" "")
4028         (float_truncate:DF
4029          (match_operand:XF 1 "register_operand" "")))
4030    (clobber (match_operand:DF 2 "memory_operand" ""))]
4031   "TARGET_80387"
4032   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4033   "")
4035 ;; Signed conversion to DImode.
4037 (define_expand "fix_truncxfdi2"
4038   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4039                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4040               (clobber (reg:CC FLAGS_REG))])]
4041   "TARGET_80387"
4043   if (TARGET_FISTTP)
4044    {
4045      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4046      DONE;
4047    }
4050 (define_expand "fix_trunc<mode>di2"
4051   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4052                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4053               (clobber (reg:CC FLAGS_REG))])]
4054   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4056   if (TARGET_FISTTP
4057       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4058    {
4059      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060      DONE;
4061    }
4062   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4063    {
4064      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4065      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4066      if (out != operands[0])
4067         emit_move_insn (operands[0], out);
4068      DONE;
4069    }
4072 ;; Signed conversion to SImode.
4074 (define_expand "fix_truncxfsi2"
4075   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4076                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4077               (clobber (reg:CC FLAGS_REG))])]
4078   "TARGET_80387"
4080   if (TARGET_FISTTP)
4081    {
4082      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4083      DONE;
4084    }
4087 (define_expand "fix_trunc<mode>si2"
4088   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4089                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4090               (clobber (reg:CC FLAGS_REG))])]
4091   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4093   if (TARGET_FISTTP
4094       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4095    {
4096      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097      DONE;
4098    }
4099   if (SSE_FLOAT_MODE_P (<MODE>mode))
4100    {
4101      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4102      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4103      if (out != operands[0])
4104         emit_move_insn (operands[0], out);
4105      DONE;
4106    }
4109 ;; Signed conversion to HImode.
4111 (define_expand "fix_trunc<mode>hi2"
4112   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4113                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4114               (clobber (reg:CC FLAGS_REG))])]
4115   "TARGET_80387
4116    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4118   if (TARGET_FISTTP)
4119    {
4120      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4121      DONE;
4122    }
4125 ;; When SSE is available, it is always faster to use it!
4126 (define_insn "fix_truncsfdi_sse"
4127   [(set (match_operand:DI 0 "register_operand" "=r,r")
4128         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4130   "cvttss2si{q}\t{%1, %0|%0, %1}"
4131   [(set_attr "type" "sseicvt")
4132    (set_attr "mode" "SF")
4133    (set_attr "athlon_decode" "double,vector")])
4135 (define_insn "fix_truncdfdi_sse"
4136   [(set (match_operand:DI 0 "register_operand" "=r,r")
4137         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4138   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4139   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4140   [(set_attr "type" "sseicvt")
4141    (set_attr "mode" "DF")
4142    (set_attr "athlon_decode" "double,vector")])
4144 (define_insn "fix_truncsfsi_sse"
4145   [(set (match_operand:SI 0 "register_operand" "=r,r")
4146         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4147   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4148   "cvttss2si\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "sseicvt")
4150    (set_attr "mode" "DF")
4151    (set_attr "athlon_decode" "double,vector")])
4153 (define_insn "fix_truncdfsi_sse"
4154   [(set (match_operand:SI 0 "register_operand" "=r,r")
4155         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4156   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4157   "cvttsd2si\t{%1, %0|%0, %1}"
4158   [(set_attr "type" "sseicvt")
4159    (set_attr "mode" "DF")
4160    (set_attr "athlon_decode" "double,vector")])
4162 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4163 (define_peephole2
4164   [(set (match_operand:DF 0 "register_operand" "")
4165         (match_operand:DF 1 "memory_operand" ""))
4166    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4167         (fix:SSEMODEI24 (match_dup 0)))]
4168   "!TARGET_K8
4169    && peep2_reg_dead_p (2, operands[0])"
4170   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4171   "")
4173 (define_peephole2
4174   [(set (match_operand:SF 0 "register_operand" "")
4175         (match_operand:SF 1 "memory_operand" ""))
4176    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4177         (fix:SSEMODEI24 (match_dup 0)))]
4178   "!TARGET_K8
4179    && peep2_reg_dead_p (2, operands[0])"
4180   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4181   "")
4183 ;; Avoid vector decoded forms of the instruction.
4184 (define_peephole2
4185   [(match_scratch:DF 2 "Y")
4186    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4187         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4188   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4189   [(set (match_dup 2) (match_dup 1))
4190    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4191   "")
4193 (define_peephole2
4194   [(match_scratch:SF 2 "x")
4195    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4196         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4197   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4198   [(set (match_dup 2) (match_dup 1))
4199    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4200   "")
4202 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4205   "TARGET_FISTTP
4206    && FLOAT_MODE_P (GET_MODE (operands[1]))
4207    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208          && (TARGET_64BIT || <MODE>mode != DImode))
4209         && TARGET_SSE_MATH)
4210    && !(reload_completed || reload_in_progress)"
4211   "#"
4212   "&& 1"
4213   [(const_int 0)]
4215   if (memory_operand (operands[0], VOIDmode))
4216     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4217   else
4218     {
4219       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4220       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4221                                                             operands[1],
4222                                                             operands[2]));
4223     }
4224   DONE;
4226   [(set_attr "type" "fisttp")
4227    (set_attr "mode" "<MODE>")])
4229 (define_insn "fix_trunc<mode>_i387_fisttp"
4230   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4231         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4232    (clobber (match_scratch:XF 2 "=&1f"))]
4233   "TARGET_FISTTP
4234    && FLOAT_MODE_P (GET_MODE (operands[1]))
4235    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4236          && (TARGET_64BIT || <MODE>mode != DImode))
4237         && TARGET_SSE_MATH)"
4238   "* return output_fix_trunc (insn, operands, 1);"
4239   [(set_attr "type" "fisttp")
4240    (set_attr "mode" "<MODE>")])
4242 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4246    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4247   "TARGET_FISTTP
4248    && FLOAT_MODE_P (GET_MODE (operands[1]))
4249    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4250         && (TARGET_64BIT || <MODE>mode != DImode))
4251         && TARGET_SSE_MATH)"
4252   "#"
4253   [(set_attr "type" "fisttp")
4254    (set_attr "mode" "<MODE>")])
4256 (define_split
4257   [(set (match_operand:X87MODEI 0 "register_operand" "")
4258         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4259    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4260    (clobber (match_scratch 3 ""))]
4261   "reload_completed"
4262   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4263               (clobber (match_dup 3))])
4264    (set (match_dup 0) (match_dup 2))]
4265   "")
4267 (define_split
4268   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4269         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4270    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4271    (clobber (match_scratch 3 ""))]
4272   "reload_completed"
4273   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4274               (clobber (match_dup 3))])]
4275   "")
4277 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4278 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4279 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4280 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4281 ;; function in i386.c.
4282 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4283   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4284         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4285    (clobber (reg:CC FLAGS_REG))]
4286   "TARGET_80387 && !TARGET_FISTTP
4287    && FLOAT_MODE_P (GET_MODE (operands[1]))
4288    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4289          && (TARGET_64BIT || <MODE>mode != DImode))
4290    && !(reload_completed || reload_in_progress)"
4291   "#"
4292   "&& 1"
4293   [(const_int 0)]
4295   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4297   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4298   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4299   if (memory_operand (operands[0], VOIDmode))
4300     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4301                                          operands[2], operands[3]));
4302   else
4303     {
4304       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4305       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4306                                                      operands[2], operands[3],
4307                                                      operands[4]));
4308     }
4309   DONE;
4311   [(set_attr "type" "fistp")
4312    (set_attr "i387_cw" "trunc")
4313    (set_attr "mode" "<MODE>")])
4315 (define_insn "fix_truncdi_i387"
4316   [(set (match_operand:DI 0 "memory_operand" "=m")
4317         (fix:DI (match_operand 1 "register_operand" "f")))
4318    (use (match_operand:HI 2 "memory_operand" "m"))
4319    (use (match_operand:HI 3 "memory_operand" "m"))
4320    (clobber (match_scratch:XF 4 "=&1f"))]
4321   "TARGET_80387 && !TARGET_FISTTP
4322    && FLOAT_MODE_P (GET_MODE (operands[1]))
4323    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4324   "* return output_fix_trunc (insn, operands, 0);"
4325   [(set_attr "type" "fistp")
4326    (set_attr "i387_cw" "trunc")
4327    (set_attr "mode" "DI")])
4329 (define_insn "fix_truncdi_i387_with_temp"
4330   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4331         (fix:DI (match_operand 1 "register_operand" "f,f")))
4332    (use (match_operand:HI 2 "memory_operand" "m,m"))
4333    (use (match_operand:HI 3 "memory_operand" "m,m"))
4334    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4335    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4336   "TARGET_80387 && !TARGET_FISTTP
4337    && FLOAT_MODE_P (GET_MODE (operands[1]))
4338    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4339   "#"
4340   [(set_attr "type" "fistp")
4341    (set_attr "i387_cw" "trunc")
4342    (set_attr "mode" "DI")])
4344 (define_split 
4345   [(set (match_operand:DI 0 "register_operand" "")
4346         (fix:DI (match_operand 1 "register_operand" "")))
4347    (use (match_operand:HI 2 "memory_operand" ""))
4348    (use (match_operand:HI 3 "memory_operand" ""))
4349    (clobber (match_operand:DI 4 "memory_operand" ""))
4350    (clobber (match_scratch 5 ""))]
4351   "reload_completed"
4352   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4353               (use (match_dup 2))
4354               (use (match_dup 3))
4355               (clobber (match_dup 5))])
4356    (set (match_dup 0) (match_dup 4))]
4357   "")
4359 (define_split 
4360   [(set (match_operand:DI 0 "memory_operand" "")
4361         (fix:DI (match_operand 1 "register_operand" "")))
4362    (use (match_operand:HI 2 "memory_operand" ""))
4363    (use (match_operand:HI 3 "memory_operand" ""))
4364    (clobber (match_operand:DI 4 "memory_operand" ""))
4365    (clobber (match_scratch 5 ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))
4370               (clobber (match_dup 5))])]
4371   "")
4373 (define_insn "fix_trunc<mode>_i387"
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4376    (use (match_operand:HI 2 "memory_operand" "m"))
4377    (use (match_operand:HI 3 "memory_operand" "m"))]
4378   "TARGET_80387 && !TARGET_FISTTP
4379    && FLOAT_MODE_P (GET_MODE (operands[1]))
4380    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4381   "* return output_fix_trunc (insn, operands, 0);"
4382   [(set_attr "type" "fistp")
4383    (set_attr "i387_cw" "trunc")
4384    (set_attr "mode" "<MODE>")])
4386 (define_insn "fix_trunc<mode>_i387_with_temp"
4387   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4388         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4389    (use (match_operand:HI 2 "memory_operand" "m,m"))
4390    (use (match_operand:HI 3 "memory_operand" "m,m"))
4391    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4392   "TARGET_80387 && !TARGET_FISTTP
4393    && FLOAT_MODE_P (GET_MODE (operands[1]))
4394    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4395   "#"
4396   [(set_attr "type" "fistp")
4397    (set_attr "i387_cw" "trunc")
4398    (set_attr "mode" "<MODE>")])
4400 (define_split 
4401   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4402         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4403    (use (match_operand:HI 2 "memory_operand" ""))
4404    (use (match_operand:HI 3 "memory_operand" ""))
4405    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4406   "reload_completed"
4407   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4408               (use (match_dup 2))
4409               (use (match_dup 3))])
4410    (set (match_dup 0) (match_dup 4))]
4411   "")
4413 (define_split 
4414   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4415         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4416    (use (match_operand:HI 2 "memory_operand" ""))
4417    (use (match_operand:HI 3 "memory_operand" ""))
4418    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4419   "reload_completed"
4420   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4421               (use (match_dup 2))
4422               (use (match_dup 3))])]
4423   "")
4425 (define_insn "x86_fnstcw_1"
4426   [(set (match_operand:HI 0 "memory_operand" "=m")
4427         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4428   "TARGET_80387"
4429   "fnstcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")])
4434 (define_insn "x86_fldcw_1"
4435   [(set (reg:HI FPSR_REG)
4436         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4437   "TARGET_80387"
4438   "fldcw\t%0"
4439   [(set_attr "length" "2")
4440    (set_attr "mode" "HI")
4441    (set_attr "unit" "i387")
4442    (set_attr "athlon_decode" "vector")])
4444 ;; Conversion between fixed point and floating point.
4446 ;; Even though we only accept memory inputs, the backend _really_
4447 ;; wants to be able to do this between registers.
4449 (define_expand "floathisf2"
4450   [(set (match_operand:SF 0 "register_operand" "")
4451         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4452   "TARGET_80387 || TARGET_SSE_MATH"
4454   if (TARGET_SSE_MATH)
4455     {
4456       emit_insn (gen_floatsisf2 (operands[0],
4457                                  convert_to_mode (SImode, operands[1], 0)));
4458       DONE;
4459     }
4462 (define_insn "*floathisf2_i387"
4463   [(set (match_operand:SF 0 "register_operand" "=f,f")
4464         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4465   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4466   "@
4467    fild%z1\t%1
4468    #"
4469   [(set_attr "type" "fmov,multi")
4470    (set_attr "mode" "SF")
4471    (set_attr "unit" "*,i387")
4472    (set_attr "fp_int_src" "true")])
4474 (define_expand "floatsisf2"
4475   [(set (match_operand:SF 0 "register_operand" "")
4476         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4477   "TARGET_80387 || TARGET_SSE_MATH"
4478   "")
4480 (define_insn "*floatsisf2_mixed"
4481   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4482         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4483   "TARGET_MIX_SSE_I387"
4484   "@
4485    fild%z1\t%1
4486    #
4487    cvtsi2ss\t{%1, %0|%0, %1}
4488    cvtsi2ss\t{%1, %0|%0, %1}"
4489   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4490    (set_attr "mode" "SF")
4491    (set_attr "unit" "*,i387,*,*")
4492    (set_attr "athlon_decode" "*,*,vector,double")
4493    (set_attr "fp_int_src" "true")])
4495 (define_insn "*floatsisf2_sse"
4496   [(set (match_operand:SF 0 "register_operand" "=x,x")
4497         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4498   "TARGET_SSE_MATH"
4499   "cvtsi2ss\t{%1, %0|%0, %1}"
4500   [(set_attr "type" "sseicvt")
4501    (set_attr "mode" "SF")
4502    (set_attr "athlon_decode" "vector,double")
4503    (set_attr "fp_int_src" "true")])
4505 (define_insn "*floatsisf2_i387"
4506   [(set (match_operand:SF 0 "register_operand" "=f,f")
4507         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4508   "TARGET_80387"
4509   "@
4510    fild%z1\t%1
4511    #"
4512   [(set_attr "type" "fmov,multi")
4513    (set_attr "mode" "SF")
4514    (set_attr "unit" "*,i387")
4515    (set_attr "fp_int_src" "true")])
4517 (define_expand "floatdisf2"
4518   [(set (match_operand:SF 0 "register_operand" "")
4519         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4520   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4521   "")
4523 (define_insn "*floatdisf2_mixed"
4524   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4525         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4526   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4527   "@
4528    fild%z1\t%1
4529    #
4530    cvtsi2ss{q}\t{%1, %0|%0, %1}
4531    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4532   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4533    (set_attr "mode" "SF")
4534    (set_attr "unit" "*,i387,*,*")
4535    (set_attr "athlon_decode" "*,*,vector,double")
4536    (set_attr "fp_int_src" "true")])
4538 (define_insn "*floatdisf2_sse"
4539   [(set (match_operand:SF 0 "register_operand" "=x,x")
4540         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4541   "TARGET_64BIT && TARGET_SSE_MATH"
4542   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4543   [(set_attr "type" "sseicvt")
4544    (set_attr "mode" "SF")
4545    (set_attr "athlon_decode" "vector,double")
4546    (set_attr "fp_int_src" "true")])
4548 (define_insn "*floatdisf2_i387"
4549   [(set (match_operand:SF 0 "register_operand" "=f,f")
4550         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4551   "TARGET_80387"
4552   "@
4553    fild%z1\t%1
4554    #"
4555   [(set_attr "type" "fmov,multi")
4556    (set_attr "mode" "SF")
4557    (set_attr "unit" "*,i387")
4558    (set_attr "fp_int_src" "true")])
4560 (define_expand "floathidf2"
4561   [(set (match_operand:DF 0 "register_operand" "")
4562         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4563   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4565   if (TARGET_SSE2 && TARGET_SSE_MATH)
4566     {
4567       emit_insn (gen_floatsidf2 (operands[0],
4568                                  convert_to_mode (SImode, operands[1], 0)));
4569       DONE;
4570     }
4573 (define_insn "*floathidf2_i387"
4574   [(set (match_operand:DF 0 "register_operand" "=f,f")
4575         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4576   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4577   "@
4578    fild%z1\t%1
4579    #"
4580   [(set_attr "type" "fmov,multi")
4581    (set_attr "mode" "DF")
4582    (set_attr "unit" "*,i387")
4583    (set_attr "fp_int_src" "true")])
4585 (define_expand "floatsidf2"
4586   [(set (match_operand:DF 0 "register_operand" "")
4587         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4588   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4589   "")
4591 (define_insn "*floatsidf2_mixed"
4592   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4593         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4594   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4595   "@
4596    fild%z1\t%1
4597    #
4598    cvtsi2sd\t{%1, %0|%0, %1}
4599    cvtsi2sd\t{%1, %0|%0, %1}"
4600   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4601    (set_attr "mode" "DF")
4602    (set_attr "unit" "*,i387,*,*")
4603    (set_attr "athlon_decode" "*,*,double,direct")
4604    (set_attr "fp_int_src" "true")])
4606 (define_insn "*floatsidf2_sse"
4607   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4608         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4609   "TARGET_SSE2 && TARGET_SSE_MATH"
4610   "cvtsi2sd\t{%1, %0|%0, %1}"
4611   [(set_attr "type" "sseicvt")
4612    (set_attr "mode" "DF")
4613    (set_attr "athlon_decode" "double,direct")
4614    (set_attr "fp_int_src" "true")])
4616 (define_insn "*floatsidf2_i387"
4617   [(set (match_operand:DF 0 "register_operand" "=f,f")
4618         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4619   "TARGET_80387"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "DF")
4625    (set_attr "unit" "*,i387")
4626    (set_attr "fp_int_src" "true")])
4628 (define_expand "floatdidf2"
4629   [(set (match_operand:DF 0 "register_operand" "")
4630         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4631   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4632   "")
4634 (define_insn "*floatdidf2_mixed"
4635   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4636         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4637   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4638   "@
4639    fild%z1\t%1
4640    #
4641    cvtsi2sd{q}\t{%1, %0|%0, %1}
4642    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4643   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4644    (set_attr "mode" "DF")
4645    (set_attr "unit" "*,i387,*,*")
4646    (set_attr "athlon_decode" "*,*,double,direct")
4647    (set_attr "fp_int_src" "true")])
4649 (define_insn "*floatdidf2_sse"
4650   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4651         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4652   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4653   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4654   [(set_attr "type" "sseicvt")
4655    (set_attr "mode" "DF")
4656    (set_attr "athlon_decode" "double,direct")
4657    (set_attr "fp_int_src" "true")])
4659 (define_insn "*floatdidf2_i387"
4660   [(set (match_operand:DF 0 "register_operand" "=f,f")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662   "TARGET_80387"
4663   "@
4664    fild%z1\t%1
4665    #"
4666   [(set_attr "type" "fmov,multi")
4667    (set_attr "mode" "DF")
4668    (set_attr "unit" "*,i387")
4669    (set_attr "fp_int_src" "true")])
4671 (define_insn "floathixf2"
4672   [(set (match_operand:XF 0 "register_operand" "=f,f")
4673         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4674   "TARGET_80387"
4675   "@
4676    fild%z1\t%1
4677    #"
4678   [(set_attr "type" "fmov,multi")
4679    (set_attr "mode" "XF")
4680    (set_attr "unit" "*,i387")
4681    (set_attr "fp_int_src" "true")])
4683 (define_insn "floatsixf2"
4684   [(set (match_operand:XF 0 "register_operand" "=f,f")
4685         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4686   "TARGET_80387"
4687   "@
4688    fild%z1\t%1
4689    #"
4690   [(set_attr "type" "fmov,multi")
4691    (set_attr "mode" "XF")
4692    (set_attr "unit" "*,i387")
4693    (set_attr "fp_int_src" "true")])
4695 (define_insn "floatdixf2"
4696   [(set (match_operand:XF 0 "register_operand" "=f,f")
4697         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4698   "TARGET_80387"
4699   "@
4700    fild%z1\t%1
4701    #"
4702   [(set_attr "type" "fmov,multi")
4703    (set_attr "mode" "XF")
4704    (set_attr "unit" "*,i387")
4705    (set_attr "fp_int_src" "true")])
4707 ;; %%% Kill these when reload knows how to do it.
4708 (define_split
4709   [(set (match_operand 0 "fp_register_operand" "")
4710         (float (match_operand 1 "register_operand" "")))]
4711   "reload_completed
4712    && TARGET_80387
4713    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4714   [(const_int 0)]
4716   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4717   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4718   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4719   ix86_free_from_memory (GET_MODE (operands[1]));
4720   DONE;
4723 (define_expand "floatunssisf2"
4724   [(use (match_operand:SF 0 "register_operand" ""))
4725    (use (match_operand:SI 1 "register_operand" ""))]
4726   "!TARGET_64BIT && TARGET_SSE_MATH"
4727   "x86_emit_floatuns (operands); DONE;")
4729 (define_expand "floatunsdisf2"
4730   [(use (match_operand:SF 0 "register_operand" ""))
4731    (use (match_operand:DI 1 "register_operand" ""))]
4732   "TARGET_64BIT && TARGET_SSE_MATH"
4733   "x86_emit_floatuns (operands); DONE;")
4735 (define_expand "floatunsdidf2"
4736   [(use (match_operand:DF 0 "register_operand" ""))
4737    (use (match_operand:DI 1 "register_operand" ""))]
4738   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4739   "x86_emit_floatuns (operands); DONE;")
4741 ;; SSE extract/set expanders
4744 ;; Add instructions
4746 ;; %%% splits for addditi3
4748 (define_expand "addti3"
4749   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4750         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4751                  (match_operand:TI 2 "x86_64_general_operand" "")))
4752    (clobber (reg:CC FLAGS_REG))]
4753   "TARGET_64BIT"
4754   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4756 (define_insn "*addti3_1"
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4759                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4762   "#")
4764 (define_split
4765   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4766         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4767                  (match_operand:TI 2 "general_operand" "")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "TARGET_64BIT && reload_completed"
4770   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771                                           UNSPEC_ADD_CARRY))
4772               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4773    (parallel [(set (match_dup 3)
4774                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4775                                      (match_dup 4))
4776                             (match_dup 5)))
4777               (clobber (reg:CC FLAGS_REG))])]
4778   "split_ti (operands+0, 1, operands+0, operands+3);
4779    split_ti (operands+1, 1, operands+1, operands+4);
4780    split_ti (operands+2, 1, operands+2, operands+5);")
4782 ;; %%% splits for addsidi3
4783 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4784 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4785 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4787 (define_expand "adddi3"
4788   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4789         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4790                  (match_operand:DI 2 "x86_64_general_operand" "")))
4791    (clobber (reg:CC FLAGS_REG))]
4792   ""
4793   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4795 (define_insn "*adddi3_1"
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4798                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "#")
4803 (define_split
4804   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4805         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4806                  (match_operand:DI 2 "general_operand" "")))
4807    (clobber (reg:CC FLAGS_REG))]
4808   "!TARGET_64BIT && reload_completed"
4809   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4810                                           UNSPEC_ADD_CARRY))
4811               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4812    (parallel [(set (match_dup 3)
4813                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4814                                      (match_dup 4))
4815                             (match_dup 5)))
4816               (clobber (reg:CC FLAGS_REG))])]
4817   "split_di (operands+0, 1, operands+0, operands+3);
4818    split_di (operands+1, 1, operands+1, operands+4);
4819    split_di (operands+2, 1, operands+2, operands+5);")
4821 (define_insn "adddi3_carry_rex64"
4822   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4823           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4824                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4825                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4826    (clobber (reg:CC FLAGS_REG))]
4827   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4828   "adc{q}\t{%2, %0|%0, %2}"
4829   [(set_attr "type" "alu")
4830    (set_attr "pent_pair" "pu")
4831    (set_attr "mode" "DI")])
4833 (define_insn "*adddi3_cc_rex64"
4834   [(set (reg:CC FLAGS_REG)
4835         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4836                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4837                    UNSPEC_ADD_CARRY))
4838    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4839         (plus:DI (match_dup 1) (match_dup 2)))]
4840   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4841   "add{q}\t{%2, %0|%0, %2}"
4842   [(set_attr "type" "alu")
4843    (set_attr "mode" "DI")])
4845 (define_insn "addqi3_carry"
4846   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4847           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4848                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4849                    (match_operand:QI 2 "general_operand" "qi,qm")))
4850    (clobber (reg:CC FLAGS_REG))]
4851   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4852   "adc{b}\t{%2, %0|%0, %2}"
4853   [(set_attr "type" "alu")
4854    (set_attr "pent_pair" "pu")
4855    (set_attr "mode" "QI")])
4857 (define_insn "addhi3_carry"
4858   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4859           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4860                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4861                    (match_operand:HI 2 "general_operand" "ri,rm")))
4862    (clobber (reg:CC FLAGS_REG))]
4863   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4864   "adc{w}\t{%2, %0|%0, %2}"
4865   [(set_attr "type" "alu")
4866    (set_attr "pent_pair" "pu")
4867    (set_attr "mode" "HI")])
4869 (define_insn "addsi3_carry"
4870   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:SI 2 "general_operand" "ri,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4876   "adc{l}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "SI")])
4881 (define_insn "*addsi3_carry_zext"
4882   [(set (match_operand:DI 0 "register_operand" "=r")
4883           (zero_extend:DI 
4884             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4885                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4886                      (match_operand:SI 2 "general_operand" "rim"))))
4887    (clobber (reg:CC FLAGS_REG))]
4888   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4889   "adc{l}\t{%2, %k0|%k0, %2}"
4890   [(set_attr "type" "alu")
4891    (set_attr "pent_pair" "pu")
4892    (set_attr "mode" "SI")])
4894 (define_insn "*addsi3_cc"
4895   [(set (reg:CC FLAGS_REG)
4896         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4897                     (match_operand:SI 2 "general_operand" "ri,rm")]
4898                    UNSPEC_ADD_CARRY))
4899    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4900         (plus:SI (match_dup 1) (match_dup 2)))]
4901   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4902   "add{l}\t{%2, %0|%0, %2}"
4903   [(set_attr "type" "alu")
4904    (set_attr "mode" "SI")])
4906 (define_insn "addqi3_cc"
4907   [(set (reg:CC FLAGS_REG)
4908         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4909                     (match_operand:QI 2 "general_operand" "qi,qm")]
4910                    UNSPEC_ADD_CARRY))
4911    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4912         (plus:QI (match_dup 1) (match_dup 2)))]
4913   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4914   "add{b}\t{%2, %0|%0, %2}"
4915   [(set_attr "type" "alu")
4916    (set_attr "mode" "QI")])
4918 (define_expand "addsi3"
4919   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4920                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4921                             (match_operand:SI 2 "general_operand" "")))
4922               (clobber (reg:CC FLAGS_REG))])]
4923   ""
4924   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4926 (define_insn "*lea_1"
4927   [(set (match_operand:SI 0 "register_operand" "=r")
4928         (match_operand:SI 1 "no_seg_address_operand" "p"))]
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_rex64"
4935   [(set (match_operand:SI 0 "register_operand" "=r")
4936         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4937   "TARGET_64BIT"
4938   "lea{l}\t{%a1, %0|%0, %a1}"
4939   [(set_attr "type" "lea")
4940    (set_attr "mode" "SI")])
4942 (define_insn "*lea_1_zext"
4943   [(set (match_operand:DI 0 "register_operand" "=r")
4944         (zero_extend:DI
4945          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4946   "TARGET_64BIT"
4947   "lea{l}\t{%a1, %k0|%k0, %a1}"
4948   [(set_attr "type" "lea")
4949    (set_attr "mode" "SI")])
4951 (define_insn "*lea_2_rex64"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4954   "TARGET_64BIT"
4955   "lea{q}\t{%a1, %0|%0, %a1}"
4956   [(set_attr "type" "lea")
4957    (set_attr "mode" "DI")])
4959 ;; The lea patterns for non-Pmodes needs to be matched by several
4960 ;; insns converted to real lea by splitters.
4962 (define_insn_and_split "*lea_general_1"
4963   [(set (match_operand 0 "register_operand" "=r")
4964         (plus (plus (match_operand 1 "index_register_operand" "l")
4965                     (match_operand 2 "register_operand" "r"))
4966               (match_operand 3 "immediate_operand" "i")))]
4967   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4968     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4969    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4970    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4971    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4972    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4973        || GET_MODE (operands[3]) == VOIDmode)"
4974   "#"
4975   "&& reload_completed"
4976   [(const_int 0)]
4978   rtx pat;
4979   operands[0] = gen_lowpart (SImode, operands[0]);
4980   operands[1] = gen_lowpart (Pmode, operands[1]);
4981   operands[2] = gen_lowpart (Pmode, operands[2]);
4982   operands[3] = gen_lowpart (Pmode, operands[3]);
4983   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4984                       operands[3]);
4985   if (Pmode != SImode)
4986     pat = gen_rtx_SUBREG (SImode, pat, 0);
4987   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4988   DONE;
4990   [(set_attr "type" "lea")
4991    (set_attr "mode" "SI")])
4993 (define_insn_and_split "*lea_general_1_zext"
4994   [(set (match_operand:DI 0 "register_operand" "=r")
4995         (zero_extend:DI
4996           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4997                             (match_operand:SI 2 "register_operand" "r"))
4998                    (match_operand:SI 3 "immediate_operand" "i"))))]
4999   "TARGET_64BIT"
5000   "#"
5001   "&& reload_completed"
5002   [(set (match_dup 0)
5003         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5004                                                      (match_dup 2))
5005                                             (match_dup 3)) 0)))]
5007   operands[1] = gen_lowpart (Pmode, operands[1]);
5008   operands[2] = gen_lowpart (Pmode, operands[2]);
5009   operands[3] = gen_lowpart (Pmode, operands[3]);
5011   [(set_attr "type" "lea")
5012    (set_attr "mode" "SI")])
5014 (define_insn_and_split "*lea_general_2"
5015   [(set (match_operand 0 "register_operand" "=r")
5016         (plus (mult (match_operand 1 "index_register_operand" "l")
5017                     (match_operand 2 "const248_operand" "i"))
5018               (match_operand 3 "nonmemory_operand" "ri")))]
5019   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5020     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5021    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5022    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5023    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5024        || GET_MODE (operands[3]) == VOIDmode)"
5025   "#"
5026   "&& reload_completed"
5027   [(const_int 0)]
5029   rtx pat;
5030   operands[0] = gen_lowpart (SImode, operands[0]);
5031   operands[1] = gen_lowpart (Pmode, operands[1]);
5032   operands[3] = gen_lowpart (Pmode, operands[3]);
5033   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5034                       operands[3]);
5035   if (Pmode != SImode)
5036     pat = gen_rtx_SUBREG (SImode, pat, 0);
5037   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5038   DONE;
5040   [(set_attr "type" "lea")
5041    (set_attr "mode" "SI")])
5043 (define_insn_and_split "*lea_general_2_zext"
5044   [(set (match_operand:DI 0 "register_operand" "=r")
5045         (zero_extend:DI
5046           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5047                             (match_operand:SI 2 "const248_operand" "n"))
5048                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5049   "TARGET_64BIT"
5050   "#"
5051   "&& reload_completed"
5052   [(set (match_dup 0)
5053         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5054                                                      (match_dup 2))
5055                                             (match_dup 3)) 0)))]
5057   operands[1] = gen_lowpart (Pmode, operands[1]);
5058   operands[3] = gen_lowpart (Pmode, operands[3]);
5060   [(set_attr "type" "lea")
5061    (set_attr "mode" "SI")])
5063 (define_insn_and_split "*lea_general_3"
5064   [(set (match_operand 0 "register_operand" "=r")
5065         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5066                           (match_operand 2 "const248_operand" "i"))
5067                     (match_operand 3 "register_operand" "r"))
5068               (match_operand 4 "immediate_operand" "i")))]
5069   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5070     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5071    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5072    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5073    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5074   "#"
5075   "&& reload_completed"
5076   [(const_int 0)]
5078   rtx pat;
5079   operands[0] = gen_lowpart (SImode, operands[0]);
5080   operands[1] = gen_lowpart (Pmode, operands[1]);
5081   operands[3] = gen_lowpart (Pmode, operands[3]);
5082   operands[4] = gen_lowpart (Pmode, operands[4]);
5083   pat = gen_rtx_PLUS (Pmode,
5084                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5085                                                          operands[2]),
5086                                     operands[3]),
5087                       operands[4]);
5088   if (Pmode != SImode)
5089     pat = gen_rtx_SUBREG (SImode, pat, 0);
5090   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5091   DONE;
5093   [(set_attr "type" "lea")
5094    (set_attr "mode" "SI")])
5096 (define_insn_and_split "*lea_general_3_zext"
5097   [(set (match_operand:DI 0 "register_operand" "=r")
5098         (zero_extend:DI
5099           (plus:SI (plus:SI (mult:SI
5100                               (match_operand:SI 1 "index_register_operand" "l")
5101                               (match_operand:SI 2 "const248_operand" "n"))
5102                             (match_operand:SI 3 "register_operand" "r"))
5103                    (match_operand:SI 4 "immediate_operand" "i"))))]
5104   "TARGET_64BIT"
5105   "#"
5106   "&& reload_completed"
5107   [(set (match_dup 0)
5108         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5109                                                               (match_dup 2))
5110                                                      (match_dup 3))
5111                                             (match_dup 4)) 0)))]
5113   operands[1] = gen_lowpart (Pmode, operands[1]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5115   operands[4] = gen_lowpart (Pmode, operands[4]);
5117   [(set_attr "type" "lea")
5118    (set_attr "mode" "SI")])
5120 (define_insn "*adddi_1_rex64"
5121   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5122         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5123                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5124    (clobber (reg:CC FLAGS_REG))]
5125   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5127   switch (get_attr_type (insn))
5128     {
5129     case TYPE_LEA:
5130       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5131       return "lea{q}\t{%a2, %0|%0, %a2}";
5133     case TYPE_INCDEC:
5134       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5135       if (operands[2] == const1_rtx)
5136         return "inc{q}\t%0";
5137       else
5138         {
5139           gcc_assert (operands[2] == constm1_rtx);
5140           return "dec{q}\t%0";
5141         }
5143     default:
5144       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5146       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5147          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5148       if (GET_CODE (operands[2]) == CONST_INT
5149           /* Avoid overflows.  */
5150           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5151           && (INTVAL (operands[2]) == 128
5152               || (INTVAL (operands[2]) < 0
5153                   && INTVAL (operands[2]) != -128)))
5154         {
5155           operands[2] = GEN_INT (-INTVAL (operands[2]));
5156           return "sub{q}\t{%2, %0|%0, %2}";
5157         }
5158       return "add{q}\t{%2, %0|%0, %2}";
5159     }
5161   [(set (attr "type")
5162      (cond [(eq_attr "alternative" "2")
5163               (const_string "lea")
5164             ; Current assemblers are broken and do not allow @GOTOFF in
5165             ; ought but a memory context.
5166             (match_operand:DI 2 "pic_symbolic_operand" "")
5167               (const_string "lea")
5168             (match_operand:DI 2 "incdec_operand" "")
5169               (const_string "incdec")
5170            ]
5171            (const_string "alu")))
5172    (set_attr "mode" "DI")])
5174 ;; Convert lea to the lea pattern to avoid flags dependency.
5175 (define_split
5176   [(set (match_operand:DI 0 "register_operand" "")
5177         (plus:DI (match_operand:DI 1 "register_operand" "")
5178                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5179    (clobber (reg:CC FLAGS_REG))]
5180   "TARGET_64BIT && reload_completed
5181    && true_regnum (operands[0]) != true_regnum (operands[1])"
5182   [(set (match_dup 0)
5183         (plus:DI (match_dup 1)
5184                  (match_dup 2)))]
5185   "")
5187 (define_insn "*adddi_2_rex64"
5188   [(set (reg FLAGS_REG)
5189         (compare
5190           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5191                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5192           (const_int 0)))                       
5193    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5194         (plus:DI (match_dup 1) (match_dup 2)))]
5195   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5196    && ix86_binary_operator_ok (PLUS, DImode, operands)
5197    /* Current assemblers are broken and do not allow @GOTOFF in
5198       ought but a memory context.  */
5199    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5201   switch (get_attr_type (insn))
5202     {
5203     case TYPE_INCDEC:
5204       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5205       if (operands[2] == const1_rtx)
5206         return "inc{q}\t%0";
5207       else
5208         {
5209           gcc_assert (operands[2] == constm1_rtx);
5210           return "dec{q}\t%0";
5211         }
5213     default:
5214       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5215       /* ???? We ought to handle there the 32bit case too
5216          - do we need new constraint?  */
5217       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5218          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5219       if (GET_CODE (operands[2]) == CONST_INT
5220           /* Avoid overflows.  */
5221           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5222           && (INTVAL (operands[2]) == 128
5223               || (INTVAL (operands[2]) < 0
5224                   && INTVAL (operands[2]) != -128)))
5225         {
5226           operands[2] = GEN_INT (-INTVAL (operands[2]));
5227           return "sub{q}\t{%2, %0|%0, %2}";
5228         }
5229       return "add{q}\t{%2, %0|%0, %2}";
5230     }
5232   [(set (attr "type")
5233      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5234         (const_string "incdec")
5235         (const_string "alu")))
5236    (set_attr "mode" "DI")])
5238 (define_insn "*adddi_3_rex64"
5239   [(set (reg FLAGS_REG)
5240         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5241                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5242    (clobber (match_scratch:DI 0 "=r"))]
5243   "TARGET_64BIT
5244    && ix86_match_ccmode (insn, CCZmode)
5245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5246    /* Current assemblers are broken and do not allow @GOTOFF in
5247       ought but a memory context.  */
5248    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5250   switch (get_attr_type (insn))
5251     {
5252     case TYPE_INCDEC:
5253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5254       if (operands[2] == const1_rtx)
5255         return "inc{q}\t%0";
5256       else
5257         {
5258           gcc_assert (operands[2] == constm1_rtx);
5259           return "dec{q}\t%0";
5260         }
5262     default:
5263       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5264       /* ???? We ought to handle there the 32bit case too
5265          - do we need new constraint?  */
5266       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5267          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5268       if (GET_CODE (operands[2]) == CONST_INT
5269           /* Avoid overflows.  */
5270           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5271           && (INTVAL (operands[2]) == 128
5272               || (INTVAL (operands[2]) < 0
5273                   && INTVAL (operands[2]) != -128)))
5274         {
5275           operands[2] = GEN_INT (-INTVAL (operands[2]));
5276           return "sub{q}\t{%2, %0|%0, %2}";
5277         }
5278       return "add{q}\t{%2, %0|%0, %2}";
5279     }
5281   [(set (attr "type")
5282      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5283         (const_string "incdec")
5284         (const_string "alu")))
5285    (set_attr "mode" "DI")])
5287 ; For comparisons against 1, -1 and 128, we may generate better code
5288 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5289 ; is matched then.  We can't accept general immediate, because for
5290 ; case of overflows,  the result is messed up.
5291 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5292 ; when negated.
5293 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5294 ; only for comparisons not depending on it.
5295 (define_insn "*adddi_4_rex64"
5296   [(set (reg FLAGS_REG)
5297         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5298                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5299    (clobber (match_scratch:DI 0 "=rm"))]
5300   "TARGET_64BIT
5301    &&  ix86_match_ccmode (insn, CCGCmode)"
5303   switch (get_attr_type (insn))
5304     {
5305     case TYPE_INCDEC:
5306       if (operands[2] == constm1_rtx)
5307         return "inc{q}\t%0";
5308       else
5309         {
5310           gcc_assert (operands[2] == const1_rtx);
5311           return "dec{q}\t%0";
5312         }
5314     default:
5315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5317          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5318       if ((INTVAL (operands[2]) == -128
5319            || (INTVAL (operands[2]) > 0
5320                && INTVAL (operands[2]) != 128))
5321           /* Avoid overflows.  */
5322           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5323         return "sub{q}\t{%2, %0|%0, %2}";
5324       operands[2] = GEN_INT (-INTVAL (operands[2]));
5325       return "add{q}\t{%2, %0|%0, %2}";
5326     }
5328   [(set (attr "type")
5329      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5330         (const_string "incdec")
5331         (const_string "alu")))
5332    (set_attr "mode" "DI")])
5334 (define_insn "*adddi_5_rex64"
5335   [(set (reg FLAGS_REG)
5336         (compare
5337           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5338                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5339           (const_int 0)))                       
5340    (clobber (match_scratch:DI 0 "=r"))]
5341   "TARGET_64BIT
5342    && ix86_match_ccmode (insn, CCGOCmode)
5343    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5344    /* Current assemblers are broken and do not allow @GOTOFF in
5345       ought but a memory context.  */
5346    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5348   switch (get_attr_type (insn))
5349     {
5350     case TYPE_INCDEC:
5351       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5352       if (operands[2] == const1_rtx)
5353         return "inc{q}\t%0";
5354       else
5355         {
5356           gcc_assert (operands[2] == constm1_rtx);
5357           return "dec{q}\t%0";
5358         }
5360     default:
5361       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5362       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5363          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5364       if (GET_CODE (operands[2]) == CONST_INT
5365           /* Avoid overflows.  */
5366           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5367           && (INTVAL (operands[2]) == 128
5368               || (INTVAL (operands[2]) < 0
5369                   && INTVAL (operands[2]) != -128)))
5370         {
5371           operands[2] = GEN_INT (-INTVAL (operands[2]));
5372           return "sub{q}\t{%2, %0|%0, %2}";
5373         }
5374       return "add{q}\t{%2, %0|%0, %2}";
5375     }
5377   [(set (attr "type")
5378      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5379         (const_string "incdec")
5380         (const_string "alu")))
5381    (set_attr "mode" "DI")])
5384 (define_insn "*addsi_1"
5385   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5386         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5387                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5388    (clobber (reg:CC FLAGS_REG))]
5389   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5391   switch (get_attr_type (insn))
5392     {
5393     case TYPE_LEA:
5394       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5395       return "lea{l}\t{%a2, %0|%0, %a2}";
5397     case TYPE_INCDEC:
5398       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399       if (operands[2] == const1_rtx)
5400         return "inc{l}\t%0";
5401       else
5402         {
5403           gcc_assert (operands[2] == constm1_rtx);
5404           return "dec{l}\t%0";
5405         }
5407     default:
5408       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (GET_CODE (operands[2]) == CONST_INT
5413           && (INTVAL (operands[2]) == 128
5414               || (INTVAL (operands[2]) < 0
5415                   && INTVAL (operands[2]) != -128)))
5416         {
5417           operands[2] = GEN_INT (-INTVAL (operands[2]));
5418           return "sub{l}\t{%2, %0|%0, %2}";
5419         }
5420       return "add{l}\t{%2, %0|%0, %2}";
5421     }
5423   [(set (attr "type")
5424      (cond [(eq_attr "alternative" "2")
5425               (const_string "lea")
5426             ; Current assemblers are broken and do not allow @GOTOFF in
5427             ; ought but a memory context.
5428             (match_operand:SI 2 "pic_symbolic_operand" "")
5429               (const_string "lea")
5430             (match_operand:SI 2 "incdec_operand" "")
5431               (const_string "incdec")
5432            ]
5433            (const_string "alu")))
5434    (set_attr "mode" "SI")])
5436 ;; Convert lea to the lea pattern to avoid flags dependency.
5437 (define_split
5438   [(set (match_operand 0 "register_operand" "")
5439         (plus (match_operand 1 "register_operand" "")
5440               (match_operand 2 "nonmemory_operand" "")))
5441    (clobber (reg:CC FLAGS_REG))]
5442   "reload_completed
5443    && true_regnum (operands[0]) != true_regnum (operands[1])"
5444   [(const_int 0)]
5446   rtx pat;
5447   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5448      may confuse gen_lowpart.  */
5449   if (GET_MODE (operands[0]) != Pmode)
5450     {
5451       operands[1] = gen_lowpart (Pmode, operands[1]);
5452       operands[2] = gen_lowpart (Pmode, operands[2]);
5453     }
5454   operands[0] = gen_lowpart (SImode, operands[0]);
5455   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5456   if (Pmode != SImode)
5457     pat = gen_rtx_SUBREG (SImode, pat, 0);
5458   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5459   DONE;
5462 ;; It may seem that nonimmediate operand is proper one for operand 1.
5463 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5464 ;; we take care in ix86_binary_operator_ok to not allow two memory
5465 ;; operands so proper swapping will be done in reload.  This allow
5466 ;; patterns constructed from addsi_1 to match.
5467 (define_insn "addsi_1_zext"
5468   [(set (match_operand:DI 0 "register_operand" "=r,r")
5469         (zero_extend:DI
5470           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5471                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5472    (clobber (reg:CC FLAGS_REG))]
5473   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5475   switch (get_attr_type (insn))
5476     {
5477     case TYPE_LEA:
5478       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5479       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5481     case TYPE_INCDEC:
5482       if (operands[2] == const1_rtx)
5483         return "inc{l}\t%k0";
5484       else
5485         {
5486           gcc_assert (operands[2] == constm1_rtx);
5487           return "dec{l}\t%k0";
5488         }
5490     default:
5491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5492          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5493       if (GET_CODE (operands[2]) == CONST_INT
5494           && (INTVAL (operands[2]) == 128
5495               || (INTVAL (operands[2]) < 0
5496                   && INTVAL (operands[2]) != -128)))
5497         {
5498           operands[2] = GEN_INT (-INTVAL (operands[2]));
5499           return "sub{l}\t{%2, %k0|%k0, %2}";
5500         }
5501       return "add{l}\t{%2, %k0|%k0, %2}";
5502     }
5504   [(set (attr "type")
5505      (cond [(eq_attr "alternative" "1")
5506               (const_string "lea")
5507             ; Current assemblers are broken and do not allow @GOTOFF in
5508             ; ought but a memory context.
5509             (match_operand:SI 2 "pic_symbolic_operand" "")
5510               (const_string "lea")
5511             (match_operand:SI 2 "incdec_operand" "")
5512               (const_string "incdec")
5513            ]
5514            (const_string "alu")))
5515    (set_attr "mode" "SI")])
5517 ;; Convert lea to the lea pattern to avoid flags dependency.
5518 (define_split
5519   [(set (match_operand:DI 0 "register_operand" "")
5520         (zero_extend:DI
5521           (plus:SI (match_operand:SI 1 "register_operand" "")
5522                    (match_operand:SI 2 "nonmemory_operand" ""))))
5523    (clobber (reg:CC FLAGS_REG))]
5524   "TARGET_64BIT && reload_completed
5525    && true_regnum (operands[0]) != true_regnum (operands[1])"
5526   [(set (match_dup 0)
5527         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5529   operands[1] = gen_lowpart (Pmode, operands[1]);
5530   operands[2] = gen_lowpart (Pmode, operands[2]);
5533 (define_insn "*addsi_2"
5534   [(set (reg FLAGS_REG)
5535         (compare
5536           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5537                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5538           (const_int 0)))                       
5539    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5540         (plus:SI (match_dup 1) (match_dup 2)))]
5541   "ix86_match_ccmode (insn, CCGOCmode)
5542    && ix86_binary_operator_ok (PLUS, SImode, operands)
5543    /* Current assemblers are broken and do not allow @GOTOFF in
5544       ought but a memory context.  */
5545    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5547   switch (get_attr_type (insn))
5548     {
5549     case TYPE_INCDEC:
5550       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5551       if (operands[2] == const1_rtx)
5552         return "inc{l}\t%0";
5553       else
5554         {
5555           gcc_assert (operands[2] == constm1_rtx);
5556           return "dec{l}\t%0";
5557         }
5559     default:
5560       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5561       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5562          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5563       if (GET_CODE (operands[2]) == CONST_INT
5564           && (INTVAL (operands[2]) == 128
5565               || (INTVAL (operands[2]) < 0
5566                   && INTVAL (operands[2]) != -128)))
5567         {
5568           operands[2] = GEN_INT (-INTVAL (operands[2]));
5569           return "sub{l}\t{%2, %0|%0, %2}";
5570         }
5571       return "add{l}\t{%2, %0|%0, %2}";
5572     }
5574   [(set (attr "type")
5575      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5576         (const_string "incdec")
5577         (const_string "alu")))
5578    (set_attr "mode" "SI")])
5580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5581 (define_insn "*addsi_2_zext"
5582   [(set (reg FLAGS_REG)
5583         (compare
5584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5585                    (match_operand:SI 2 "general_operand" "rmni"))
5586           (const_int 0)))                       
5587    (set (match_operand:DI 0 "register_operand" "=r")
5588         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5589   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5590    && ix86_binary_operator_ok (PLUS, SImode, operands)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       if (operands[2] == const1_rtx)
5599         return "inc{l}\t%k0";
5600       else
5601         {
5602           gcc_assert (operands[2] == constm1_rtx);
5603           return "dec{l}\t%k0";
5604         }
5606     default:
5607       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5609       if (GET_CODE (operands[2]) == CONST_INT
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{l}\t{%2, %k0|%k0, %2}";
5616         }
5617       return "add{l}\t{%2, %k0|%k0, %2}";
5618     }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "SI")])
5626 (define_insn "*addsi_3"
5627   [(set (reg FLAGS_REG)
5628         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5629                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5630    (clobber (match_scratch:SI 0 "=r"))]
5631   "ix86_match_ccmode (insn, CCZmode)
5632    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5633    /* Current assemblers are broken and do not allow @GOTOFF in
5634       ought but a memory context.  */
5635    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5637   switch (get_attr_type (insn))
5638     {
5639     case TYPE_INCDEC:
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       if (operands[2] == const1_rtx)
5642         return "inc{l}\t%0";
5643       else
5644         {
5645           gcc_assert (operands[2] == constm1_rtx);
5646           return "dec{l}\t%0";
5647         }
5649     default:
5650       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5651       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5652          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5653       if (GET_CODE (operands[2]) == CONST_INT
5654           && (INTVAL (operands[2]) == 128
5655               || (INTVAL (operands[2]) < 0
5656                   && INTVAL (operands[2]) != -128)))
5657         {
5658           operands[2] = GEN_INT (-INTVAL (operands[2]));
5659           return "sub{l}\t{%2, %0|%0, %2}";
5660         }
5661       return "add{l}\t{%2, %0|%0, %2}";
5662     }
5664   [(set (attr "type")
5665      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5666         (const_string "incdec")
5667         (const_string "alu")))
5668    (set_attr "mode" "SI")])
5670 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5671 (define_insn "*addsi_3_zext"
5672   [(set (reg FLAGS_REG)
5673         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5674                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5675    (set (match_operand:DI 0 "register_operand" "=r")
5676         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5677   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5678    && ix86_binary_operator_ok (PLUS, SImode, operands)
5679    /* Current assemblers are broken and do not allow @GOTOFF in
5680       ought but a memory context.  */
5681    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5683   switch (get_attr_type (insn))
5684     {
5685     case TYPE_INCDEC:
5686       if (operands[2] == const1_rtx)
5687         return "inc{l}\t%k0";
5688       else
5689         {
5690           gcc_assert (operands[2] == constm1_rtx);
5691           return "dec{l}\t%k0";
5692         }
5694     default:
5695       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5696          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5697       if (GET_CODE (operands[2]) == CONST_INT
5698           && (INTVAL (operands[2]) == 128
5699               || (INTVAL (operands[2]) < 0
5700                   && INTVAL (operands[2]) != -128)))
5701         {
5702           operands[2] = GEN_INT (-INTVAL (operands[2]));
5703           return "sub{l}\t{%2, %k0|%k0, %2}";
5704         }
5705       return "add{l}\t{%2, %k0|%k0, %2}";
5706     }
5708   [(set (attr "type")
5709      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5710         (const_string "incdec")
5711         (const_string "alu")))
5712    (set_attr "mode" "SI")])
5714 ; For comparisons against 1, -1 and 128, we may generate better code
5715 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5716 ; is matched then.  We can't accept general immediate, because for
5717 ; case of overflows,  the result is messed up.
5718 ; This pattern also don't hold of 0x80000000, since the value overflows
5719 ; when negated.
5720 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5721 ; only for comparisons not depending on it.
5722 (define_insn "*addsi_4"
5723   [(set (reg FLAGS_REG)
5724         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5725                  (match_operand:SI 2 "const_int_operand" "n")))
5726    (clobber (match_scratch:SI 0 "=rm"))]
5727   "ix86_match_ccmode (insn, CCGCmode)
5728    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_INCDEC:
5733       if (operands[2] == constm1_rtx)
5734         return "inc{l}\t%0";
5735       else
5736         {
5737           gcc_assert (operands[2] == const1_rtx);
5738           return "dec{l}\t%0";
5739         }
5741     default:
5742       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if ((INTVAL (operands[2]) == -128
5746            || (INTVAL (operands[2]) > 0
5747                && INTVAL (operands[2]) != 128)))
5748         return "sub{l}\t{%2, %0|%0, %2}";
5749       operands[2] = GEN_INT (-INTVAL (operands[2]));
5750       return "add{l}\t{%2, %0|%0, %2}";
5751     }
5753   [(set (attr "type")
5754      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5755         (const_string "incdec")
5756         (const_string "alu")))
5757    (set_attr "mode" "SI")])
5759 (define_insn "*addsi_5"
5760   [(set (reg FLAGS_REG)
5761         (compare
5762           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5763                    (match_operand:SI 2 "general_operand" "rmni"))
5764           (const_int 0)))                       
5765    (clobber (match_scratch:SI 0 "=r"))]
5766   "ix86_match_ccmode (insn, CCGOCmode)
5767    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5768    /* Current assemblers are broken and do not allow @GOTOFF in
5769       ought but a memory context.  */
5770    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5772   switch (get_attr_type (insn))
5773     {
5774     case TYPE_INCDEC:
5775       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776       if (operands[2] == const1_rtx)
5777         return "inc{l}\t%0";
5778       else
5779         {
5780           gcc_assert (operands[2] == constm1_rtx);
5781           return "dec{l}\t%0";
5782         }
5784     default:
5785       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5787          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5788       if (GET_CODE (operands[2]) == CONST_INT
5789           && (INTVAL (operands[2]) == 128
5790               || (INTVAL (operands[2]) < 0
5791                   && INTVAL (operands[2]) != -128)))
5792         {
5793           operands[2] = GEN_INT (-INTVAL (operands[2]));
5794           return "sub{l}\t{%2, %0|%0, %2}";
5795         }
5796       return "add{l}\t{%2, %0|%0, %2}";
5797     }
5799   [(set (attr "type")
5800      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5801         (const_string "incdec")
5802         (const_string "alu")))
5803    (set_attr "mode" "SI")])
5805 (define_expand "addhi3"
5806   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5807                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5808                             (match_operand:HI 2 "general_operand" "")))
5809               (clobber (reg:CC FLAGS_REG))])]
5810   "TARGET_HIMODE_MATH"
5811   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5813 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5814 ;; type optimizations enabled by define-splits.  This is not important
5815 ;; for PII, and in fact harmful because of partial register stalls.
5817 (define_insn "*addhi_1_lea"
5818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5819         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5820                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5821    (clobber (reg:CC FLAGS_REG))]
5822   "!TARGET_PARTIAL_REG_STALL
5823    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5825   switch (get_attr_type (insn))
5826     {
5827     case TYPE_LEA:
5828       return "#";
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{w}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{w}\t%0";
5836         }
5838     default:
5839       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5840          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5841       if (GET_CODE (operands[2]) == CONST_INT
5842           && (INTVAL (operands[2]) == 128
5843               || (INTVAL (operands[2]) < 0
5844                   && INTVAL (operands[2]) != -128)))
5845         {
5846           operands[2] = GEN_INT (-INTVAL (operands[2]));
5847           return "sub{w}\t{%2, %0|%0, %2}";
5848         }
5849       return "add{w}\t{%2, %0|%0, %2}";
5850     }
5852   [(set (attr "type")
5853      (if_then_else (eq_attr "alternative" "2")
5854         (const_string "lea")
5855         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5856            (const_string "incdec")
5857            (const_string "alu"))))
5858    (set_attr "mode" "HI,HI,SI")])
5860 (define_insn "*addhi_1"
5861   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5862         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                  (match_operand:HI 2 "general_operand" "ri,rm")))
5864    (clobber (reg:CC FLAGS_REG))]
5865   "TARGET_PARTIAL_REG_STALL
5866    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5868   switch (get_attr_type (insn))
5869     {
5870     case TYPE_INCDEC:
5871       if (operands[2] == const1_rtx)
5872         return "inc{w}\t%0";
5873       else
5874         {
5875           gcc_assert (operands[2] == constm1_rtx);
5876           return "dec{w}\t%0";
5877         }
5879     default:
5880       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5882       if (GET_CODE (operands[2]) == CONST_INT
5883           && (INTVAL (operands[2]) == 128
5884               || (INTVAL (operands[2]) < 0
5885                   && INTVAL (operands[2]) != -128)))
5886         {
5887           operands[2] = GEN_INT (-INTVAL (operands[2]));
5888           return "sub{w}\t{%2, %0|%0, %2}";
5889         }
5890       return "add{w}\t{%2, %0|%0, %2}";
5891     }
5893   [(set (attr "type")
5894      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5895         (const_string "incdec")
5896         (const_string "alu")))
5897    (set_attr "mode" "HI")])
5899 (define_insn "*addhi_2"
5900   [(set (reg FLAGS_REG)
5901         (compare
5902           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5903                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5904           (const_int 0)))                       
5905    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5906         (plus:HI (match_dup 1) (match_dup 2)))]
5907   "ix86_match_ccmode (insn, CCGOCmode)
5908    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5910   switch (get_attr_type (insn))
5911     {
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return "dec{w}\t%0";
5919         }
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (GET_CODE (operands[2]) == CONST_INT
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{w}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{w}\t{%2, %0|%0, %2}";
5933     }
5935   [(set (attr "type")
5936      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5937         (const_string "incdec")
5938         (const_string "alu")))
5939    (set_attr "mode" "HI")])
5941 (define_insn "*addhi_3"
5942   [(set (reg FLAGS_REG)
5943         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5944                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5945    (clobber (match_scratch:HI 0 "=r"))]
5946   "ix86_match_ccmode (insn, CCZmode)
5947    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == const1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == constm1_rtx);
5957           return "dec{w}\t%0";
5958         }
5960     default:
5961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5963       if (GET_CODE (operands[2]) == CONST_INT
5964           && (INTVAL (operands[2]) == 128
5965               || (INTVAL (operands[2]) < 0
5966                   && INTVAL (operands[2]) != -128)))
5967         {
5968           operands[2] = GEN_INT (-INTVAL (operands[2]));
5969           return "sub{w}\t{%2, %0|%0, %2}";
5970         }
5971       return "add{w}\t{%2, %0|%0, %2}";
5972     }
5974   [(set (attr "type")
5975      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5976         (const_string "incdec")
5977         (const_string "alu")))
5978    (set_attr "mode" "HI")])
5980 ; See comments above addsi_4 for details.
5981 (define_insn "*addhi_4"
5982   [(set (reg FLAGS_REG)
5983         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5984                  (match_operand:HI 2 "const_int_operand" "n")))
5985    (clobber (match_scratch:HI 0 "=rm"))]
5986   "ix86_match_ccmode (insn, CCGCmode)
5987    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == constm1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == const1_rtx);
5997           return "dec{w}\t%0";
5998         }
6000     default:
6001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6003          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6004       if ((INTVAL (operands[2]) == -128
6005            || (INTVAL (operands[2]) > 0
6006                && INTVAL (operands[2]) != 128)))
6007         return "sub{w}\t{%2, %0|%0, %2}";
6008       operands[2] = GEN_INT (-INTVAL (operands[2]));
6009       return "add{w}\t{%2, %0|%0, %2}";
6010     }
6012   [(set (attr "type")
6013      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6014         (const_string "incdec")
6015         (const_string "alu")))
6016    (set_attr "mode" "SI")])
6019 (define_insn "*addhi_5"
6020   [(set (reg FLAGS_REG)
6021         (compare
6022           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6023                    (match_operand:HI 2 "general_operand" "rmni"))
6024           (const_int 0)))                       
6025    (clobber (match_scratch:HI 0 "=r"))]
6026   "ix86_match_ccmode (insn, CCGOCmode)
6027    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6029   switch (get_attr_type (insn))
6030     {
6031     case TYPE_INCDEC:
6032       if (operands[2] == const1_rtx)
6033         return "inc{w}\t%0";
6034       else
6035         {
6036           gcc_assert (operands[2] == constm1_rtx);
6037           return "dec{w}\t%0";
6038         }
6040     default:
6041       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6042          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6043       if (GET_CODE (operands[2]) == CONST_INT
6044           && (INTVAL (operands[2]) == 128
6045               || (INTVAL (operands[2]) < 0
6046                   && INTVAL (operands[2]) != -128)))
6047         {
6048           operands[2] = GEN_INT (-INTVAL (operands[2]));
6049           return "sub{w}\t{%2, %0|%0, %2}";
6050         }
6051       return "add{w}\t{%2, %0|%0, %2}";
6052     }
6054   [(set (attr "type")
6055      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6056         (const_string "incdec")
6057         (const_string "alu")))
6058    (set_attr "mode" "HI")])
6060 (define_expand "addqi3"
6061   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6062                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6063                             (match_operand:QI 2 "general_operand" "")))
6064               (clobber (reg:CC FLAGS_REG))])]
6065   "TARGET_QIMODE_MATH"
6066   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6068 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6069 (define_insn "*addqi_1_lea"
6070   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6071         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6072                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6073    (clobber (reg:CC FLAGS_REG))]
6074   "!TARGET_PARTIAL_REG_STALL
6075    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6077   int widen = (which_alternative == 2);
6078   switch (get_attr_type (insn))
6079     {
6080     case TYPE_LEA:
6081       return "#";
6082     case TYPE_INCDEC:
6083       if (operands[2] == const1_rtx)
6084         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6085       else
6086         {
6087           gcc_assert (operands[2] == constm1_rtx);
6088           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6089         }
6091     default:
6092       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6094       if (GET_CODE (operands[2]) == CONST_INT
6095           && (INTVAL (operands[2]) == 128
6096               || (INTVAL (operands[2]) < 0
6097                   && INTVAL (operands[2]) != -128)))
6098         {
6099           operands[2] = GEN_INT (-INTVAL (operands[2]));
6100           if (widen)
6101             return "sub{l}\t{%2, %k0|%k0, %2}";
6102           else
6103             return "sub{b}\t{%2, %0|%0, %2}";
6104         }
6105       if (widen)
6106         return "add{l}\t{%k2, %k0|%k0, %k2}";
6107       else
6108         return "add{b}\t{%2, %0|%0, %2}";
6109     }
6111   [(set (attr "type")
6112      (if_then_else (eq_attr "alternative" "3")
6113         (const_string "lea")
6114         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6115            (const_string "incdec")
6116            (const_string "alu"))))
6117    (set_attr "mode" "QI,QI,SI,SI")])
6119 (define_insn "*addqi_1"
6120   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6121         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6122                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6123    (clobber (reg:CC FLAGS_REG))]
6124   "TARGET_PARTIAL_REG_STALL
6125    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6127   int widen = (which_alternative == 2);
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137         }
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (GET_CODE (operands[2]) == CONST_INT
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           if (widen)
6149             return "sub{l}\t{%2, %k0|%k0, %2}";
6150           else
6151             return "sub{b}\t{%2, %0|%0, %2}";
6152         }
6153       if (widen)
6154         return "add{l}\t{%k2, %k0|%k0, %k2}";
6155       else
6156         return "add{b}\t{%2, %0|%0, %2}";
6157     }
6159   [(set (attr "type")
6160      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6161         (const_string "incdec")
6162         (const_string "alu")))
6163    (set_attr "mode" "QI,QI,SI")])
6165 (define_insn "*addqi_1_slp"
6166   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6167         (plus:QI (match_dup 0)
6168                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6169    (clobber (reg:CC FLAGS_REG))]
6170   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6173   switch (get_attr_type (insn))
6174     {
6175     case TYPE_INCDEC:
6176       if (operands[1] == const1_rtx)
6177         return "inc{b}\t%0";
6178       else
6179         {
6180           gcc_assert (operands[1] == constm1_rtx);
6181           return "dec{b}\t%0";
6182         }
6184     default:
6185       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6186       if (GET_CODE (operands[1]) == CONST_INT
6187           && INTVAL (operands[1]) < 0)
6188         {
6189           operands[1] = GEN_INT (-INTVAL (operands[1]));
6190           return "sub{b}\t{%1, %0|%0, %1}";
6191         }
6192       return "add{b}\t{%1, %0|%0, %1}";
6193     }
6195   [(set (attr "type")
6196      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6197         (const_string "incdec")
6198         (const_string "alu1")))
6199    (set (attr "memory")
6200      (if_then_else (match_operand 1 "memory_operand" "")
6201         (const_string "load")
6202         (const_string "none")))
6203    (set_attr "mode" "QI")])
6205 (define_insn "*addqi_2"
6206   [(set (reg FLAGS_REG)
6207         (compare
6208           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6209                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6210           (const_int 0)))
6211    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6212         (plus:QI (match_dup 1) (match_dup 2)))]
6213   "ix86_match_ccmode (insn, CCGOCmode)
6214    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return "inc{b}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx
6224                       || (GET_CODE (operands[2]) == CONST_INT
6225                           && INTVAL (operands[2]) == 255));
6226           return "dec{b}\t%0";
6227         }
6229     default:
6230       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6231       if (GET_CODE (operands[2]) == CONST_INT
6232           && INTVAL (operands[2]) < 0)
6233         {
6234           operands[2] = GEN_INT (-INTVAL (operands[2]));
6235           return "sub{b}\t{%2, %0|%0, %2}";
6236         }
6237       return "add{b}\t{%2, %0|%0, %2}";
6238     }
6240   [(set (attr "type")
6241      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242         (const_string "incdec")
6243         (const_string "alu")))
6244    (set_attr "mode" "QI")])
6246 (define_insn "*addqi_3"
6247   [(set (reg FLAGS_REG)
6248         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6249                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6250    (clobber (match_scratch:QI 0 "=q"))]
6251   "ix86_match_ccmode (insn, CCZmode)
6252    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6254   switch (get_attr_type (insn))
6255     {
6256     case TYPE_INCDEC:
6257       if (operands[2] == const1_rtx)
6258         return "inc{b}\t%0";
6259       else
6260         {
6261           gcc_assert (operands[2] == constm1_rtx
6262                       || (GET_CODE (operands[2]) == CONST_INT
6263                           && INTVAL (operands[2]) == 255));
6264           return "dec{b}\t%0";
6265         }
6267     default:
6268       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6269       if (GET_CODE (operands[2]) == CONST_INT
6270           && INTVAL (operands[2]) < 0)
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           return "sub{b}\t{%2, %0|%0, %2}";
6274         }
6275       return "add{b}\t{%2, %0|%0, %2}";
6276     }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set_attr "mode" "QI")])
6284 ; See comments above addsi_4 for details.
6285 (define_insn "*addqi_4"
6286   [(set (reg FLAGS_REG)
6287         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6288                  (match_operand:QI 2 "const_int_operand" "n")))
6289    (clobber (match_scratch:QI 0 "=qm"))]
6290   "ix86_match_ccmode (insn, CCGCmode)
6291    && (INTVAL (operands[2]) & 0xff) != 0x80"
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == constm1_rtx
6297           || (GET_CODE (operands[2]) == CONST_INT
6298               && INTVAL (operands[2]) == 255))
6299         return "inc{b}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == const1_rtx);
6303           return "dec{b}\t%0";
6304         }
6306     default:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       if (INTVAL (operands[2]) < 0)
6309         {
6310           operands[2] = GEN_INT (-INTVAL (operands[2]));
6311           return "add{b}\t{%2, %0|%0, %2}";
6312         }
6313       return "sub{b}\t{%2, %0|%0, %2}";
6314     }
6316   [(set (attr "type")
6317      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6318         (const_string "incdec")
6319         (const_string "alu")))
6320    (set_attr "mode" "QI")])
6323 (define_insn "*addqi_5"
6324   [(set (reg FLAGS_REG)
6325         (compare
6326           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6327                    (match_operand:QI 2 "general_operand" "qmni"))
6328           (const_int 0)))
6329    (clobber (match_scratch:QI 0 "=q"))]
6330   "ix86_match_ccmode (insn, CCGOCmode)
6331    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[2] == const1_rtx)
6337         return "inc{b}\t%0";
6338       else
6339         {
6340           gcc_assert (operands[2] == constm1_rtx
6341                       || (GET_CODE (operands[2]) == CONST_INT
6342                           && INTVAL (operands[2]) == 255));
6343           return "dec{b}\t%0";
6344         }
6346     default:
6347       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6348       if (GET_CODE (operands[2]) == CONST_INT
6349           && INTVAL (operands[2]) < 0)
6350         {
6351           operands[2] = GEN_INT (-INTVAL (operands[2]));
6352           return "sub{b}\t{%2, %0|%0, %2}";
6353         }
6354       return "add{b}\t{%2, %0|%0, %2}";
6355     }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "QI")])
6364 (define_insn "addqi_ext_1"
6365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366                          (const_int 8)
6367                          (const_int 8))
6368         (plus:SI
6369           (zero_extract:SI
6370             (match_operand 1 "ext_register_operand" "0")
6371             (const_int 8)
6372             (const_int 8))
6373           (match_operand:QI 2 "general_operand" "Qmn")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "!TARGET_64BIT"
6377   switch (get_attr_type (insn))
6378     {
6379     case TYPE_INCDEC:
6380       if (operands[2] == const1_rtx)
6381         return "inc{b}\t%h0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx
6385                       || (GET_CODE (operands[2]) == CONST_INT
6386                           && INTVAL (operands[2]) == 255));
6387           return "dec{b}\t%h0";
6388         }
6390     default:
6391       return "add{b}\t{%2, %h0|%h0, %2}";
6392     }
6394   [(set (attr "type")
6395      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396         (const_string "incdec")
6397         (const_string "alu")))
6398    (set_attr "mode" "QI")])
6400 (define_insn "*addqi_ext_1_rex64"
6401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402                          (const_int 8)
6403                          (const_int 8))
6404         (plus:SI
6405           (zero_extract:SI
6406             (match_operand 1 "ext_register_operand" "0")
6407             (const_int 8)
6408             (const_int 8))
6409           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6410    (clobber (reg:CC FLAGS_REG))]
6411   "TARGET_64BIT"
6413   switch (get_attr_type (insn))
6414     {
6415     case TYPE_INCDEC:
6416       if (operands[2] == const1_rtx)
6417         return "inc{b}\t%h0";
6418       else
6419         {
6420           gcc_assert (operands[2] == constm1_rtx
6421                       || (GET_CODE (operands[2]) == CONST_INT
6422                           && INTVAL (operands[2]) == 255));
6423           return "dec{b}\t%h0";
6424         }
6426     default:
6427       return "add{b}\t{%2, %h0|%h0, %2}";
6428     }
6430   [(set (attr "type")
6431      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6432         (const_string "incdec")
6433         (const_string "alu")))
6434    (set_attr "mode" "QI")])
6436 (define_insn "*addqi_ext_2"
6437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6438                          (const_int 8)
6439                          (const_int 8))
6440         (plus:SI
6441           (zero_extract:SI
6442             (match_operand 1 "ext_register_operand" "%0")
6443             (const_int 8)
6444             (const_int 8))
6445           (zero_extract:SI
6446             (match_operand 2 "ext_register_operand" "Q")
6447             (const_int 8)
6448             (const_int 8))))
6449    (clobber (reg:CC FLAGS_REG))]
6450   ""
6451   "add{b}\t{%h2, %h0|%h0, %h2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "QI")])
6455 ;; The patterns that match these are at the end of this file.
6457 (define_expand "addxf3"
6458   [(set (match_operand:XF 0 "register_operand" "")
6459         (plus:XF (match_operand:XF 1 "register_operand" "")
6460                  (match_operand:XF 2 "register_operand" "")))]
6461   "TARGET_80387"
6462   "")
6464 (define_expand "adddf3"
6465   [(set (match_operand:DF 0 "register_operand" "")
6466         (plus:DF (match_operand:DF 1 "register_operand" "")
6467                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6468   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6469   "")
6471 (define_expand "addsf3"
6472   [(set (match_operand:SF 0 "register_operand" "")
6473         (plus:SF (match_operand:SF 1 "register_operand" "")
6474                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6475   "TARGET_80387 || TARGET_SSE_MATH"
6476   "")
6478 ;; Subtract instructions
6480 ;; %%% splits for subditi3
6482 (define_expand "subti3"
6483   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6484                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6485                              (match_operand:TI 2 "x86_64_general_operand" "")))
6486               (clobber (reg:CC FLAGS_REG))])]
6487   "TARGET_64BIT"
6488   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6490 (define_insn "*subti3_1"
6491   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6492         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6493                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6494    (clobber (reg:CC FLAGS_REG))]
6495   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6496   "#")
6498 (define_split
6499   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6500         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6501                   (match_operand:TI 2 "general_operand" "")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT && reload_completed"
6504   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6505               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6506    (parallel [(set (match_dup 3)
6507                    (minus:DI (match_dup 4)
6508                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6509                                       (match_dup 5))))
6510               (clobber (reg:CC FLAGS_REG))])]
6511   "split_ti (operands+0, 1, operands+0, operands+3);
6512    split_ti (operands+1, 1, operands+1, operands+4);
6513    split_ti (operands+2, 1, operands+2, operands+5);")
6515 ;; %%% splits for subsidi3
6517 (define_expand "subdi3"
6518   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6519                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6520                              (match_operand:DI 2 "x86_64_general_operand" "")))
6521               (clobber (reg:CC FLAGS_REG))])]
6522   ""
6523   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6525 (define_insn "*subdi3_1"
6526   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6527         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6528                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6529    (clobber (reg:CC FLAGS_REG))]
6530   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6531   "#")
6533 (define_split
6534   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6535         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6536                   (match_operand:DI 2 "general_operand" "")))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "!TARGET_64BIT && reload_completed"
6539   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6540               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6541    (parallel [(set (match_dup 3)
6542                    (minus:SI (match_dup 4)
6543                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6544                                       (match_dup 5))))
6545               (clobber (reg:CC FLAGS_REG))])]
6546   "split_di (operands+0, 1, operands+0, operands+3);
6547    split_di (operands+1, 1, operands+1, operands+4);
6548    split_di (operands+2, 1, operands+2, operands+5);")
6550 (define_insn "subdi3_carry_rex64"
6551   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6552           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6554                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6555    (clobber (reg:CC FLAGS_REG))]
6556   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6557   "sbb{q}\t{%2, %0|%0, %2}"
6558   [(set_attr "type" "alu")
6559    (set_attr "pent_pair" "pu")
6560    (set_attr "mode" "DI")])
6562 (define_insn "*subdi_1_rex64"
6563   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6564         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6565                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6566    (clobber (reg:CC FLAGS_REG))]
6567   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6568   "sub{q}\t{%2, %0|%0, %2}"
6569   [(set_attr "type" "alu")
6570    (set_attr "mode" "DI")])
6572 (define_insn "*subdi_2_rex64"
6573   [(set (reg FLAGS_REG)
6574         (compare
6575           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6577           (const_int 0)))
6578    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6579         (minus:DI (match_dup 1) (match_dup 2)))]
6580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6581    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6582   "sub{q}\t{%2, %0|%0, %2}"
6583   [(set_attr "type" "alu")
6584    (set_attr "mode" "DI")])
6586 (define_insn "*subdi_3_rex63"
6587   [(set (reg FLAGS_REG)
6588         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6589                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6590    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6591         (minus:DI (match_dup 1) (match_dup 2)))]
6592   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6593    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6594   "sub{q}\t{%2, %0|%0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "DI")])
6598 (define_insn "subqi3_carry"
6599   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6600           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6601             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6602                (match_operand:QI 2 "general_operand" "qi,qm"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6605   "sbb{b}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "QI")])
6610 (define_insn "subhi3_carry"
6611   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6612           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6613             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6614                (match_operand:HI 2 "general_operand" "ri,rm"))))
6615    (clobber (reg:CC FLAGS_REG))]
6616   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6617   "sbb{w}\t{%2, %0|%0, %2}"
6618   [(set_attr "type" "alu")
6619    (set_attr "pent_pair" "pu")
6620    (set_attr "mode" "HI")])
6622 (define_insn "subsi3_carry"
6623   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6624           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6625             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6626                (match_operand:SI 2 "general_operand" "ri,rm"))))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6629   "sbb{l}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "pent_pair" "pu")
6632    (set_attr "mode" "SI")])
6634 (define_insn "subsi3_carry_zext"
6635   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6636           (zero_extend:DI
6637             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6638               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6639                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6640    (clobber (reg:CC FLAGS_REG))]
6641   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sbb{l}\t{%2, %k0|%k0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "pent_pair" "pu")
6645    (set_attr "mode" "SI")])
6647 (define_expand "subsi3"
6648   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6649                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6650                              (match_operand:SI 2 "general_operand" "")))
6651               (clobber (reg:CC FLAGS_REG))])]
6652   ""
6653   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6655 (define_insn "*subsi_1"
6656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658                   (match_operand:SI 2 "general_operand" "ri,rm")))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6661   "sub{l}\t{%2, %0|%0, %2}"
6662   [(set_attr "type" "alu")
6663    (set_attr "mode" "SI")])
6665 (define_insn "*subsi_1_zext"
6666   [(set (match_operand:DI 0 "register_operand" "=r")
6667         (zero_extend:DI
6668           (minus:SI (match_operand:SI 1 "register_operand" "0")
6669                     (match_operand:SI 2 "general_operand" "rim"))))
6670    (clobber (reg:CC FLAGS_REG))]
6671   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672   "sub{l}\t{%2, %k0|%k0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "mode" "SI")])
6676 (define_insn "*subsi_2"
6677   [(set (reg FLAGS_REG)
6678         (compare
6679           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6680                     (match_operand:SI 2 "general_operand" "ri,rm"))
6681           (const_int 0)))
6682    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6683         (minus:SI (match_dup 1) (match_dup 2)))]
6684   "ix86_match_ccmode (insn, CCGOCmode)
6685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686   "sub{l}\t{%2, %0|%0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "SI")])
6690 (define_insn "*subsi_2_zext"
6691   [(set (reg FLAGS_REG)
6692         (compare
6693           (minus:SI (match_operand:SI 1 "register_operand" "0")
6694                     (match_operand:SI 2 "general_operand" "rim"))
6695           (const_int 0)))
6696    (set (match_operand:DI 0 "register_operand" "=r")
6697         (zero_extend:DI
6698           (minus:SI (match_dup 1)
6699                     (match_dup 2))))]
6700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702   "sub{l}\t{%2, %k0|%k0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "SI")])
6706 (define_insn "*subsi_3"
6707   [(set (reg FLAGS_REG)
6708         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6709                  (match_operand:SI 2 "general_operand" "ri,rm")))
6710    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6711         (minus:SI (match_dup 1) (match_dup 2)))]
6712   "ix86_match_ccmode (insn, CCmode)
6713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714   "sub{l}\t{%2, %0|%0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "SI")])
6718 (define_insn "*subsi_3_zext"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "register_operand" "0")
6721                  (match_operand:SI 2 "general_operand" "rim")))
6722    (set (match_operand:DI 0 "register_operand" "=r")
6723         (zero_extend:DI
6724           (minus:SI (match_dup 1)
6725                     (match_dup 2))))]
6726   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6727    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6728   "sub{l}\t{%2, %1|%1, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "DI")])
6732 (define_expand "subhi3"
6733   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6734                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6735                              (match_operand:HI 2 "general_operand" "")))
6736               (clobber (reg:CC FLAGS_REG))])]
6737   "TARGET_HIMODE_MATH"
6738   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6740 (define_insn "*subhi_1"
6741   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6742         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6743                   (match_operand:HI 2 "general_operand" "ri,rm")))
6744    (clobber (reg:CC FLAGS_REG))]
6745   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6746   "sub{w}\t{%2, %0|%0, %2}"
6747   [(set_attr "type" "alu")
6748    (set_attr "mode" "HI")])
6750 (define_insn "*subhi_2"
6751   [(set (reg FLAGS_REG)
6752         (compare
6753           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6754                     (match_operand:HI 2 "general_operand" "ri,rm"))
6755           (const_int 0)))
6756    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6757         (minus:HI (match_dup 1) (match_dup 2)))]
6758   "ix86_match_ccmode (insn, CCGOCmode)
6759    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6760   "sub{w}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "HI")])
6764 (define_insn "*subhi_3"
6765   [(set (reg FLAGS_REG)
6766         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6767                  (match_operand:HI 2 "general_operand" "ri,rm")))
6768    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6769         (minus:HI (match_dup 1) (match_dup 2)))]
6770   "ix86_match_ccmode (insn, CCmode)
6771    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6772   "sub{w}\t{%2, %0|%0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "mode" "HI")])
6776 (define_expand "subqi3"
6777   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6778                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6779                              (match_operand:QI 2 "general_operand" "")))
6780               (clobber (reg:CC FLAGS_REG))])]
6781   "TARGET_QIMODE_MATH"
6782   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6784 (define_insn "*subqi_1"
6785   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6786         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6787                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6790   "sub{b}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "alu")
6792    (set_attr "mode" "QI")])
6794 (define_insn "*subqi_1_slp"
6795   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6796         (minus:QI (match_dup 0)
6797                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6798    (clobber (reg:CC FLAGS_REG))]
6799   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6801   "sub{b}\t{%1, %0|%0, %1}"
6802   [(set_attr "type" "alu1")
6803    (set_attr "mode" "QI")])
6805 (define_insn "*subqi_2"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6809                     (match_operand:QI 2 "general_operand" "qi,qm"))
6810           (const_int 0)))
6811    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6812         (minus:HI (match_dup 1) (match_dup 2)))]
6813   "ix86_match_ccmode (insn, CCGOCmode)
6814    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6815   "sub{b}\t{%2, %0|%0, %2}"
6816   [(set_attr "type" "alu")
6817    (set_attr "mode" "QI")])
6819 (define_insn "*subqi_3"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6822                  (match_operand:QI 2 "general_operand" "qi,qm")))
6823    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6824         (minus:HI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCmode)
6826    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6827   "sub{b}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "QI")])
6831 ;; The patterns that match these are at the end of this file.
6833 (define_expand "subxf3"
6834   [(set (match_operand:XF 0 "register_operand" "")
6835         (minus:XF (match_operand:XF 1 "register_operand" "")
6836                   (match_operand:XF 2 "register_operand" "")))]
6837   "TARGET_80387"
6838   "")
6840 (define_expand "subdf3"
6841   [(set (match_operand:DF 0 "register_operand" "")
6842         (minus:DF (match_operand:DF 1 "register_operand" "")
6843                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6844   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6845   "")
6847 (define_expand "subsf3"
6848   [(set (match_operand:SF 0 "register_operand" "")
6849         (minus:SF (match_operand:SF 1 "register_operand" "")
6850                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6851   "TARGET_80387 || TARGET_SSE_MATH"
6852   "")
6854 ;; Multiply instructions
6856 (define_expand "muldi3"
6857   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6858                    (mult:DI (match_operand:DI 1 "register_operand" "")
6859                             (match_operand:DI 2 "x86_64_general_operand" "")))
6860               (clobber (reg:CC FLAGS_REG))])]
6861   "TARGET_64BIT"
6862   "")
6864 (define_insn "*muldi3_1_rex64"
6865   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6866         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6867                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6868    (clobber (reg:CC FLAGS_REG))]
6869   "TARGET_64BIT
6870    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6871   "@
6872    imul{q}\t{%2, %1, %0|%0, %1, %2}
6873    imul{q}\t{%2, %1, %0|%0, %1, %2}
6874    imul{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "imul")
6876    (set_attr "prefix_0f" "0,0,1")
6877    (set (attr "athlon_decode")
6878         (cond [(eq_attr "cpu" "athlon")
6879                   (const_string "vector")
6880                (eq_attr "alternative" "1")
6881                   (const_string "vector")
6882                (and (eq_attr "alternative" "2")
6883                     (match_operand 1 "memory_operand" ""))
6884                   (const_string "vector")]
6885               (const_string "direct")))
6886    (set_attr "mode" "DI")])
6888 (define_expand "mulsi3"
6889   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6890                    (mult:SI (match_operand:SI 1 "register_operand" "")
6891                             (match_operand:SI 2 "general_operand" "")))
6892               (clobber (reg:CC FLAGS_REG))])]
6893   ""
6894   "")
6896 (define_insn "*mulsi3_1"
6897   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6898         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6899                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6900    (clobber (reg:CC FLAGS_REG))]
6901   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6902   "@
6903    imul{l}\t{%2, %1, %0|%0, %1, %2}
6904    imul{l}\t{%2, %1, %0|%0, %1, %2}
6905    imul{l}\t{%2, %0|%0, %2}"
6906   [(set_attr "type" "imul")
6907    (set_attr "prefix_0f" "0,0,1")
6908    (set (attr "athlon_decode")
6909         (cond [(eq_attr "cpu" "athlon")
6910                   (const_string "vector")
6911                (eq_attr "alternative" "1")
6912                   (const_string "vector")
6913                (and (eq_attr "alternative" "2")
6914                     (match_operand 1 "memory_operand" ""))
6915                   (const_string "vector")]
6916               (const_string "direct")))
6917    (set_attr "mode" "SI")])
6919 (define_insn "*mulsi3_1_zext"
6920   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6921         (zero_extend:DI
6922           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6923                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "TARGET_64BIT
6926    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6927   "@
6928    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6930    imul{l}\t{%2, %k0|%k0, %2}"
6931   [(set_attr "type" "imul")
6932    (set_attr "prefix_0f" "0,0,1")
6933    (set (attr "athlon_decode")
6934         (cond [(eq_attr "cpu" "athlon")
6935                   (const_string "vector")
6936                (eq_attr "alternative" "1")
6937                   (const_string "vector")
6938                (and (eq_attr "alternative" "2")
6939                     (match_operand 1 "memory_operand" ""))
6940                   (const_string "vector")]
6941               (const_string "direct")))
6942    (set_attr "mode" "SI")])
6944 (define_expand "mulhi3"
6945   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6946                    (mult:HI (match_operand:HI 1 "register_operand" "")
6947                             (match_operand:HI 2 "general_operand" "")))
6948               (clobber (reg:CC FLAGS_REG))])]
6949   "TARGET_HIMODE_MATH"
6950   "")
6952 (define_insn "*mulhi3_1"
6953   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6954         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6958   "@
6959    imul{w}\t{%2, %1, %0|%0, %1, %2}
6960    imul{w}\t{%2, %1, %0|%0, %1, %2}
6961    imul{w}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "imul")
6963    (set_attr "prefix_0f" "0,0,1")
6964    (set (attr "athlon_decode")
6965         (cond [(eq_attr "cpu" "athlon")
6966                   (const_string "vector")
6967                (eq_attr "alternative" "1,2")
6968                   (const_string "vector")]
6969               (const_string "direct")))
6970    (set_attr "mode" "HI")])
6972 (define_expand "mulqi3"
6973   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6974                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6975                             (match_operand:QI 2 "register_operand" "")))
6976               (clobber (reg:CC FLAGS_REG))])]
6977   "TARGET_QIMODE_MATH"
6978   "")
6980 (define_insn "*mulqi3_1"
6981   [(set (match_operand:QI 0 "register_operand" "=a")
6982         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6983                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6984    (clobber (reg:CC FLAGS_REG))]
6985   "TARGET_QIMODE_MATH
6986    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6987   "mul{b}\t%2"
6988   [(set_attr "type" "imul")
6989    (set_attr "length_immediate" "0")
6990    (set (attr "athlon_decode")
6991      (if_then_else (eq_attr "cpu" "athlon")
6992         (const_string "vector")
6993         (const_string "direct")))
6994    (set_attr "mode" "QI")])
6996 (define_expand "umulqihi3"
6997   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6998                    (mult:HI (zero_extend:HI
6999                               (match_operand:QI 1 "nonimmediate_operand" ""))
7000                             (zero_extend:HI
7001                               (match_operand:QI 2 "register_operand" ""))))
7002               (clobber (reg:CC FLAGS_REG))])]
7003   "TARGET_QIMODE_MATH"
7004   "")
7006 (define_insn "*umulqihi3_1"
7007   [(set (match_operand:HI 0 "register_operand" "=a")
7008         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7009                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7010    (clobber (reg:CC FLAGS_REG))]
7011   "TARGET_QIMODE_MATH
7012    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7013   "mul{b}\t%2"
7014   [(set_attr "type" "imul")
7015    (set_attr "length_immediate" "0")
7016    (set (attr "athlon_decode")
7017      (if_then_else (eq_attr "cpu" "athlon")
7018         (const_string "vector")
7019         (const_string "direct")))
7020    (set_attr "mode" "QI")])
7022 (define_expand "mulqihi3"
7023   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7024                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7025                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7026               (clobber (reg:CC FLAGS_REG))])]
7027   "TARGET_QIMODE_MATH"
7028   "")
7030 (define_insn "*mulqihi3_insn"
7031   [(set (match_operand:HI 0 "register_operand" "=a")
7032         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7033                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "TARGET_QIMODE_MATH
7036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7037   "imul{b}\t%2"
7038   [(set_attr "type" "imul")
7039    (set_attr "length_immediate" "0")
7040    (set (attr "athlon_decode")
7041      (if_then_else (eq_attr "cpu" "athlon")
7042         (const_string "vector")
7043         (const_string "direct")))
7044    (set_attr "mode" "QI")])
7046 (define_expand "umulditi3"
7047   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7048                    (mult:TI (zero_extend:TI
7049                               (match_operand:DI 1 "nonimmediate_operand" ""))
7050                             (zero_extend:TI
7051                               (match_operand:DI 2 "register_operand" ""))))
7052               (clobber (reg:CC FLAGS_REG))])]
7053   "TARGET_64BIT"
7054   "")
7056 (define_insn "*umulditi3_insn"
7057   [(set (match_operand:TI 0 "register_operand" "=A")
7058         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7059                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7060    (clobber (reg:CC FLAGS_REG))]
7061   "TARGET_64BIT
7062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7063   "mul{q}\t%2"
7064   [(set_attr "type" "imul")
7065    (set_attr "length_immediate" "0")
7066    (set (attr "athlon_decode")
7067      (if_then_else (eq_attr "cpu" "athlon")
7068         (const_string "vector")
7069         (const_string "double")))
7070    (set_attr "mode" "DI")])
7072 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7073 (define_expand "umulsidi3"
7074   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7075                    (mult:DI (zero_extend:DI
7076                               (match_operand:SI 1 "nonimmediate_operand" ""))
7077                             (zero_extend:DI
7078                               (match_operand:SI 2 "register_operand" ""))))
7079               (clobber (reg:CC FLAGS_REG))])]
7080   "!TARGET_64BIT"
7081   "")
7083 (define_insn "*umulsidi3_insn"
7084   [(set (match_operand:DI 0 "register_operand" "=A")
7085         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7086                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "!TARGET_64BIT
7089    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090   "mul{l}\t%2"
7091   [(set_attr "type" "imul")
7092    (set_attr "length_immediate" "0")
7093    (set (attr "athlon_decode")
7094      (if_then_else (eq_attr "cpu" "athlon")
7095         (const_string "vector")
7096         (const_string "double")))
7097    (set_attr "mode" "SI")])
7099 (define_expand "mulditi3"
7100   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7101                    (mult:TI (sign_extend:TI
7102                               (match_operand:DI 1 "nonimmediate_operand" ""))
7103                             (sign_extend:TI
7104                               (match_operand:DI 2 "register_operand" ""))))
7105               (clobber (reg:CC FLAGS_REG))])]
7106   "TARGET_64BIT"
7107   "")
7109 (define_insn "*mulditi3_insn"
7110   [(set (match_operand:TI 0 "register_operand" "=A")
7111         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7112                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7113    (clobber (reg:CC FLAGS_REG))]
7114   "TARGET_64BIT
7115    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7116   "imul{q}\t%2"
7117   [(set_attr "type" "imul")
7118    (set_attr "length_immediate" "0")
7119    (set (attr "athlon_decode")
7120      (if_then_else (eq_attr "cpu" "athlon")
7121         (const_string "vector")
7122         (const_string "double")))
7123    (set_attr "mode" "DI")])
7125 (define_expand "mulsidi3"
7126   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7127                    (mult:DI (sign_extend:DI
7128                               (match_operand:SI 1 "nonimmediate_operand" ""))
7129                             (sign_extend:DI
7130                               (match_operand:SI 2 "register_operand" ""))))
7131               (clobber (reg:CC FLAGS_REG))])]
7132   "!TARGET_64BIT"
7133   "")
7135 (define_insn "*mulsidi3_insn"
7136   [(set (match_operand:DI 0 "register_operand" "=A")
7137         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7138                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7139    (clobber (reg:CC FLAGS_REG))]
7140   "!TARGET_64BIT
7141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7142   "imul{l}\t%2"
7143   [(set_attr "type" "imul")
7144    (set_attr "length_immediate" "0")
7145    (set (attr "athlon_decode")
7146      (if_then_else (eq_attr "cpu" "athlon")
7147         (const_string "vector")
7148         (const_string "double")))
7149    (set_attr "mode" "SI")])
7151 (define_expand "umuldi3_highpart"
7152   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7153                    (truncate:DI
7154                      (lshiftrt:TI
7155                        (mult:TI (zero_extend:TI
7156                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7157                                 (zero_extend:TI
7158                                   (match_operand:DI 2 "register_operand" "")))
7159                        (const_int 64))))
7160               (clobber (match_scratch:DI 3 ""))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "TARGET_64BIT"
7163   "")
7165 (define_insn "*umuldi3_highpart_rex64"
7166   [(set (match_operand:DI 0 "register_operand" "=d")
7167         (truncate:DI
7168           (lshiftrt:TI
7169             (mult:TI (zero_extend:TI
7170                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7171                      (zero_extend:TI
7172                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7173             (const_int 64))))
7174    (clobber (match_scratch:DI 3 "=1"))
7175    (clobber (reg:CC FLAGS_REG))]
7176   "TARGET_64BIT
7177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7178   "mul{q}\t%2"
7179   [(set_attr "type" "imul")
7180    (set_attr "length_immediate" "0")
7181    (set (attr "athlon_decode")
7182      (if_then_else (eq_attr "cpu" "athlon")
7183         (const_string "vector")
7184         (const_string "double")))
7185    (set_attr "mode" "DI")])
7187 (define_expand "umulsi3_highpart"
7188   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7189                    (truncate:SI
7190                      (lshiftrt:DI
7191                        (mult:DI (zero_extend:DI
7192                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7193                                 (zero_extend:DI
7194                                   (match_operand:SI 2 "register_operand" "")))
7195                        (const_int 32))))
7196               (clobber (match_scratch:SI 3 ""))
7197               (clobber (reg:CC FLAGS_REG))])]
7198   ""
7199   "")
7201 (define_insn "*umulsi3_highpart_insn"
7202   [(set (match_operand:SI 0 "register_operand" "=d")
7203         (truncate:SI
7204           (lshiftrt:DI
7205             (mult:DI (zero_extend:DI
7206                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7207                      (zero_extend:DI
7208                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7209             (const_int 32))))
7210    (clobber (match_scratch:SI 3 "=1"))
7211    (clobber (reg:CC FLAGS_REG))]
7212   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7213   "mul{l}\t%2"
7214   [(set_attr "type" "imul")
7215    (set_attr "length_immediate" "0")
7216    (set (attr "athlon_decode")
7217      (if_then_else (eq_attr "cpu" "athlon")
7218         (const_string "vector")
7219         (const_string "double")))
7220    (set_attr "mode" "SI")])
7222 (define_insn "*umulsi3_highpart_zext"
7223   [(set (match_operand:DI 0 "register_operand" "=d")
7224         (zero_extend:DI (truncate:SI
7225           (lshiftrt:DI
7226             (mult:DI (zero_extend:DI
7227                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7228                      (zero_extend:DI
7229                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7230             (const_int 32)))))
7231    (clobber (match_scratch:SI 3 "=1"))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_64BIT
7234    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235   "mul{l}\t%2"
7236   [(set_attr "type" "imul")
7237    (set_attr "length_immediate" "0")
7238    (set (attr "athlon_decode")
7239      (if_then_else (eq_attr "cpu" "athlon")
7240         (const_string "vector")
7241         (const_string "double")))
7242    (set_attr "mode" "SI")])
7244 (define_expand "smuldi3_highpart"
7245   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7246                    (truncate:DI
7247                      (lshiftrt:TI
7248                        (mult:TI (sign_extend:TI
7249                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7250                                 (sign_extend:TI
7251                                   (match_operand:DI 2 "register_operand" "")))
7252                        (const_int 64))))
7253               (clobber (match_scratch:DI 3 ""))
7254               (clobber (reg:CC FLAGS_REG))])]
7255   "TARGET_64BIT"
7256   "")
7258 (define_insn "*smuldi3_highpart_rex64"
7259   [(set (match_operand:DI 0 "register_operand" "=d")
7260         (truncate:DI
7261           (lshiftrt:TI
7262             (mult:TI (sign_extend:TI
7263                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264                      (sign_extend:TI
7265                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266             (const_int 64))))
7267    (clobber (match_scratch:DI 3 "=1"))
7268    (clobber (reg:CC FLAGS_REG))]
7269   "TARGET_64BIT
7270    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271   "imul{q}\t%2"
7272   [(set_attr "type" "imul")
7273    (set (attr "athlon_decode")
7274      (if_then_else (eq_attr "cpu" "athlon")
7275         (const_string "vector")
7276         (const_string "double")))
7277    (set_attr "mode" "DI")])
7279 (define_expand "smulsi3_highpart"
7280   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7281                    (truncate:SI
7282                      (lshiftrt:DI
7283                        (mult:DI (sign_extend:DI
7284                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7285                                 (sign_extend:DI
7286                                   (match_operand:SI 2 "register_operand" "")))
7287                        (const_int 32))))
7288               (clobber (match_scratch:SI 3 ""))
7289               (clobber (reg:CC FLAGS_REG))])]
7290   ""
7291   "")
7293 (define_insn "*smulsi3_highpart_insn"
7294   [(set (match_operand:SI 0 "register_operand" "=d")
7295         (truncate:SI
7296           (lshiftrt:DI
7297             (mult:DI (sign_extend:DI
7298                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7299                      (sign_extend:DI
7300                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7301             (const_int 32))))
7302    (clobber (match_scratch:SI 3 "=1"))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7305   "imul{l}\t%2"
7306   [(set_attr "type" "imul")
7307    (set (attr "athlon_decode")
7308      (if_then_else (eq_attr "cpu" "athlon")
7309         (const_string "vector")
7310         (const_string "double")))
7311    (set_attr "mode" "SI")])
7313 (define_insn "*smulsi3_highpart_zext"
7314   [(set (match_operand:DI 0 "register_operand" "=d")
7315         (zero_extend:DI (truncate:SI
7316           (lshiftrt:DI
7317             (mult:DI (sign_extend:DI
7318                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7319                      (sign_extend:DI
7320                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7321             (const_int 32)))))
7322    (clobber (match_scratch:SI 3 "=1"))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_64BIT
7325    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7326   "imul{l}\t%2"
7327   [(set_attr "type" "imul")
7328    (set (attr "athlon_decode")
7329      (if_then_else (eq_attr "cpu" "athlon")
7330         (const_string "vector")
7331         (const_string "double")))
7332    (set_attr "mode" "SI")])
7334 ;; The patterns that match these are at the end of this file.
7336 (define_expand "mulxf3"
7337   [(set (match_operand:XF 0 "register_operand" "")
7338         (mult:XF (match_operand:XF 1 "register_operand" "")
7339                  (match_operand:XF 2 "register_operand" "")))]
7340   "TARGET_80387"
7341   "")
7343 (define_expand "muldf3"
7344   [(set (match_operand:DF 0 "register_operand" "")
7345         (mult:DF (match_operand:DF 1 "register_operand" "")
7346                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7347   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7348   "")
7350 (define_expand "mulsf3"
7351   [(set (match_operand:SF 0 "register_operand" "")
7352         (mult:SF (match_operand:SF 1 "register_operand" "")
7353                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7354   "TARGET_80387 || TARGET_SSE_MATH"
7355   "")
7357 ;; Divide instructions
7359 (define_insn "divqi3"
7360   [(set (match_operand:QI 0 "register_operand" "=a")
7361         (div:QI (match_operand:HI 1 "register_operand" "0")
7362                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_QIMODE_MATH"
7365   "idiv{b}\t%2"
7366   [(set_attr "type" "idiv")
7367    (set_attr "mode" "QI")])
7369 (define_insn "udivqi3"
7370   [(set (match_operand:QI 0 "register_operand" "=a")
7371         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7372                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7373    (clobber (reg:CC FLAGS_REG))]
7374   "TARGET_QIMODE_MATH"
7375   "div{b}\t%2"
7376   [(set_attr "type" "idiv")
7377    (set_attr "mode" "QI")])
7379 ;; The patterns that match these are at the end of this file.
7381 (define_expand "divxf3"
7382   [(set (match_operand:XF 0 "register_operand" "")
7383         (div:XF (match_operand:XF 1 "register_operand" "")
7384                 (match_operand:XF 2 "register_operand" "")))]
7385   "TARGET_80387"
7386   "")
7388 (define_expand "divdf3"
7389   [(set (match_operand:DF 0 "register_operand" "")
7390         (div:DF (match_operand:DF 1 "register_operand" "")
7391                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7392    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7393    "")
7395 (define_expand "divsf3"
7396   [(set (match_operand:SF 0 "register_operand" "")
7397         (div:SF (match_operand:SF 1 "register_operand" "")
7398                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7399   "TARGET_80387 || TARGET_SSE_MATH"
7400   "")
7402 ;; Remainder instructions.
7404 (define_expand "divmoddi4"
7405   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7406                    (div:DI (match_operand:DI 1 "register_operand" "")
7407                            (match_operand:DI 2 "nonimmediate_operand" "")))
7408               (set (match_operand:DI 3 "register_operand" "")
7409                    (mod:DI (match_dup 1) (match_dup 2)))
7410               (clobber (reg:CC FLAGS_REG))])]
7411   "TARGET_64BIT"
7412   "")
7414 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7415 ;; Penalize eax case slightly because it results in worse scheduling
7416 ;; of code.
7417 (define_insn "*divmoddi4_nocltd_rex64"
7418   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7419         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7420                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7421    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7422         (mod:DI (match_dup 2) (match_dup 3)))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7425   "#"
7426   [(set_attr "type" "multi")])
7428 (define_insn "*divmoddi4_cltd_rex64"
7429   [(set (match_operand:DI 0 "register_operand" "=a")
7430         (div:DI (match_operand:DI 2 "register_operand" "a")
7431                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7432    (set (match_operand:DI 1 "register_operand" "=&d")
7433         (mod:DI (match_dup 2) (match_dup 3)))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7436   "#"
7437   [(set_attr "type" "multi")])
7439 (define_insn "*divmoddi_noext_rex64"
7440   [(set (match_operand:DI 0 "register_operand" "=a")
7441         (div:DI (match_operand:DI 1 "register_operand" "0")
7442                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7443    (set (match_operand:DI 3 "register_operand" "=d")
7444         (mod:DI (match_dup 1) (match_dup 2)))
7445    (use (match_operand:DI 4 "register_operand" "3"))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_64BIT"
7448   "idiv{q}\t%2"
7449   [(set_attr "type" "idiv")
7450    (set_attr "mode" "DI")])
7452 (define_split
7453   [(set (match_operand:DI 0 "register_operand" "")
7454         (div:DI (match_operand:DI 1 "register_operand" "")
7455                 (match_operand:DI 2 "nonimmediate_operand" "")))
7456    (set (match_operand:DI 3 "register_operand" "")
7457         (mod:DI (match_dup 1) (match_dup 2)))
7458    (clobber (reg:CC FLAGS_REG))]
7459   "TARGET_64BIT && reload_completed"
7460   [(parallel [(set (match_dup 3)
7461                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7462               (clobber (reg:CC FLAGS_REG))])
7463    (parallel [(set (match_dup 0)
7464                    (div:DI (reg:DI 0) (match_dup 2)))
7465               (set (match_dup 3)
7466                    (mod:DI (reg:DI 0) (match_dup 2)))
7467               (use (match_dup 3))
7468               (clobber (reg:CC FLAGS_REG))])]
7470   /* Avoid use of cltd in favor of a mov+shift.  */
7471   if (!TARGET_USE_CLTD && !optimize_size)
7472     {
7473       if (true_regnum (operands[1]))
7474         emit_move_insn (operands[0], operands[1]);
7475       else
7476         emit_move_insn (operands[3], operands[1]);
7477       operands[4] = operands[3];
7478     }
7479   else
7480     {
7481       gcc_assert (!true_regnum (operands[1]));
7482       operands[4] = operands[1];
7483     }
7487 (define_expand "divmodsi4"
7488   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7489                    (div:SI (match_operand:SI 1 "register_operand" "")
7490                            (match_operand:SI 2 "nonimmediate_operand" "")))
7491               (set (match_operand:SI 3 "register_operand" "")
7492                    (mod:SI (match_dup 1) (match_dup 2)))
7493               (clobber (reg:CC FLAGS_REG))])]
7494   ""
7495   "")
7497 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7498 ;; Penalize eax case slightly because it results in worse scheduling
7499 ;; of code.
7500 (define_insn "*divmodsi4_nocltd"
7501   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7502         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7503                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7504    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7505         (mod:SI (match_dup 2) (match_dup 3)))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "!optimize_size && !TARGET_USE_CLTD"
7508   "#"
7509   [(set_attr "type" "multi")])
7511 (define_insn "*divmodsi4_cltd"
7512   [(set (match_operand:SI 0 "register_operand" "=a")
7513         (div:SI (match_operand:SI 2 "register_operand" "a")
7514                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7515    (set (match_operand:SI 1 "register_operand" "=&d")
7516         (mod:SI (match_dup 2) (match_dup 3)))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "optimize_size || TARGET_USE_CLTD"
7519   "#"
7520   [(set_attr "type" "multi")])
7522 (define_insn "*divmodsi_noext"
7523   [(set (match_operand:SI 0 "register_operand" "=a")
7524         (div:SI (match_operand:SI 1 "register_operand" "0")
7525                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7526    (set (match_operand:SI 3 "register_operand" "=d")
7527         (mod:SI (match_dup 1) (match_dup 2)))
7528    (use (match_operand:SI 4 "register_operand" "3"))
7529    (clobber (reg:CC FLAGS_REG))]
7530   ""
7531   "idiv{l}\t%2"
7532   [(set_attr "type" "idiv")
7533    (set_attr "mode" "SI")])
7535 (define_split
7536   [(set (match_operand:SI 0 "register_operand" "")
7537         (div:SI (match_operand:SI 1 "register_operand" "")
7538                 (match_operand:SI 2 "nonimmediate_operand" "")))
7539    (set (match_operand:SI 3 "register_operand" "")
7540         (mod:SI (match_dup 1) (match_dup 2)))
7541    (clobber (reg:CC FLAGS_REG))]
7542   "reload_completed"
7543   [(parallel [(set (match_dup 3)
7544                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7545               (clobber (reg:CC FLAGS_REG))])
7546    (parallel [(set (match_dup 0)
7547                    (div:SI (reg:SI 0) (match_dup 2)))
7548               (set (match_dup 3)
7549                    (mod:SI (reg:SI 0) (match_dup 2)))
7550               (use (match_dup 3))
7551               (clobber (reg:CC FLAGS_REG))])]
7553   /* Avoid use of cltd in favor of a mov+shift.  */
7554   if (!TARGET_USE_CLTD && !optimize_size)
7555     {
7556       if (true_regnum (operands[1]))
7557         emit_move_insn (operands[0], operands[1]);
7558       else
7559         emit_move_insn (operands[3], operands[1]);
7560       operands[4] = operands[3];
7561     }
7562   else
7563     {
7564       gcc_assert (!true_regnum (operands[1]));
7565       operands[4] = operands[1];
7566     }
7568 ;; %%% Split me.
7569 (define_insn "divmodhi4"
7570   [(set (match_operand:HI 0 "register_operand" "=a")
7571         (div:HI (match_operand:HI 1 "register_operand" "0")
7572                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7573    (set (match_operand:HI 3 "register_operand" "=&d")
7574         (mod:HI (match_dup 1) (match_dup 2)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "TARGET_HIMODE_MATH"
7577   "cwtd\;idiv{w}\t%2"
7578   [(set_attr "type" "multi")
7579    (set_attr "length_immediate" "0")
7580    (set_attr "mode" "SI")])
7582 (define_insn "udivmoddi4"
7583   [(set (match_operand:DI 0 "register_operand" "=a")
7584         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7585                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7586    (set (match_operand:DI 3 "register_operand" "=&d")
7587         (umod:DI (match_dup 1) (match_dup 2)))
7588    (clobber (reg:CC FLAGS_REG))]
7589   "TARGET_64BIT"
7590   "xor{q}\t%3, %3\;div{q}\t%2"
7591   [(set_attr "type" "multi")
7592    (set_attr "length_immediate" "0")
7593    (set_attr "mode" "DI")])
7595 (define_insn "*udivmoddi4_noext"
7596   [(set (match_operand:DI 0 "register_operand" "=a")
7597         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7598                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7599    (set (match_operand:DI 3 "register_operand" "=d")
7600         (umod:DI (match_dup 1) (match_dup 2)))
7601    (use (match_dup 3))
7602    (clobber (reg:CC FLAGS_REG))]
7603   "TARGET_64BIT"
7604   "div{q}\t%2"
7605   [(set_attr "type" "idiv")
7606    (set_attr "mode" "DI")])
7608 (define_split
7609   [(set (match_operand:DI 0 "register_operand" "")
7610         (udiv:DI (match_operand:DI 1 "register_operand" "")
7611                  (match_operand:DI 2 "nonimmediate_operand" "")))
7612    (set (match_operand:DI 3 "register_operand" "")
7613         (umod:DI (match_dup 1) (match_dup 2)))
7614    (clobber (reg:CC FLAGS_REG))]
7615   "TARGET_64BIT && reload_completed"
7616   [(set (match_dup 3) (const_int 0))
7617    (parallel [(set (match_dup 0)
7618                    (udiv:DI (match_dup 1) (match_dup 2)))
7619               (set (match_dup 3)
7620                    (umod:DI (match_dup 1) (match_dup 2)))
7621               (use (match_dup 3))
7622               (clobber (reg:CC FLAGS_REG))])]
7623   "")
7625 (define_insn "udivmodsi4"
7626   [(set (match_operand:SI 0 "register_operand" "=a")
7627         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7628                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7629    (set (match_operand:SI 3 "register_operand" "=&d")
7630         (umod:SI (match_dup 1) (match_dup 2)))
7631    (clobber (reg:CC FLAGS_REG))]
7632   ""
7633   "xor{l}\t%3, %3\;div{l}\t%2"
7634   [(set_attr "type" "multi")
7635    (set_attr "length_immediate" "0")
7636    (set_attr "mode" "SI")])
7638 (define_insn "*udivmodsi4_noext"
7639   [(set (match_operand:SI 0 "register_operand" "=a")
7640         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7641                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7642    (set (match_operand:SI 3 "register_operand" "=d")
7643         (umod:SI (match_dup 1) (match_dup 2)))
7644    (use (match_dup 3))
7645    (clobber (reg:CC FLAGS_REG))]
7646   ""
7647   "div{l}\t%2"
7648   [(set_attr "type" "idiv")
7649    (set_attr "mode" "SI")])
7651 (define_split
7652   [(set (match_operand:SI 0 "register_operand" "")
7653         (udiv:SI (match_operand:SI 1 "register_operand" "")
7654                  (match_operand:SI 2 "nonimmediate_operand" "")))
7655    (set (match_operand:SI 3 "register_operand" "")
7656         (umod:SI (match_dup 1) (match_dup 2)))
7657    (clobber (reg:CC FLAGS_REG))]
7658   "reload_completed"
7659   [(set (match_dup 3) (const_int 0))
7660    (parallel [(set (match_dup 0)
7661                    (udiv:SI (match_dup 1) (match_dup 2)))
7662               (set (match_dup 3)
7663                    (umod:SI (match_dup 1) (match_dup 2)))
7664               (use (match_dup 3))
7665               (clobber (reg:CC FLAGS_REG))])]
7666   "")
7668 (define_expand "udivmodhi4"
7669   [(set (match_dup 4) (const_int 0))
7670    (parallel [(set (match_operand:HI 0 "register_operand" "")
7671                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7672                             (match_operand:HI 2 "nonimmediate_operand" "")))
7673               (set (match_operand:HI 3 "register_operand" "")
7674                    (umod:HI (match_dup 1) (match_dup 2)))
7675               (use (match_dup 4))
7676               (clobber (reg:CC FLAGS_REG))])]
7677   "TARGET_HIMODE_MATH"
7678   "operands[4] = gen_reg_rtx (HImode);")
7680 (define_insn "*udivmodhi_noext"
7681   [(set (match_operand:HI 0 "register_operand" "=a")
7682         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7683                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7684    (set (match_operand:HI 3 "register_operand" "=d")
7685         (umod:HI (match_dup 1) (match_dup 2)))
7686    (use (match_operand:HI 4 "register_operand" "3"))
7687    (clobber (reg:CC FLAGS_REG))]
7688   ""
7689   "div{w}\t%2"
7690   [(set_attr "type" "idiv")
7691    (set_attr "mode" "HI")])
7693 ;; We cannot use div/idiv for double division, because it causes
7694 ;; "division by zero" on the overflow and that's not what we expect
7695 ;; from truncate.  Because true (non truncating) double division is
7696 ;; never generated, we can't create this insn anyway.
7698 ;(define_insn ""
7699 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7700 ;       (truncate:SI
7701 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7702 ;                  (zero_extend:DI
7703 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7704 ;   (set (match_operand:SI 3 "register_operand" "=d")
7705 ;       (truncate:SI
7706 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7707 ;   (clobber (reg:CC FLAGS_REG))]
7708 ;  ""
7709 ;  "div{l}\t{%2, %0|%0, %2}"
7710 ;  [(set_attr "type" "idiv")])
7712 ;;- Logical AND instructions
7714 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7715 ;; Note that this excludes ah.
7717 (define_insn "*testdi_1_rex64"
7718   [(set (reg FLAGS_REG)
7719         (compare
7720           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7721                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7722           (const_int 0)))]
7723   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7724    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7725   "@
7726    test{l}\t{%k1, %k0|%k0, %k1}
7727    test{l}\t{%k1, %k0|%k0, %k1}
7728    test{q}\t{%1, %0|%0, %1}
7729    test{q}\t{%1, %0|%0, %1}
7730    test{q}\t{%1, %0|%0, %1}"
7731   [(set_attr "type" "test")
7732    (set_attr "modrm" "0,1,0,1,1")
7733    (set_attr "mode" "SI,SI,DI,DI,DI")
7734    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7736 (define_insn "testsi_1"
7737   [(set (reg FLAGS_REG)
7738         (compare
7739           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7740                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7741           (const_int 0)))]
7742   "ix86_match_ccmode (insn, CCNOmode)
7743    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7744   "test{l}\t{%1, %0|%0, %1}"
7745   [(set_attr "type" "test")
7746    (set_attr "modrm" "0,1,1")
7747    (set_attr "mode" "SI")
7748    (set_attr "pent_pair" "uv,np,uv")])
7750 (define_expand "testsi_ccno_1"
7751   [(set (reg:CCNO FLAGS_REG)
7752         (compare:CCNO
7753           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7754                   (match_operand:SI 1 "nonmemory_operand" ""))
7755           (const_int 0)))]
7756   ""
7757   "")
7759 (define_insn "*testhi_1"
7760   [(set (reg FLAGS_REG)
7761         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7762                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7763                  (const_int 0)))]
7764   "ix86_match_ccmode (insn, CCNOmode)
7765    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7766   "test{w}\t{%1, %0|%0, %1}"
7767   [(set_attr "type" "test")
7768    (set_attr "modrm" "0,1,1")
7769    (set_attr "mode" "HI")
7770    (set_attr "pent_pair" "uv,np,uv")])
7772 (define_expand "testqi_ccz_1"
7773   [(set (reg:CCZ FLAGS_REG)
7774         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7775                              (match_operand:QI 1 "nonmemory_operand" ""))
7776                  (const_int 0)))]
7777   ""
7778   "")
7780 (define_insn "*testqi_1_maybe_si"
7781   [(set (reg FLAGS_REG)
7782         (compare
7783           (and:QI
7784             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7785             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7786           (const_int 0)))]
7787    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7788     && ix86_match_ccmode (insn,
7789                          GET_CODE (operands[1]) == CONST_INT
7790                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7792   if (which_alternative == 3)
7793     {
7794       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7795         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7796       return "test{l}\t{%1, %k0|%k0, %1}";
7797     }
7798   return "test{b}\t{%1, %0|%0, %1}";
7800   [(set_attr "type" "test")
7801    (set_attr "modrm" "0,1,1,1")
7802    (set_attr "mode" "QI,QI,QI,SI")
7803    (set_attr "pent_pair" "uv,np,uv,np")])
7805 (define_insn "*testqi_1"
7806   [(set (reg FLAGS_REG)
7807         (compare
7808           (and:QI
7809             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7810             (match_operand:QI 1 "general_operand" "n,n,qn"))
7811           (const_int 0)))]
7812   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7813    && ix86_match_ccmode (insn, CCNOmode)"
7814   "test{b}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "QI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7820 (define_expand "testqi_ext_ccno_0"
7821   [(set (reg:CCNO FLAGS_REG)
7822         (compare:CCNO
7823           (and:SI
7824             (zero_extract:SI
7825               (match_operand 0 "ext_register_operand" "")
7826               (const_int 8)
7827               (const_int 8))
7828             (match_operand 1 "const_int_operand" ""))
7829           (const_int 0)))]
7830   ""
7831   "")
7833 (define_insn "*testqi_ext_0"
7834   [(set (reg FLAGS_REG)
7835         (compare
7836           (and:SI
7837             (zero_extract:SI
7838               (match_operand 0 "ext_register_operand" "Q")
7839               (const_int 8)
7840               (const_int 8))
7841             (match_operand 1 "const_int_operand" "n"))
7842           (const_int 0)))]
7843   "ix86_match_ccmode (insn, CCNOmode)"
7844   "test{b}\t{%1, %h0|%h0, %1}"
7845   [(set_attr "type" "test")
7846    (set_attr "mode" "QI")
7847    (set_attr "length_immediate" "1")
7848    (set_attr "pent_pair" "np")])
7850 (define_insn "*testqi_ext_1"
7851   [(set (reg FLAGS_REG)
7852         (compare
7853           (and:SI
7854             (zero_extract:SI
7855               (match_operand 0 "ext_register_operand" "Q")
7856               (const_int 8)
7857               (const_int 8))
7858             (zero_extend:SI
7859               (match_operand:QI 1 "general_operand" "Qm")))
7860           (const_int 0)))]
7861   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7862    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7863   "test{b}\t{%1, %h0|%h0, %1}"
7864   [(set_attr "type" "test")
7865    (set_attr "mode" "QI")])
7867 (define_insn "*testqi_ext_1_rex64"
7868   [(set (reg FLAGS_REG)
7869         (compare
7870           (and:SI
7871             (zero_extract:SI
7872               (match_operand 0 "ext_register_operand" "Q")
7873               (const_int 8)
7874               (const_int 8))
7875             (zero_extend:SI
7876               (match_operand:QI 1 "register_operand" "Q")))
7877           (const_int 0)))]
7878   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7879   "test{b}\t{%1, %h0|%h0, %1}"
7880   [(set_attr "type" "test")
7881    (set_attr "mode" "QI")])
7883 (define_insn "*testqi_ext_2"
7884   [(set (reg FLAGS_REG)
7885         (compare
7886           (and:SI
7887             (zero_extract:SI
7888               (match_operand 0 "ext_register_operand" "Q")
7889               (const_int 8)
7890               (const_int 8))
7891             (zero_extract:SI
7892               (match_operand 1 "ext_register_operand" "Q")
7893               (const_int 8)
7894               (const_int 8)))
7895           (const_int 0)))]
7896   "ix86_match_ccmode (insn, CCNOmode)"
7897   "test{b}\t{%h1, %h0|%h0, %h1}"
7898   [(set_attr "type" "test")
7899    (set_attr "mode" "QI")])
7901 ;; Combine likes to form bit extractions for some tests.  Humor it.
7902 (define_insn "*testqi_ext_3"
7903   [(set (reg FLAGS_REG)
7904         (compare (zero_extract:SI
7905                    (match_operand 0 "nonimmediate_operand" "rm")
7906                    (match_operand:SI 1 "const_int_operand" "")
7907                    (match_operand:SI 2 "const_int_operand" ""))
7908                  (const_int 0)))]
7909   "ix86_match_ccmode (insn, CCNOmode)
7910    && INTVAL (operands[1]) > 0
7911    && INTVAL (operands[2]) >= 0
7912    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7913    && (GET_MODE (operands[0]) == SImode
7914        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7915        || GET_MODE (operands[0]) == HImode
7916        || GET_MODE (operands[0]) == QImode)"
7917   "#")
7919 (define_insn "*testqi_ext_3_rex64"
7920   [(set (reg FLAGS_REG)
7921         (compare (zero_extract:DI
7922                    (match_operand 0 "nonimmediate_operand" "rm")
7923                    (match_operand:DI 1 "const_int_operand" "")
7924                    (match_operand:DI 2 "const_int_operand" ""))
7925                  (const_int 0)))]
7926   "TARGET_64BIT
7927    && ix86_match_ccmode (insn, CCNOmode)
7928    && INTVAL (operands[1]) > 0
7929    && INTVAL (operands[2]) >= 0
7930    /* Ensure that resulting mask is zero or sign extended operand.  */
7931    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7932        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7933            && INTVAL (operands[1]) > 32))
7934    && (GET_MODE (operands[0]) == SImode
7935        || GET_MODE (operands[0]) == DImode
7936        || GET_MODE (operands[0]) == HImode
7937        || GET_MODE (operands[0]) == QImode)"
7938   "#")
7940 (define_split
7941   [(set (match_operand 0 "flags_reg_operand" "")
7942         (match_operator 1 "compare_operator"
7943           [(zero_extract
7944              (match_operand 2 "nonimmediate_operand" "")
7945              (match_operand 3 "const_int_operand" "")
7946              (match_operand 4 "const_int_operand" ""))
7947            (const_int 0)]))]
7948   "ix86_match_ccmode (insn, CCNOmode)"
7949   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7951   rtx val = operands[2];
7952   HOST_WIDE_INT len = INTVAL (operands[3]);
7953   HOST_WIDE_INT pos = INTVAL (operands[4]);
7954   HOST_WIDE_INT mask;
7955   enum machine_mode mode, submode;
7957   mode = GET_MODE (val);
7958   if (GET_CODE (val) == MEM)
7959     {
7960       /* ??? Combine likes to put non-volatile mem extractions in QImode
7961          no matter the size of the test.  So find a mode that works.  */
7962       if (! MEM_VOLATILE_P (val))
7963         {
7964           mode = smallest_mode_for_size (pos + len, MODE_INT);
7965           val = adjust_address (val, mode, 0);
7966         }
7967     }
7968   else if (GET_CODE (val) == SUBREG
7969            && (submode = GET_MODE (SUBREG_REG (val)),
7970                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7971            && pos + len <= GET_MODE_BITSIZE (submode))
7972     {
7973       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7974       mode = submode;
7975       val = SUBREG_REG (val);
7976     }
7977   else if (mode == HImode && pos + len <= 8)
7978     {
7979       /* Small HImode tests can be converted to QImode.  */
7980       mode = QImode;
7981       val = gen_lowpart (QImode, val);
7982     }
7984   if (len == HOST_BITS_PER_WIDE_INT)
7985     mask = -1;
7986   else
7987     mask = ((HOST_WIDE_INT)1 << len) - 1;
7988   mask <<= pos;
7990   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7993 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7994 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7995 ;; this is relatively important trick.
7996 ;; Do the conversion only post-reload to avoid limiting of the register class
7997 ;; to QI regs.
7998 (define_split
7999   [(set (match_operand 0 "flags_reg_operand" "")
8000         (match_operator 1 "compare_operator"
8001           [(and (match_operand 2 "register_operand" "")
8002                 (match_operand 3 "const_int_operand" ""))
8003            (const_int 0)]))]
8004    "reload_completed
8005     && QI_REG_P (operands[2])
8006     && GET_MODE (operands[2]) != QImode
8007     && ((ix86_match_ccmode (insn, CCZmode)
8008          && !(INTVAL (operands[3]) & ~(255 << 8)))
8009         || (ix86_match_ccmode (insn, CCNOmode)
8010             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8011   [(set (match_dup 0)
8012         (match_op_dup 1
8013           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8014                    (match_dup 3))
8015            (const_int 0)]))]
8016   "operands[2] = gen_lowpart (SImode, operands[2]);
8017    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8019 (define_split
8020   [(set (match_operand 0 "flags_reg_operand" "")
8021         (match_operator 1 "compare_operator"
8022           [(and (match_operand 2 "nonimmediate_operand" "")
8023                 (match_operand 3 "const_int_operand" ""))
8024            (const_int 0)]))]
8025    "reload_completed
8026     && GET_MODE (operands[2]) != QImode
8027     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8028     && ((ix86_match_ccmode (insn, CCZmode)
8029          && !(INTVAL (operands[3]) & ~255))
8030         || (ix86_match_ccmode (insn, CCNOmode)
8031             && !(INTVAL (operands[3]) & ~127)))"
8032   [(set (match_dup 0)
8033         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8034                          (const_int 0)]))]
8035   "operands[2] = gen_lowpart (QImode, operands[2]);
8036    operands[3] = gen_lowpart (QImode, operands[3]);")
8039 ;; %%% This used to optimize known byte-wide and operations to memory,
8040 ;; and sometimes to QImode registers.  If this is considered useful,
8041 ;; it should be done with splitters.
8043 (define_expand "anddi3"
8044   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8045         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8046                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT"
8049   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8051 (define_insn "*anddi_1_rex64"
8052   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8053         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8054                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8058   switch (get_attr_type (insn))
8059     {
8060     case TYPE_IMOVX:
8061       {
8062         enum machine_mode mode;
8064         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8065         if (INTVAL (operands[2]) == 0xff)
8066           mode = QImode;
8067         else
8068           {
8069             gcc_assert (INTVAL (operands[2]) == 0xffff);
8070             mode = HImode;
8071           }
8072         
8073         operands[1] = gen_lowpart (mode, operands[1]);
8074         if (mode == QImode)
8075           return "movz{bq|x}\t{%1,%0|%0, %1}";
8076         else
8077           return "movz{wq|x}\t{%1,%0|%0, %1}";
8078       }
8080     default:
8081       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8082       if (get_attr_mode (insn) == MODE_SI)
8083         return "and{l}\t{%k2, %k0|%k0, %k2}";
8084       else
8085         return "and{q}\t{%2, %0|%0, %2}";
8086     }
8088   [(set_attr "type" "alu,alu,alu,imovx")
8089    (set_attr "length_immediate" "*,*,*,0")
8090    (set_attr "mode" "SI,DI,DI,DI")])
8092 (define_insn "*anddi_2"
8093   [(set (reg FLAGS_REG)
8094         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8095                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8096                  (const_int 0)))
8097    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8098         (and:DI (match_dup 1) (match_dup 2)))]
8099   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8100    && ix86_binary_operator_ok (AND, DImode, operands)"
8101   "@
8102    and{l}\t{%k2, %k0|%k0, %k2}
8103    and{q}\t{%2, %0|%0, %2}
8104    and{q}\t{%2, %0|%0, %2}"
8105   [(set_attr "type" "alu")
8106    (set_attr "mode" "SI,DI,DI")])
8108 (define_expand "andsi3"
8109   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8110         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8111                 (match_operand:SI 2 "general_operand" "")))
8112    (clobber (reg:CC FLAGS_REG))]
8113   ""
8114   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8116 (define_insn "*andsi_1"
8117   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8118         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8119                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8120    (clobber (reg:CC FLAGS_REG))]
8121   "ix86_binary_operator_ok (AND, SImode, operands)"
8123   switch (get_attr_type (insn))
8124     {
8125     case TYPE_IMOVX:
8126       {
8127         enum machine_mode mode;
8129         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8130         if (INTVAL (operands[2]) == 0xff)
8131           mode = QImode;
8132         else
8133           {
8134             gcc_assert (INTVAL (operands[2]) == 0xffff);
8135             mode = HImode;
8136           }
8137         
8138         operands[1] = gen_lowpart (mode, operands[1]);
8139         if (mode == QImode)
8140           return "movz{bl|x}\t{%1,%0|%0, %1}";
8141         else
8142           return "movz{wl|x}\t{%1,%0|%0, %1}";
8143       }
8145     default:
8146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8147       return "and{l}\t{%2, %0|%0, %2}";
8148     }
8150   [(set_attr "type" "alu,alu,imovx")
8151    (set_attr "length_immediate" "*,*,0")
8152    (set_attr "mode" "SI")])
8154 (define_split
8155   [(set (match_operand 0 "register_operand" "")
8156         (and (match_dup 0)
8157              (const_int -65536)))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8160   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8161   "operands[1] = gen_lowpart (HImode, operands[0]);")
8163 (define_split
8164   [(set (match_operand 0 "ext_register_operand" "")
8165         (and (match_dup 0)
8166              (const_int -256)))
8167    (clobber (reg:CC FLAGS_REG))]
8168   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8169   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8170   "operands[1] = gen_lowpart (QImode, operands[0]);")
8172 (define_split
8173   [(set (match_operand 0 "ext_register_operand" "")
8174         (and (match_dup 0)
8175              (const_int -65281)))
8176    (clobber (reg:CC FLAGS_REG))]
8177   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8178   [(parallel [(set (zero_extract:SI (match_dup 0)
8179                                     (const_int 8)
8180                                     (const_int 8))
8181                    (xor:SI 
8182                      (zero_extract:SI (match_dup 0)
8183                                       (const_int 8)
8184                                       (const_int 8))
8185                      (zero_extract:SI (match_dup 0)
8186                                       (const_int 8)
8187                                       (const_int 8))))
8188               (clobber (reg:CC FLAGS_REG))])]
8189   "operands[0] = gen_lowpart (SImode, operands[0]);")
8191 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8192 (define_insn "*andsi_1_zext"
8193   [(set (match_operand:DI 0 "register_operand" "=r")
8194         (zero_extend:DI
8195           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8196                   (match_operand:SI 2 "general_operand" "rim"))))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8199   "and{l}\t{%2, %k0|%k0, %2}"
8200   [(set_attr "type" "alu")
8201    (set_attr "mode" "SI")])
8203 (define_insn "*andsi_2"
8204   [(set (reg FLAGS_REG)
8205         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8206                          (match_operand:SI 2 "general_operand" "rim,ri"))
8207                  (const_int 0)))
8208    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8209         (and:SI (match_dup 1) (match_dup 2)))]
8210   "ix86_match_ccmode (insn, CCNOmode)
8211    && ix86_binary_operator_ok (AND, SImode, operands)"
8212   "and{l}\t{%2, %0|%0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "mode" "SI")])
8216 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8217 (define_insn "*andsi_2_zext"
8218   [(set (reg FLAGS_REG)
8219         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8220                          (match_operand:SI 2 "general_operand" "rim"))
8221                  (const_int 0)))
8222    (set (match_operand:DI 0 "register_operand" "=r")
8223         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8224   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8225    && ix86_binary_operator_ok (AND, SImode, operands)"
8226   "and{l}\t{%2, %k0|%k0, %2}"
8227   [(set_attr "type" "alu")
8228    (set_attr "mode" "SI")])
8230 (define_expand "andhi3"
8231   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8232         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8233                 (match_operand:HI 2 "general_operand" "")))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "TARGET_HIMODE_MATH"
8236   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8238 (define_insn "*andhi_1"
8239   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8240         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8241                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "ix86_binary_operator_ok (AND, HImode, operands)"
8245   switch (get_attr_type (insn))
8246     {
8247     case TYPE_IMOVX:
8248       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8249       gcc_assert (INTVAL (operands[2]) == 0xff);
8250       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8252     default:
8253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8255       return "and{w}\t{%2, %0|%0, %2}";
8256     }
8258   [(set_attr "type" "alu,alu,imovx")
8259    (set_attr "length_immediate" "*,*,0")
8260    (set_attr "mode" "HI,HI,SI")])
8262 (define_insn "*andhi_2"
8263   [(set (reg FLAGS_REG)
8264         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8265                          (match_operand:HI 2 "general_operand" "rim,ri"))
8266                  (const_int 0)))
8267    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8268         (and:HI (match_dup 1) (match_dup 2)))]
8269   "ix86_match_ccmode (insn, CCNOmode)
8270    && ix86_binary_operator_ok (AND, HImode, operands)"
8271   "and{w}\t{%2, %0|%0, %2}"
8272   [(set_attr "type" "alu")
8273    (set_attr "mode" "HI")])
8275 (define_expand "andqi3"
8276   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8277         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8278                 (match_operand:QI 2 "general_operand" "")))
8279    (clobber (reg:CC FLAGS_REG))]
8280   "TARGET_QIMODE_MATH"
8281   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8283 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8284 (define_insn "*andqi_1"
8285   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8286         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8287                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "ix86_binary_operator_ok (AND, QImode, operands)"
8290   "@
8291    and{b}\t{%2, %0|%0, %2}
8292    and{b}\t{%2, %0|%0, %2}
8293    and{l}\t{%k2, %k0|%k0, %k2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "QI,QI,SI")])
8297 (define_insn "*andqi_1_slp"
8298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8299         (and:QI (match_dup 0)
8300                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8303    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8304   "and{b}\t{%1, %0|%0, %1}"
8305   [(set_attr "type" "alu1")
8306    (set_attr "mode" "QI")])
8308 (define_insn "*andqi_2_maybe_si"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:QI
8311                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8312                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8313                  (const_int 0)))
8314    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8315         (and:QI (match_dup 1) (match_dup 2)))]
8316   "ix86_binary_operator_ok (AND, QImode, operands)
8317    && ix86_match_ccmode (insn,
8318                          GET_CODE (operands[2]) == CONST_INT
8319                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8321   if (which_alternative == 2)
8322     {
8323       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8324         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8325       return "and{l}\t{%2, %k0|%k0, %2}";
8326     }
8327   return "and{b}\t{%2, %0|%0, %2}";
8329   [(set_attr "type" "alu")
8330    (set_attr "mode" "QI,QI,SI")])
8332 (define_insn "*andqi_2"
8333   [(set (reg FLAGS_REG)
8334         (compare (and:QI
8335                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8336                    (match_operand:QI 2 "general_operand" "qim,qi"))
8337                  (const_int 0)))
8338    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8339         (and:QI (match_dup 1) (match_dup 2)))]
8340   "ix86_match_ccmode (insn, CCNOmode)
8341    && ix86_binary_operator_ok (AND, QImode, operands)"
8342   "and{b}\t{%2, %0|%0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "mode" "QI")])
8346 (define_insn "*andqi_2_slp"
8347   [(set (reg FLAGS_REG)
8348         (compare (and:QI
8349                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8350                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8351                  (const_int 0)))
8352    (set (strict_low_part (match_dup 0))
8353         (and:QI (match_dup 0) (match_dup 1)))]
8354   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8355    && ix86_match_ccmode (insn, CCNOmode)
8356    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8357   "and{b}\t{%1, %0|%0, %1}"
8358   [(set_attr "type" "alu1")
8359    (set_attr "mode" "QI")])
8361 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8362 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8363 ;; for a QImode operand, which of course failed.
8365 (define_insn "andqi_ext_0"
8366   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8367                          (const_int 8)
8368                          (const_int 8))
8369         (and:SI 
8370           (zero_extract:SI
8371             (match_operand 1 "ext_register_operand" "0")
8372             (const_int 8)
8373             (const_int 8))
8374           (match_operand 2 "const_int_operand" "n")))
8375    (clobber (reg:CC FLAGS_REG))]
8376   ""
8377   "and{b}\t{%2, %h0|%h0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "1")
8380    (set_attr "mode" "QI")])
8382 ;; Generated by peephole translating test to and.  This shows up
8383 ;; often in fp comparisons.
8385 (define_insn "*andqi_ext_0_cc"
8386   [(set (reg FLAGS_REG)
8387         (compare
8388           (and:SI
8389             (zero_extract:SI
8390               (match_operand 1 "ext_register_operand" "0")
8391               (const_int 8)
8392               (const_int 8))
8393             (match_operand 2 "const_int_operand" "n"))
8394           (const_int 0)))
8395    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396                          (const_int 8)
8397                          (const_int 8))
8398         (and:SI 
8399           (zero_extract:SI
8400             (match_dup 1)
8401             (const_int 8)
8402             (const_int 8))
8403           (match_dup 2)))]
8404   "ix86_match_ccmode (insn, CCNOmode)"
8405   "and{b}\t{%2, %h0|%h0, %2}"
8406   [(set_attr "type" "alu")
8407    (set_attr "length_immediate" "1")
8408    (set_attr "mode" "QI")])
8410 (define_insn "*andqi_ext_1"
8411   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8412                          (const_int 8)
8413                          (const_int 8))
8414         (and:SI 
8415           (zero_extract:SI
8416             (match_operand 1 "ext_register_operand" "0")
8417             (const_int 8)
8418             (const_int 8))
8419           (zero_extend:SI
8420             (match_operand:QI 2 "general_operand" "Qm"))))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "!TARGET_64BIT"
8423   "and{b}\t{%2, %h0|%h0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "0")
8426    (set_attr "mode" "QI")])
8428 (define_insn "*andqi_ext_1_rex64"
8429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8430                          (const_int 8)
8431                          (const_int 8))
8432         (and:SI 
8433           (zero_extract:SI
8434             (match_operand 1 "ext_register_operand" "0")
8435             (const_int 8)
8436             (const_int 8))
8437           (zero_extend:SI
8438             (match_operand 2 "ext_register_operand" "Q"))))
8439    (clobber (reg:CC FLAGS_REG))]
8440   "TARGET_64BIT"
8441   "and{b}\t{%2, %h0|%h0, %2}"
8442   [(set_attr "type" "alu")
8443    (set_attr "length_immediate" "0")
8444    (set_attr "mode" "QI")])
8446 (define_insn "*andqi_ext_2"
8447   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8448                          (const_int 8)
8449                          (const_int 8))
8450         (and:SI
8451           (zero_extract:SI
8452             (match_operand 1 "ext_register_operand" "%0")
8453             (const_int 8)
8454             (const_int 8))
8455           (zero_extract:SI
8456             (match_operand 2 "ext_register_operand" "Q")
8457             (const_int 8)
8458             (const_int 8))))
8459    (clobber (reg:CC FLAGS_REG))]
8460   ""
8461   "and{b}\t{%h2, %h0|%h0, %h2}"
8462   [(set_attr "type" "alu")
8463    (set_attr "length_immediate" "0")
8464    (set_attr "mode" "QI")])
8466 ;; Convert wide AND instructions with immediate operand to shorter QImode
8467 ;; equivalents when possible.
8468 ;; Don't do the splitting with memory operands, since it introduces risk
8469 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8470 ;; for size, but that can (should?) be handled by generic code instead.
8471 (define_split
8472   [(set (match_operand 0 "register_operand" "")
8473         (and (match_operand 1 "register_operand" "")
8474              (match_operand 2 "const_int_operand" "")))
8475    (clobber (reg:CC FLAGS_REG))]
8476    "reload_completed
8477     && QI_REG_P (operands[0])
8478     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8479     && !(~INTVAL (operands[2]) & ~(255 << 8))
8480     && GET_MODE (operands[0]) != QImode"
8481   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8482                    (and:SI (zero_extract:SI (match_dup 1)
8483                                             (const_int 8) (const_int 8))
8484                            (match_dup 2)))
8485               (clobber (reg:CC FLAGS_REG))])]
8486   "operands[0] = gen_lowpart (SImode, operands[0]);
8487    operands[1] = gen_lowpart (SImode, operands[1]);
8488    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8490 ;; Since AND can be encoded with sign extended immediate, this is only
8491 ;; profitable when 7th bit is not set.
8492 (define_split
8493   [(set (match_operand 0 "register_operand" "")
8494         (and (match_operand 1 "general_operand" "")
8495              (match_operand 2 "const_int_operand" "")))
8496    (clobber (reg:CC FLAGS_REG))]
8497    "reload_completed
8498     && ANY_QI_REG_P (operands[0])
8499     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8500     && !(~INTVAL (operands[2]) & ~255)
8501     && !(INTVAL (operands[2]) & 128)
8502     && GET_MODE (operands[0]) != QImode"
8503   [(parallel [(set (strict_low_part (match_dup 0))
8504                    (and:QI (match_dup 1)
8505                            (match_dup 2)))
8506               (clobber (reg:CC FLAGS_REG))])]
8507   "operands[0] = gen_lowpart (QImode, operands[0]);
8508    operands[1] = gen_lowpart (QImode, operands[1]);
8509    operands[2] = gen_lowpart (QImode, operands[2]);")
8511 ;; Logical inclusive OR instructions
8513 ;; %%% This used to optimize known byte-wide and operations to memory.
8514 ;; If this is considered useful, it should be done with splitters.
8516 (define_expand "iordi3"
8517   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8518         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8519                 (match_operand:DI 2 "x86_64_general_operand" "")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT"
8522   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8524 (define_insn "*iordi_1_rex64"
8525   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8526         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8527                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_64BIT
8530    && ix86_binary_operator_ok (IOR, DImode, operands)"
8531   "or{q}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "DI")])
8535 (define_insn "*iordi_2_rex64"
8536   [(set (reg FLAGS_REG)
8537         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8538                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8539                  (const_int 0)))
8540    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8541         (ior:DI (match_dup 1) (match_dup 2)))]
8542   "TARGET_64BIT
8543    && ix86_match_ccmode (insn, CCNOmode)
8544    && ix86_binary_operator_ok (IOR, DImode, operands)"
8545   "or{q}\t{%2, %0|%0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "DI")])
8549 (define_insn "*iordi_3_rex64"
8550   [(set (reg FLAGS_REG)
8551         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8552                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8553                  (const_int 0)))
8554    (clobber (match_scratch:DI 0 "=r"))]
8555   "TARGET_64BIT
8556    && ix86_match_ccmode (insn, CCNOmode)
8557    && ix86_binary_operator_ok (IOR, DImode, operands)"
8558   "or{q}\t{%2, %0|%0, %2}"
8559   [(set_attr "type" "alu")
8560    (set_attr "mode" "DI")])
8563 (define_expand "iorsi3"
8564   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8565         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8566                 (match_operand:SI 2 "general_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   ""
8569   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8571 (define_insn "*iorsi_1"
8572   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8573         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8574                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "ix86_binary_operator_ok (IOR, SImode, operands)"
8577   "or{l}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*iorsi_1_zext"
8583   [(set (match_operand:DI 0 "register_operand" "=rm")
8584         (zero_extend:DI
8585           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8586                   (match_operand:SI 2 "general_operand" "rim"))))
8587    (clobber (reg:CC FLAGS_REG))]
8588   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8589   "or{l}\t{%2, %k0|%k0, %2}"
8590   [(set_attr "type" "alu")
8591    (set_attr "mode" "SI")])
8593 (define_insn "*iorsi_1_zext_imm"
8594   [(set (match_operand:DI 0 "register_operand" "=rm")
8595         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8596                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "TARGET_64BIT"
8599   "or{l}\t{%2, %k0|%k0, %2}"
8600   [(set_attr "type" "alu")
8601    (set_attr "mode" "SI")])
8603 (define_insn "*iorsi_2"
8604   [(set (reg FLAGS_REG)
8605         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8606                          (match_operand:SI 2 "general_operand" "rim,ri"))
8607                  (const_int 0)))
8608    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8609         (ior:SI (match_dup 1) (match_dup 2)))]
8610   "ix86_match_ccmode (insn, CCNOmode)
8611    && ix86_binary_operator_ok (IOR, SImode, operands)"
8612   "or{l}\t{%2, %0|%0, %2}"
8613   [(set_attr "type" "alu")
8614    (set_attr "mode" "SI")])
8616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8617 ;; ??? Special case for immediate operand is missing - it is tricky.
8618 (define_insn "*iorsi_2_zext"
8619   [(set (reg FLAGS_REG)
8620         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8621                          (match_operand:SI 2 "general_operand" "rim"))
8622                  (const_int 0)))
8623    (set (match_operand:DI 0 "register_operand" "=r")
8624         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8625   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8626    && ix86_binary_operator_ok (IOR, SImode, operands)"
8627   "or{l}\t{%2, %k0|%k0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "mode" "SI")])
8631 (define_insn "*iorsi_2_zext_imm"
8632   [(set (reg FLAGS_REG)
8633         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8635                  (const_int 0)))
8636    (set (match_operand:DI 0 "register_operand" "=r")
8637         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8638   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8639    && ix86_binary_operator_ok (IOR, SImode, operands)"
8640   "or{l}\t{%2, %k0|%k0, %2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "mode" "SI")])
8644 (define_insn "*iorsi_3"
8645   [(set (reg FLAGS_REG)
8646         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8647                          (match_operand:SI 2 "general_operand" "rim"))
8648                  (const_int 0)))
8649    (clobber (match_scratch:SI 0 "=r"))]
8650   "ix86_match_ccmode (insn, CCNOmode)
8651    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8652   "or{l}\t{%2, %0|%0, %2}"
8653   [(set_attr "type" "alu")
8654    (set_attr "mode" "SI")])
8656 (define_expand "iorhi3"
8657   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8658         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8659                 (match_operand:HI 2 "general_operand" "")))
8660    (clobber (reg:CC FLAGS_REG))]
8661   "TARGET_HIMODE_MATH"
8662   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8664 (define_insn "*iorhi_1"
8665   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8666         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8667                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "ix86_binary_operator_ok (IOR, HImode, operands)"
8670   "or{w}\t{%2, %0|%0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "HI")])
8674 (define_insn "*iorhi_2"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8677                          (match_operand:HI 2 "general_operand" "rim,ri"))
8678                  (const_int 0)))
8679    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8680         (ior:HI (match_dup 1) (match_dup 2)))]
8681   "ix86_match_ccmode (insn, CCNOmode)
8682    && ix86_binary_operator_ok (IOR, HImode, operands)"
8683   "or{w}\t{%2, %0|%0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "mode" "HI")])
8687 (define_insn "*iorhi_3"
8688   [(set (reg FLAGS_REG)
8689         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8690                          (match_operand:HI 2 "general_operand" "rim"))
8691                  (const_int 0)))
8692    (clobber (match_scratch:HI 0 "=r"))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8695   "or{w}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "HI")])
8699 (define_expand "iorqi3"
8700   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8701         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8702                 (match_operand:QI 2 "general_operand" "")))
8703    (clobber (reg:CC FLAGS_REG))]
8704   "TARGET_QIMODE_MATH"
8705   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8707 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8708 (define_insn "*iorqi_1"
8709   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8710         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8711                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8712    (clobber (reg:CC FLAGS_REG))]
8713   "ix86_binary_operator_ok (IOR, QImode, operands)"
8714   "@
8715    or{b}\t{%2, %0|%0, %2}
8716    or{b}\t{%2, %0|%0, %2}
8717    or{l}\t{%k2, %k0|%k0, %k2}"
8718   [(set_attr "type" "alu")
8719    (set_attr "mode" "QI,QI,SI")])
8721 (define_insn "*iorqi_1_slp"
8722   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8723         (ior:QI (match_dup 0)
8724                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8725    (clobber (reg:CC FLAGS_REG))]
8726   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8727    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8728   "or{b}\t{%1, %0|%0, %1}"
8729   [(set_attr "type" "alu1")
8730    (set_attr "mode" "QI")])
8732 (define_insn "*iorqi_2"
8733   [(set (reg FLAGS_REG)
8734         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8735                          (match_operand:QI 2 "general_operand" "qim,qi"))
8736                  (const_int 0)))
8737    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8738         (ior:QI (match_dup 1) (match_dup 2)))]
8739   "ix86_match_ccmode (insn, CCNOmode)
8740    && ix86_binary_operator_ok (IOR, QImode, operands)"
8741   "or{b}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "QI")])
8745 (define_insn "*iorqi_2_slp"
8746   [(set (reg FLAGS_REG)
8747         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8748                          (match_operand:QI 1 "general_operand" "qim,qi"))
8749                  (const_int 0)))
8750    (set (strict_low_part (match_dup 0))
8751         (ior:QI (match_dup 0) (match_dup 1)))]
8752   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8753    && ix86_match_ccmode (insn, CCNOmode)
8754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8755   "or{b}\t{%1, %0|%0, %1}"
8756   [(set_attr "type" "alu1")
8757    (set_attr "mode" "QI")])
8759 (define_insn "*iorqi_3"
8760   [(set (reg FLAGS_REG)
8761         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8762                          (match_operand:QI 2 "general_operand" "qim"))
8763                  (const_int 0)))
8764    (clobber (match_scratch:QI 0 "=q"))]
8765   "ix86_match_ccmode (insn, CCNOmode)
8766    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8767   "or{b}\t{%2, %0|%0, %2}"
8768   [(set_attr "type" "alu")
8769    (set_attr "mode" "QI")])
8771 (define_insn "iorqi_ext_0"
8772   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773                          (const_int 8)
8774                          (const_int 8))
8775         (ior:SI 
8776           (zero_extract:SI
8777             (match_operand 1 "ext_register_operand" "0")
8778             (const_int 8)
8779             (const_int 8))
8780           (match_operand 2 "const_int_operand" "n")))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8783   "or{b}\t{%2, %h0|%h0, %2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "length_immediate" "1")
8786    (set_attr "mode" "QI")])
8788 (define_insn "*iorqi_ext_1"
8789   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790                          (const_int 8)
8791                          (const_int 8))
8792         (ior:SI 
8793           (zero_extract:SI
8794             (match_operand 1 "ext_register_operand" "0")
8795             (const_int 8)
8796             (const_int 8))
8797           (zero_extend:SI
8798             (match_operand:QI 2 "general_operand" "Qm"))))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "!TARGET_64BIT
8801    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8802   "or{b}\t{%2, %h0|%h0, %2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "length_immediate" "0")
8805    (set_attr "mode" "QI")])
8807 (define_insn "*iorqi_ext_1_rex64"
8808   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8809                          (const_int 8)
8810                          (const_int 8))
8811         (ior:SI 
8812           (zero_extract:SI
8813             (match_operand 1 "ext_register_operand" "0")
8814             (const_int 8)
8815             (const_int 8))
8816           (zero_extend:SI
8817             (match_operand 2 "ext_register_operand" "Q"))))
8818    (clobber (reg:CC FLAGS_REG))]
8819   "TARGET_64BIT
8820    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8821   "or{b}\t{%2, %h0|%h0, %2}"
8822   [(set_attr "type" "alu")
8823    (set_attr "length_immediate" "0")
8824    (set_attr "mode" "QI")])
8826 (define_insn "*iorqi_ext_2"
8827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8828                          (const_int 8)
8829                          (const_int 8))
8830         (ior:SI 
8831           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8832                            (const_int 8)
8833                            (const_int 8))
8834           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8835                            (const_int 8)
8836                            (const_int 8))))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8839   "ior{b}\t{%h2, %h0|%h0, %h2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "length_immediate" "0")
8842    (set_attr "mode" "QI")])
8844 (define_split
8845   [(set (match_operand 0 "register_operand" "")
8846         (ior (match_operand 1 "register_operand" "")
8847              (match_operand 2 "const_int_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849    "reload_completed
8850     && QI_REG_P (operands[0])
8851     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8852     && !(INTVAL (operands[2]) & ~(255 << 8))
8853     && GET_MODE (operands[0]) != QImode"
8854   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8855                    (ior:SI (zero_extract:SI (match_dup 1)
8856                                             (const_int 8) (const_int 8))
8857                            (match_dup 2)))
8858               (clobber (reg:CC FLAGS_REG))])]
8859   "operands[0] = gen_lowpart (SImode, operands[0]);
8860    operands[1] = gen_lowpart (SImode, operands[1]);
8861    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8863 ;; Since OR can be encoded with sign extended immediate, this is only
8864 ;; profitable when 7th bit is set.
8865 (define_split
8866   [(set (match_operand 0 "register_operand" "")
8867         (ior (match_operand 1 "general_operand" "")
8868              (match_operand 2 "const_int_operand" "")))
8869    (clobber (reg:CC FLAGS_REG))]
8870    "reload_completed
8871     && ANY_QI_REG_P (operands[0])
8872     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8873     && !(INTVAL (operands[2]) & ~255)
8874     && (INTVAL (operands[2]) & 128)
8875     && GET_MODE (operands[0]) != QImode"
8876   [(parallel [(set (strict_low_part (match_dup 0))
8877                    (ior:QI (match_dup 1)
8878                            (match_dup 2)))
8879               (clobber (reg:CC FLAGS_REG))])]
8880   "operands[0] = gen_lowpart (QImode, operands[0]);
8881    operands[1] = gen_lowpart (QImode, operands[1]);
8882    operands[2] = gen_lowpart (QImode, operands[2]);")
8884 ;; Logical XOR instructions
8886 ;; %%% This used to optimize known byte-wide and operations to memory.
8887 ;; If this is considered useful, it should be done with splitters.
8889 (define_expand "xordi3"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8891         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8892                 (match_operand:DI 2 "x86_64_general_operand" "")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT"
8895   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8897 (define_insn "*xordi_1_rex64"
8898   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8899         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8900                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT
8903    && ix86_binary_operator_ok (XOR, DImode, operands)"
8904   "@
8905    xor{q}\t{%2, %0|%0, %2}
8906    xor{q}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "DI,DI")])
8910 (define_insn "*xordi_2_rex64"
8911   [(set (reg FLAGS_REG)
8912         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8913                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8914                  (const_int 0)))
8915    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8916         (xor:DI (match_dup 1) (match_dup 2)))]
8917   "TARGET_64BIT
8918    && ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_binary_operator_ok (XOR, DImode, operands)"
8920   "@
8921    xor{q}\t{%2, %0|%0, %2}
8922    xor{q}\t{%2, %0|%0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "mode" "DI,DI")])
8926 (define_insn "*xordi_3_rex64"
8927   [(set (reg FLAGS_REG)
8928         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8929                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8930                  (const_int 0)))
8931    (clobber (match_scratch:DI 0 "=r"))]
8932   "TARGET_64BIT
8933    && ix86_match_ccmode (insn, CCNOmode)
8934    && ix86_binary_operator_ok (XOR, DImode, operands)"
8935   "xor{q}\t{%2, %0|%0, %2}"
8936   [(set_attr "type" "alu")
8937    (set_attr "mode" "DI")])
8939 (define_expand "xorsi3"
8940   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8941         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8942                 (match_operand:SI 2 "general_operand" "")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   ""
8945   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8947 (define_insn "*xorsi_1"
8948   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8949         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8950                 (match_operand:SI 2 "general_operand" "ri,rm")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   "ix86_binary_operator_ok (XOR, SImode, operands)"
8953   "xor{l}\t{%2, %0|%0, %2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "SI")])
8957 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8958 ;; Add speccase for immediates
8959 (define_insn "*xorsi_1_zext"
8960   [(set (match_operand:DI 0 "register_operand" "=r")
8961         (zero_extend:DI
8962           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8963                   (match_operand:SI 2 "general_operand" "rim"))))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8966   "xor{l}\t{%2, %k0|%k0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "SI")])
8970 (define_insn "*xorsi_1_zext_imm"
8971   [(set (match_operand:DI 0 "register_operand" "=r")
8972         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8973                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8974    (clobber (reg:CC FLAGS_REG))]
8975   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8976   "xor{l}\t{%2, %k0|%k0, %2}"
8977   [(set_attr "type" "alu")
8978    (set_attr "mode" "SI")])
8980 (define_insn "*xorsi_2"
8981   [(set (reg FLAGS_REG)
8982         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983                          (match_operand:SI 2 "general_operand" "rim,ri"))
8984                  (const_int 0)))
8985    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8986         (xor:SI (match_dup 1) (match_dup 2)))]
8987   "ix86_match_ccmode (insn, CCNOmode)
8988    && ix86_binary_operator_ok (XOR, SImode, operands)"
8989   "xor{l}\t{%2, %0|%0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "SI")])
8993 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8994 ;; ??? Special case for immediate operand is missing - it is tricky.
8995 (define_insn "*xorsi_2_zext"
8996   [(set (reg FLAGS_REG)
8997         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8998                          (match_operand:SI 2 "general_operand" "rim"))
8999                  (const_int 0)))
9000    (set (match_operand:DI 0 "register_operand" "=r")
9001         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9002   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9003    && ix86_binary_operator_ok (XOR, SImode, operands)"
9004   "xor{l}\t{%2, %k0|%k0, %2}"
9005   [(set_attr "type" "alu")
9006    (set_attr "mode" "SI")])
9008 (define_insn "*xorsi_2_zext_imm"
9009   [(set (reg FLAGS_REG)
9010         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9012                  (const_int 0)))
9013    (set (match_operand:DI 0 "register_operand" "=r")
9014         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9015   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9016    && ix86_binary_operator_ok (XOR, SImode, operands)"
9017   "xor{l}\t{%2, %k0|%k0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "SI")])
9021 (define_insn "*xorsi_3"
9022   [(set (reg FLAGS_REG)
9023         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024                          (match_operand:SI 2 "general_operand" "rim"))
9025                  (const_int 0)))
9026    (clobber (match_scratch:SI 0 "=r"))]
9027   "ix86_match_ccmode (insn, CCNOmode)
9028    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9029   "xor{l}\t{%2, %0|%0, %2}"
9030   [(set_attr "type" "alu")
9031    (set_attr "mode" "SI")])
9033 (define_expand "xorhi3"
9034   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9035         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9036                 (match_operand:HI 2 "general_operand" "")))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "TARGET_HIMODE_MATH"
9039   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9041 (define_insn "*xorhi_1"
9042   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9043         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9044                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "ix86_binary_operator_ok (XOR, HImode, operands)"
9047   "xor{w}\t{%2, %0|%0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "HI")])
9051 (define_insn "*xorhi_2"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9054                          (match_operand:HI 2 "general_operand" "rim,ri"))
9055                  (const_int 0)))
9056    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9057         (xor:HI (match_dup 1) (match_dup 2)))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, HImode, operands)"
9060   "xor{w}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "HI")])
9064 (define_insn "*xorhi_3"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9067                          (match_operand:HI 2 "general_operand" "rim"))
9068                  (const_int 0)))
9069    (clobber (match_scratch:HI 0 "=r"))]
9070   "ix86_match_ccmode (insn, CCNOmode)
9071    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9072   "xor{w}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "HI")])
9076 (define_expand "xorqi3"
9077   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9078         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9079                 (match_operand:QI 2 "general_operand" "")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "TARGET_QIMODE_MATH"
9082   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9084 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9085 (define_insn "*xorqi_1"
9086   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9087         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9088                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9089    (clobber (reg:CC FLAGS_REG))]
9090   "ix86_binary_operator_ok (XOR, QImode, operands)"
9091   "@
9092    xor{b}\t{%2, %0|%0, %2}
9093    xor{b}\t{%2, %0|%0, %2}
9094    xor{l}\t{%k2, %k0|%k0, %k2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "QI,QI,SI")])
9098 (define_insn "*xorqi_1_slp"
9099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9100         (xor:QI (match_dup 0)
9101                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9102    (clobber (reg:CC FLAGS_REG))]
9103   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9104    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9105   "xor{b}\t{%1, %0|%0, %1}"
9106   [(set_attr "type" "alu1")
9107    (set_attr "mode" "QI")])
9109 (define_insn "xorqi_ext_0"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (xor:SI 
9114           (zero_extract:SI
9115             (match_operand 1 "ext_register_operand" "0")
9116             (const_int 8)
9117             (const_int 8))
9118           (match_operand 2 "const_int_operand" "n")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121   "xor{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "length_immediate" "1")
9124    (set_attr "mode" "QI")])
9126 (define_insn "*xorqi_ext_1"
9127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128                          (const_int 8)
9129                          (const_int 8))
9130         (xor:SI 
9131           (zero_extract:SI
9132             (match_operand 1 "ext_register_operand" "0")
9133             (const_int 8)
9134             (const_int 8))
9135           (zero_extend:SI
9136             (match_operand:QI 2 "general_operand" "Qm"))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "!TARGET_64BIT
9139    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140   "xor{b}\t{%2, %h0|%h0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9145 (define_insn "*xorqi_ext_1_rex64"
9146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147                          (const_int 8)
9148                          (const_int 8))
9149         (xor:SI 
9150           (zero_extract:SI
9151             (match_operand 1 "ext_register_operand" "0")
9152             (const_int 8)
9153             (const_int 8))
9154           (zero_extend:SI
9155             (match_operand 2 "ext_register_operand" "Q"))))
9156    (clobber (reg:CC FLAGS_REG))]
9157   "TARGET_64BIT
9158    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159   "xor{b}\t{%2, %h0|%h0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "length_immediate" "0")
9162    (set_attr "mode" "QI")])
9164 (define_insn "*xorqi_ext_2"
9165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166                          (const_int 8)
9167                          (const_int 8))
9168         (xor:SI 
9169           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9170                            (const_int 8)
9171                            (const_int 8))
9172           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9173                            (const_int 8)
9174                            (const_int 8))))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "xor{b}\t{%h2, %h0|%h0, %h2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "0")
9180    (set_attr "mode" "QI")])
9182 (define_insn "*xorqi_cc_1"
9183   [(set (reg FLAGS_REG)
9184         (compare
9185           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9186                   (match_operand:QI 2 "general_operand" "qim,qi"))
9187           (const_int 0)))
9188    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9189         (xor:QI (match_dup 1) (match_dup 2)))]
9190   "ix86_match_ccmode (insn, CCNOmode)
9191    && ix86_binary_operator_ok (XOR, QImode, operands)"
9192   "xor{b}\t{%2, %0|%0, %2}"
9193   [(set_attr "type" "alu")
9194    (set_attr "mode" "QI")])
9196 (define_insn "*xorqi_2_slp"
9197   [(set (reg FLAGS_REG)
9198         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9199                          (match_operand:QI 1 "general_operand" "qim,qi"))
9200                  (const_int 0)))
9201    (set (strict_low_part (match_dup 0))
9202         (xor:QI (match_dup 0) (match_dup 1)))]
9203   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9204    && ix86_match_ccmode (insn, CCNOmode)
9205    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9206   "xor{b}\t{%1, %0|%0, %1}"
9207   [(set_attr "type" "alu1")
9208    (set_attr "mode" "QI")])
9210 (define_insn "*xorqi_cc_2"
9211   [(set (reg FLAGS_REG)
9212         (compare
9213           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9214                   (match_operand:QI 2 "general_operand" "qim"))
9215           (const_int 0)))
9216    (clobber (match_scratch:QI 0 "=q"))]
9217   "ix86_match_ccmode (insn, CCNOmode)
9218    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9219   "xor{b}\t{%2, %0|%0, %2}"
9220   [(set_attr "type" "alu")
9221    (set_attr "mode" "QI")])
9223 (define_insn "*xorqi_cc_ext_1"
9224   [(set (reg FLAGS_REG)
9225         (compare
9226           (xor:SI
9227             (zero_extract:SI
9228               (match_operand 1 "ext_register_operand" "0")
9229               (const_int 8)
9230               (const_int 8))
9231             (match_operand:QI 2 "general_operand" "qmn"))
9232           (const_int 0)))
9233    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9234                          (const_int 8)
9235                          (const_int 8))
9236         (xor:SI 
9237           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9238           (match_dup 2)))]
9239   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9240   "xor{b}\t{%2, %h0|%h0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9244 (define_insn "*xorqi_cc_ext_1_rex64"
9245   [(set (reg FLAGS_REG)
9246         (compare
9247           (xor:SI
9248             (zero_extract:SI
9249               (match_operand 1 "ext_register_operand" "0")
9250               (const_int 8)
9251               (const_int 8))
9252             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9253           (const_int 0)))
9254    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255                          (const_int 8)
9256                          (const_int 8))
9257         (xor:SI 
9258           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9259           (match_dup 2)))]
9260   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9261   "xor{b}\t{%2, %h0|%h0, %2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "QI")])
9265 (define_expand "xorqi_cc_ext_1"
9266   [(parallel [
9267      (set (reg:CCNO FLAGS_REG)
9268           (compare:CCNO
9269             (xor:SI
9270               (zero_extract:SI
9271                 (match_operand 1 "ext_register_operand" "")
9272                 (const_int 8)
9273                 (const_int 8))
9274               (match_operand:QI 2 "general_operand" ""))
9275             (const_int 0)))
9276      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9277                            (const_int 8)
9278                            (const_int 8))
9279           (xor:SI 
9280             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9281             (match_dup 2)))])]
9282   ""
9283   "")
9285 (define_split
9286   [(set (match_operand 0 "register_operand" "")
9287         (xor (match_operand 1 "register_operand" "")
9288              (match_operand 2 "const_int_operand" "")))
9289    (clobber (reg:CC FLAGS_REG))]
9290    "reload_completed
9291     && QI_REG_P (operands[0])
9292     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9293     && !(INTVAL (operands[2]) & ~(255 << 8))
9294     && GET_MODE (operands[0]) != QImode"
9295   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9296                    (xor:SI (zero_extract:SI (match_dup 1)
9297                                             (const_int 8) (const_int 8))
9298                            (match_dup 2)))
9299               (clobber (reg:CC FLAGS_REG))])]
9300   "operands[0] = gen_lowpart (SImode, operands[0]);
9301    operands[1] = gen_lowpart (SImode, operands[1]);
9302    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9304 ;; Since XOR can be encoded with sign extended immediate, this is only
9305 ;; profitable when 7th bit is set.
9306 (define_split
9307   [(set (match_operand 0 "register_operand" "")
9308         (xor (match_operand 1 "general_operand" "")
9309              (match_operand 2 "const_int_operand" "")))
9310    (clobber (reg:CC FLAGS_REG))]
9311    "reload_completed
9312     && ANY_QI_REG_P (operands[0])
9313     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9314     && !(INTVAL (operands[2]) & ~255)
9315     && (INTVAL (operands[2]) & 128)
9316     && GET_MODE (operands[0]) != QImode"
9317   [(parallel [(set (strict_low_part (match_dup 0))
9318                    (xor:QI (match_dup 1)
9319                            (match_dup 2)))
9320               (clobber (reg:CC FLAGS_REG))])]
9321   "operands[0] = gen_lowpart (QImode, operands[0]);
9322    operands[1] = gen_lowpart (QImode, operands[1]);
9323    operands[2] = gen_lowpart (QImode, operands[2]);")
9325 ;; Negation instructions
9327 (define_expand "negti2"
9328   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9329                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9330               (clobber (reg:CC FLAGS_REG))])]
9331   "TARGET_64BIT"
9332   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9334 (define_insn "*negti2_1"
9335   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9336         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "TARGET_64BIT
9339    && ix86_unary_operator_ok (NEG, TImode, operands)"
9340   "#")
9342 (define_split
9343   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9344         (neg:TI (match_operand:TI 1 "general_operand" "")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "TARGET_64BIT && reload_completed"
9347   [(parallel
9348     [(set (reg:CCZ FLAGS_REG)
9349           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9350      (set (match_dup 0) (neg:DI (match_dup 2)))])
9351    (parallel
9352     [(set (match_dup 1)
9353           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9354                             (match_dup 3))
9355                    (const_int 0)))
9356      (clobber (reg:CC FLAGS_REG))])
9357    (parallel
9358     [(set (match_dup 1)
9359           (neg:DI (match_dup 1)))
9360      (clobber (reg:CC FLAGS_REG))])]
9361   "split_ti (operands+1, 1, operands+2, operands+3);
9362    split_ti (operands+0, 1, operands+0, operands+1);")
9364 (define_expand "negdi2"
9365   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9366                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9367               (clobber (reg:CC FLAGS_REG))])]
9368   ""
9369   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9371 (define_insn "*negdi2_1"
9372   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9373         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9374    (clobber (reg:CC FLAGS_REG))]
9375   "!TARGET_64BIT
9376    && ix86_unary_operator_ok (NEG, DImode, operands)"
9377   "#")
9379 (define_split
9380   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9381         (neg:DI (match_operand:DI 1 "general_operand" "")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "!TARGET_64BIT && reload_completed"
9384   [(parallel
9385     [(set (reg:CCZ FLAGS_REG)
9386           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9387      (set (match_dup 0) (neg:SI (match_dup 2)))])
9388    (parallel
9389     [(set (match_dup 1)
9390           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9391                             (match_dup 3))
9392                    (const_int 0)))
9393      (clobber (reg:CC FLAGS_REG))])
9394    (parallel
9395     [(set (match_dup 1)
9396           (neg:SI (match_dup 1)))
9397      (clobber (reg:CC FLAGS_REG))])]
9398   "split_di (operands+1, 1, operands+2, operands+3);
9399    split_di (operands+0, 1, operands+0, operands+1);")
9401 (define_insn "*negdi2_1_rex64"
9402   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9403         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9406   "neg{q}\t%0"
9407   [(set_attr "type" "negnot")
9408    (set_attr "mode" "DI")])
9410 ;; The problem with neg is that it does not perform (compare x 0),
9411 ;; it really performs (compare 0 x), which leaves us with the zero
9412 ;; flag being the only useful item.
9414 (define_insn "*negdi2_cmpz_rex64"
9415   [(set (reg:CCZ FLAGS_REG)
9416         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9417                      (const_int 0)))
9418    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9419         (neg:DI (match_dup 1)))]
9420   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9421   "neg{q}\t%0"
9422   [(set_attr "type" "negnot")
9423    (set_attr "mode" "DI")])
9426 (define_expand "negsi2"
9427   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9428                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9429               (clobber (reg:CC FLAGS_REG))])]
9430   ""
9431   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9433 (define_insn "*negsi2_1"
9434   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9435         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9436    (clobber (reg:CC FLAGS_REG))]
9437   "ix86_unary_operator_ok (NEG, SImode, operands)"
9438   "neg{l}\t%0"
9439   [(set_attr "type" "negnot")
9440    (set_attr "mode" "SI")])
9442 ;; Combine is quite creative about this pattern.
9443 (define_insn "*negsi2_1_zext"
9444   [(set (match_operand:DI 0 "register_operand" "=r")
9445         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9446                                         (const_int 32)))
9447                      (const_int 32)))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9450   "neg{l}\t%k0"
9451   [(set_attr "type" "negnot")
9452    (set_attr "mode" "SI")])
9454 ;; The problem with neg is that it does not perform (compare x 0),
9455 ;; it really performs (compare 0 x), which leaves us with the zero
9456 ;; flag being the only useful item.
9458 (define_insn "*negsi2_cmpz"
9459   [(set (reg:CCZ FLAGS_REG)
9460         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9461                      (const_int 0)))
9462    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9463         (neg:SI (match_dup 1)))]
9464   "ix86_unary_operator_ok (NEG, SImode, operands)"
9465   "neg{l}\t%0"
9466   [(set_attr "type" "negnot")
9467    (set_attr "mode" "SI")])
9469 (define_insn "*negsi2_cmpz_zext"
9470   [(set (reg:CCZ FLAGS_REG)
9471         (compare:CCZ (lshiftrt:DI
9472                        (neg:DI (ashift:DI
9473                                  (match_operand:DI 1 "register_operand" "0")
9474                                  (const_int 32)))
9475                        (const_int 32))
9476                      (const_int 0)))
9477    (set (match_operand:DI 0 "register_operand" "=r")
9478         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9479                                         (const_int 32)))
9480                      (const_int 32)))]
9481   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9482   "neg{l}\t%k0"
9483   [(set_attr "type" "negnot")
9484    (set_attr "mode" "SI")])
9486 (define_expand "neghi2"
9487   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9488                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9489               (clobber (reg:CC FLAGS_REG))])]
9490   "TARGET_HIMODE_MATH"
9491   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9493 (define_insn "*neghi2_1"
9494   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9495         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "ix86_unary_operator_ok (NEG, HImode, operands)"
9498   "neg{w}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "HI")])
9502 (define_insn "*neghi2_cmpz"
9503   [(set (reg:CCZ FLAGS_REG)
9504         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9505                      (const_int 0)))
9506    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9507         (neg:HI (match_dup 1)))]
9508   "ix86_unary_operator_ok (NEG, HImode, operands)"
9509   "neg{w}\t%0"
9510   [(set_attr "type" "negnot")
9511    (set_attr "mode" "HI")])
9513 (define_expand "negqi2"
9514   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9515                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9516               (clobber (reg:CC FLAGS_REG))])]
9517   "TARGET_QIMODE_MATH"
9518   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9520 (define_insn "*negqi2_1"
9521   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9522         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "ix86_unary_operator_ok (NEG, QImode, operands)"
9525   "neg{b}\t%0"
9526   [(set_attr "type" "negnot")
9527    (set_attr "mode" "QI")])
9529 (define_insn "*negqi2_cmpz"
9530   [(set (reg:CCZ FLAGS_REG)
9531         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9532                      (const_int 0)))
9533    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9534         (neg:QI (match_dup 1)))]
9535   "ix86_unary_operator_ok (NEG, QImode, operands)"
9536   "neg{b}\t%0"
9537   [(set_attr "type" "negnot")
9538    (set_attr "mode" "QI")])
9540 ;; Changing of sign for FP values is doable using integer unit too.
9542 (define_expand "negsf2"
9543   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9544         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9545   "TARGET_80387 || TARGET_SSE_MATH"
9546   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9548 (define_expand "abssf2"
9549   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9550         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9551   "TARGET_80387 || TARGET_SSE_MATH"
9552   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9554 (define_insn "*absnegsf2_mixed"
9555   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9556         (match_operator:SF 3 "absneg_operator"
9557           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9558    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9559    (clobber (reg:CC FLAGS_REG))]
9560   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9561    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9562   "#")
9564 (define_insn "*absnegsf2_sse"
9565   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9566         (match_operator:SF 3 "absneg_operator"
9567           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9568    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "TARGET_SSE_MATH
9571    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9572   "#")
9574 (define_insn "*absnegsf2_i387"
9575   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9576         (match_operator:SF 3 "absneg_operator"
9577           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9578    (use (match_operand 2 "" ""))
9579    (clobber (reg:CC FLAGS_REG))]
9580   "TARGET_80387 && !TARGET_SSE_MATH
9581    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9582   "#")
9584 (define_expand "copysignsf3"
9585   [(match_operand:SF 0 "register_operand" "")
9586    (match_operand:SF 1 "nonmemory_operand" "")
9587    (match_operand:SF 2 "register_operand" "")]
9588   "TARGET_SSE_MATH"
9590   ix86_expand_copysign (operands);
9591   DONE;
9594 (define_insn_and_split "copysignsf3_const"
9595   [(set (match_operand:SF 0 "register_operand"          "=x")
9596         (unspec:SF
9597           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9598            (match_operand:SF 2 "register_operand"       "0")
9599            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9600           UNSPEC_COPYSIGN))]
9601   "TARGET_SSE_MATH"
9602   "#"
9603   "&& reload_completed"
9604   [(const_int 0)]
9606   ix86_split_copysign_const (operands);
9607   DONE;
9610 (define_insn "copysignsf3_var"
9611   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9612         (unspec:SF
9613           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9614            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9615            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9616            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9617           UNSPEC_COPYSIGN))
9618    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9619   "TARGET_SSE_MATH"
9620   "#")
9622 (define_split
9623   [(set (match_operand:SF 0 "register_operand" "")
9624         (unspec:SF
9625           [(match_operand:SF 2 "register_operand" "")
9626            (match_operand:SF 3 "register_operand" "")
9627            (match_operand:V4SF 4 "" "")
9628            (match_operand:V4SF 5 "" "")]
9629           UNSPEC_COPYSIGN))
9630    (clobber (match_scratch:V4SF 1 ""))]
9631   "TARGET_SSE_MATH && reload_completed"
9632   [(const_int 0)]
9634   ix86_split_copysign_var (operands);
9635   DONE;
9638 (define_expand "negdf2"
9639   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9640         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9641   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9642   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9644 (define_expand "absdf2"
9645   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9646         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9647   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9648   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9650 (define_insn "*absnegdf2_mixed"
9651   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9652         (match_operator:DF 3 "absneg_operator"
9653           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9654    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9657    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9658   "#")
9660 (define_insn "*absnegdf2_sse"
9661   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9662         (match_operator:DF 3 "absneg_operator"
9663           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9664    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "TARGET_SSE2 && TARGET_SSE_MATH
9667    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9668   "#")
9670 (define_insn "*absnegdf2_i387"
9671   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9672         (match_operator:DF 3 "absneg_operator"
9673           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9674    (use (match_operand 2 "" ""))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9677    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9678   "#")
9680 (define_expand "copysigndf3"
9681   [(match_operand:DF 0 "register_operand" "")
9682    (match_operand:DF 1 "nonmemory_operand" "")
9683    (match_operand:DF 2 "register_operand" "")]
9684   "TARGET_SSE2 && TARGET_SSE_MATH"
9686   ix86_expand_copysign (operands);
9687   DONE;
9690 (define_insn_and_split "copysigndf3_const"
9691   [(set (match_operand:DF 0 "register_operand"          "=x")
9692         (unspec:DF
9693           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9694            (match_operand:DF 2 "register_operand"       "0")
9695            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9696           UNSPEC_COPYSIGN))]
9697   "TARGET_SSE2 && TARGET_SSE_MATH"
9698   "#"
9699   "&& reload_completed"
9700   [(const_int 0)]
9702   ix86_split_copysign_const (operands);
9703   DONE;
9706 (define_insn "copysigndf3_var"
9707   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9708         (unspec:DF
9709           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9710            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9711            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9712            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9713           UNSPEC_COPYSIGN))
9714    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9715   "TARGET_SSE2 && TARGET_SSE_MATH"
9716   "#")
9718 (define_split
9719   [(set (match_operand:DF 0 "register_operand" "")
9720         (unspec:DF
9721           [(match_operand:DF 2 "register_operand" "")
9722            (match_operand:DF 3 "register_operand" "")
9723            (match_operand:V2DF 4 "" "")
9724            (match_operand:V2DF 5 "" "")]
9725           UNSPEC_COPYSIGN))
9726    (clobber (match_scratch:V2DF 1 ""))]
9727   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9728   [(const_int 0)]
9730   ix86_split_copysign_var (operands);
9731   DONE;
9734 (define_expand "negxf2"
9735   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9736         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737   "TARGET_80387"
9738   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9740 (define_expand "absxf2"
9741   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9742         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9743   "TARGET_80387"
9744   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9746 (define_insn "*absnegxf2_i387"
9747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9748         (match_operator:XF 3 "absneg_operator"
9749           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9750    (use (match_operand 2 "" ""))
9751    (clobber (reg:CC FLAGS_REG))]
9752   "TARGET_80387
9753    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9754   "#")
9756 ;; Splitters for fp abs and neg.
9758 (define_split
9759   [(set (match_operand 0 "fp_register_operand" "")
9760         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9761    (use (match_operand 2 "" ""))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "reload_completed"
9764   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9766 (define_split
9767   [(set (match_operand 0 "register_operand" "")
9768         (match_operator 3 "absneg_operator"
9769           [(match_operand 1 "register_operand" "")]))
9770    (use (match_operand 2 "nonimmediate_operand" ""))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "reload_completed && SSE_REG_P (operands[0])"
9773   [(set (match_dup 0) (match_dup 3))]
9775   enum machine_mode mode = GET_MODE (operands[0]);
9776   enum machine_mode vmode = GET_MODE (operands[2]);
9777   rtx tmp;
9778   
9779   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9780   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9781   if (operands_match_p (operands[0], operands[2]))
9782     {
9783       tmp = operands[1];
9784       operands[1] = operands[2];
9785       operands[2] = tmp;
9786     }
9787   if (GET_CODE (operands[3]) == ABS)
9788     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9789   else
9790     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9791   operands[3] = tmp;
9794 (define_split
9795   [(set (match_operand:SF 0 "register_operand" "")
9796         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9797    (use (match_operand:V4SF 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "reload_completed"
9800   [(parallel [(set (match_dup 0) (match_dup 1))
9801               (clobber (reg:CC FLAGS_REG))])]
9803   rtx tmp;
9804   operands[0] = gen_lowpart (SImode, operands[0]);
9805   if (GET_CODE (operands[1]) == ABS)
9806     {
9807       tmp = gen_int_mode (0x7fffffff, SImode);
9808       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9809     }
9810   else
9811     {
9812       tmp = gen_int_mode (0x80000000, SImode);
9813       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9814     }
9815   operands[1] = tmp;
9818 (define_split
9819   [(set (match_operand:DF 0 "register_operand" "")
9820         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9821    (use (match_operand 2 "" ""))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "reload_completed"
9824   [(parallel [(set (match_dup 0) (match_dup 1))
9825               (clobber (reg:CC FLAGS_REG))])]
9827   rtx tmp;
9828   if (TARGET_64BIT)
9829     {
9830       tmp = gen_lowpart (DImode, operands[0]);
9831       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9832       operands[0] = tmp;
9834       if (GET_CODE (operands[1]) == ABS)
9835         tmp = const0_rtx;
9836       else
9837         tmp = gen_rtx_NOT (DImode, tmp);
9838     }
9839   else
9840     {
9841       operands[0] = gen_highpart (SImode, operands[0]);
9842       if (GET_CODE (operands[1]) == ABS)
9843         {
9844           tmp = gen_int_mode (0x7fffffff, SImode);
9845           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9846         }
9847       else
9848         {
9849           tmp = gen_int_mode (0x80000000, SImode);
9850           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9851         }
9852     }
9853   operands[1] = tmp;
9856 (define_split
9857   [(set (match_operand:XF 0 "register_operand" "")
9858         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9859    (use (match_operand 2 "" ""))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "reload_completed"
9862   [(parallel [(set (match_dup 0) (match_dup 1))
9863               (clobber (reg:CC FLAGS_REG))])]
9865   rtx tmp;
9866   operands[0] = gen_rtx_REG (SImode,
9867                              true_regnum (operands[0])
9868                              + (TARGET_64BIT ? 1 : 2));
9869   if (GET_CODE (operands[1]) == ABS)
9870     {
9871       tmp = GEN_INT (0x7fff);
9872       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9873     }
9874   else
9875     {
9876       tmp = GEN_INT (0x8000);
9877       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9878     }
9879   operands[1] = tmp;
9882 (define_split
9883   [(set (match_operand 0 "memory_operand" "")
9884         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9885    (use (match_operand 2 "" ""))
9886    (clobber (reg:CC FLAGS_REG))]
9887   "reload_completed"
9888   [(parallel [(set (match_dup 0) (match_dup 1))
9889               (clobber (reg:CC FLAGS_REG))])]
9891   enum machine_mode mode = GET_MODE (operands[0]);
9892   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9893   rtx tmp;
9895   operands[0] = adjust_address (operands[0], QImode, size - 1);
9896   if (GET_CODE (operands[1]) == ABS)
9897     {
9898       tmp = gen_int_mode (0x7f, QImode);
9899       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9900     }
9901   else
9902     {
9903       tmp = gen_int_mode (0x80, QImode);
9904       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9905     }
9906   operands[1] = tmp;
9909 ;; Conditionalize these after reload. If they match before reload, we 
9910 ;; lose the clobber and ability to use integer instructions.
9912 (define_insn "*negsf2_1"
9913   [(set (match_operand:SF 0 "register_operand" "=f")
9914         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9915   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9916   "fchs"
9917   [(set_attr "type" "fsgn")
9918    (set_attr "mode" "SF")])
9920 (define_insn "*negdf2_1"
9921   [(set (match_operand:DF 0 "register_operand" "=f")
9922         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9923   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "DF")])
9928 (define_insn "*negxf2_1"
9929   [(set (match_operand:XF 0 "register_operand" "=f")
9930         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9931   "TARGET_80387"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "XF")])
9936 (define_insn "*abssf2_1"
9937   [(set (match_operand:SF 0 "register_operand" "=f")
9938         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9939   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9940   "fabs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "SF")])
9944 (define_insn "*absdf2_1"
9945   [(set (match_operand:DF 0 "register_operand" "=f")
9946         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9947   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "DF")])
9952 (define_insn "*absxf2_1"
9953   [(set (match_operand:XF 0 "register_operand" "=f")
9954         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9955   "TARGET_80387"
9956   "fabs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9960 (define_insn "*negextendsfdf2"
9961   [(set (match_operand:DF 0 "register_operand" "=f")
9962         (neg:DF (float_extend:DF
9963                   (match_operand:SF 1 "register_operand" "0"))))]
9964   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9965   "fchs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "DF")])
9969 (define_insn "*negextenddfxf2"
9970   [(set (match_operand:XF 0 "register_operand" "=f")
9971         (neg:XF (float_extend:XF
9972                   (match_operand:DF 1 "register_operand" "0"))))]
9973   "TARGET_80387"
9974   "fchs"
9975   [(set_attr "type" "fsgn")
9976    (set_attr "mode" "XF")])
9978 (define_insn "*negextendsfxf2"
9979   [(set (match_operand:XF 0 "register_operand" "=f")
9980         (neg:XF (float_extend:XF
9981                   (match_operand:SF 1 "register_operand" "0"))))]
9982   "TARGET_80387"
9983   "fchs"
9984   [(set_attr "type" "fsgn")
9985    (set_attr "mode" "XF")])
9987 (define_insn "*absextendsfdf2"
9988   [(set (match_operand:DF 0 "register_operand" "=f")
9989         (abs:DF (float_extend:DF
9990                   (match_operand:SF 1 "register_operand" "0"))))]
9991   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9992   "fabs"
9993   [(set_attr "type" "fsgn")
9994    (set_attr "mode" "DF")])
9996 (define_insn "*absextenddfxf2"
9997   [(set (match_operand:XF 0 "register_operand" "=f")
9998         (abs:XF (float_extend:XF
9999           (match_operand:DF 1 "register_operand" "0"))))]
10000   "TARGET_80387"
10001   "fabs"
10002   [(set_attr "type" "fsgn")
10003    (set_attr "mode" "XF")])
10005 (define_insn "*absextendsfxf2"
10006   [(set (match_operand:XF 0 "register_operand" "=f")
10007         (abs:XF (float_extend:XF
10008           (match_operand:SF 1 "register_operand" "0"))))]
10009   "TARGET_80387"
10010   "fabs"
10011   [(set_attr "type" "fsgn")
10012    (set_attr "mode" "XF")])
10014 ;; One complement instructions
10016 (define_expand "one_cmpldi2"
10017   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10018         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10019   "TARGET_64BIT"
10020   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10022 (define_insn "*one_cmpldi2_1_rex64"
10023   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10024         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10025   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10026   "not{q}\t%0"
10027   [(set_attr "type" "negnot")
10028    (set_attr "mode" "DI")])
10030 (define_insn "*one_cmpldi2_2_rex64"
10031   [(set (reg FLAGS_REG)
10032         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10033                  (const_int 0)))
10034    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10035         (not:DI (match_dup 1)))]
10036   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037    && ix86_unary_operator_ok (NOT, DImode, operands)"
10038   "#"
10039   [(set_attr "type" "alu1")
10040    (set_attr "mode" "DI")])
10042 (define_split
10043   [(set (match_operand 0 "flags_reg_operand" "")
10044         (match_operator 2 "compare_operator"
10045           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10046            (const_int 0)]))
10047    (set (match_operand:DI 1 "nonimmediate_operand" "")
10048         (not:DI (match_dup 3)))]
10049   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10050   [(parallel [(set (match_dup 0)
10051                    (match_op_dup 2
10052                      [(xor:DI (match_dup 3) (const_int -1))
10053                       (const_int 0)]))
10054               (set (match_dup 1)
10055                    (xor:DI (match_dup 3) (const_int -1)))])]
10056   "")
10058 (define_expand "one_cmplsi2"
10059   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10060         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10061   ""
10062   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10064 (define_insn "*one_cmplsi2_1"
10065   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10066         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10067   "ix86_unary_operator_ok (NOT, SImode, operands)"
10068   "not{l}\t%0"
10069   [(set_attr "type" "negnot")
10070    (set_attr "mode" "SI")])
10072 ;; ??? Currently never generated - xor is used instead.
10073 (define_insn "*one_cmplsi2_1_zext"
10074   [(set (match_operand:DI 0 "register_operand" "=r")
10075         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10076   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10077   "not{l}\t%k0"
10078   [(set_attr "type" "negnot")
10079    (set_attr "mode" "SI")])
10081 (define_insn "*one_cmplsi2_2"
10082   [(set (reg FLAGS_REG)
10083         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10084                  (const_int 0)))
10085    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10086         (not:SI (match_dup 1)))]
10087   "ix86_match_ccmode (insn, CCNOmode)
10088    && ix86_unary_operator_ok (NOT, SImode, operands)"
10089   "#"
10090   [(set_attr "type" "alu1")
10091    (set_attr "mode" "SI")])
10093 (define_split
10094   [(set (match_operand 0 "flags_reg_operand" "")
10095         (match_operator 2 "compare_operator"
10096           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10097            (const_int 0)]))
10098    (set (match_operand:SI 1 "nonimmediate_operand" "")
10099         (not:SI (match_dup 3)))]
10100   "ix86_match_ccmode (insn, CCNOmode)"
10101   [(parallel [(set (match_dup 0)
10102                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10103                                     (const_int 0)]))
10104               (set (match_dup 1)
10105                    (xor:SI (match_dup 3) (const_int -1)))])]
10106   "")
10108 ;; ??? Currently never generated - xor is used instead.
10109 (define_insn "*one_cmplsi2_2_zext"
10110   [(set (reg FLAGS_REG)
10111         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10112                  (const_int 0)))
10113    (set (match_operand:DI 0 "register_operand" "=r")
10114         (zero_extend:DI (not:SI (match_dup 1))))]
10115   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10116    && ix86_unary_operator_ok (NOT, SImode, operands)"
10117   "#"
10118   [(set_attr "type" "alu1")
10119    (set_attr "mode" "SI")])
10121 (define_split
10122   [(set (match_operand 0 "flags_reg_operand" "")
10123         (match_operator 2 "compare_operator"
10124           [(not:SI (match_operand:SI 3 "register_operand" ""))
10125            (const_int 0)]))
10126    (set (match_operand:DI 1 "register_operand" "")
10127         (zero_extend:DI (not:SI (match_dup 3))))]
10128   "ix86_match_ccmode (insn, CCNOmode)"
10129   [(parallel [(set (match_dup 0)
10130                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10131                                     (const_int 0)]))
10132               (set (match_dup 1)
10133                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10134   "")
10136 (define_expand "one_cmplhi2"
10137   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10138         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10139   "TARGET_HIMODE_MATH"
10140   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10142 (define_insn "*one_cmplhi2_1"
10143   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10144         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10145   "ix86_unary_operator_ok (NOT, HImode, operands)"
10146   "not{w}\t%0"
10147   [(set_attr "type" "negnot")
10148    (set_attr "mode" "HI")])
10150 (define_insn "*one_cmplhi2_2"
10151   [(set (reg FLAGS_REG)
10152         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10153                  (const_int 0)))
10154    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10155         (not:HI (match_dup 1)))]
10156   "ix86_match_ccmode (insn, CCNOmode)
10157    && ix86_unary_operator_ok (NEG, HImode, operands)"
10158   "#"
10159   [(set_attr "type" "alu1")
10160    (set_attr "mode" "HI")])
10162 (define_split
10163   [(set (match_operand 0 "flags_reg_operand" "")
10164         (match_operator 2 "compare_operator"
10165           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10166            (const_int 0)]))
10167    (set (match_operand:HI 1 "nonimmediate_operand" "")
10168         (not:HI (match_dup 3)))]
10169   "ix86_match_ccmode (insn, CCNOmode)"
10170   [(parallel [(set (match_dup 0)
10171                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10172                                     (const_int 0)]))
10173               (set (match_dup 1)
10174                    (xor:HI (match_dup 3) (const_int -1)))])]
10175   "")
10177 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10178 (define_expand "one_cmplqi2"
10179   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10180         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10181   "TARGET_QIMODE_MATH"
10182   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10184 (define_insn "*one_cmplqi2_1"
10185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10186         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10187   "ix86_unary_operator_ok (NOT, QImode, operands)"
10188   "@
10189    not{b}\t%0
10190    not{l}\t%k0"
10191   [(set_attr "type" "negnot")
10192    (set_attr "mode" "QI,SI")])
10194 (define_insn "*one_cmplqi2_2"
10195   [(set (reg FLAGS_REG)
10196         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10197                  (const_int 0)))
10198    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10199         (not:QI (match_dup 1)))]
10200   "ix86_match_ccmode (insn, CCNOmode)
10201    && ix86_unary_operator_ok (NOT, QImode, operands)"
10202   "#"
10203   [(set_attr "type" "alu1")
10204    (set_attr "mode" "QI")])
10206 (define_split
10207   [(set (match_operand 0 "flags_reg_operand" "")
10208         (match_operator 2 "compare_operator"
10209           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10210            (const_int 0)]))
10211    (set (match_operand:QI 1 "nonimmediate_operand" "")
10212         (not:QI (match_dup 3)))]
10213   "ix86_match_ccmode (insn, CCNOmode)"
10214   [(parallel [(set (match_dup 0)
10215                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10216                                     (const_int 0)]))
10217               (set (match_dup 1)
10218                    (xor:QI (match_dup 3) (const_int -1)))])]
10219   "")
10221 ;; Arithmetic shift instructions
10223 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10224 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10225 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10226 ;; from the assembler input.
10228 ;; This instruction shifts the target reg/mem as usual, but instead of
10229 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10230 ;; is a left shift double, bits are taken from the high order bits of
10231 ;; reg, else if the insn is a shift right double, bits are taken from the
10232 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10233 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10235 ;; Since sh[lr]d does not change the `reg' operand, that is done
10236 ;; separately, making all shifts emit pairs of shift double and normal
10237 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10238 ;; support a 63 bit shift, each shift where the count is in a reg expands
10239 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10241 ;; If the shift count is a constant, we need never emit more than one
10242 ;; shift pair, instead using moves and sign extension for counts greater
10243 ;; than 31.
10245 (define_expand "ashlti3"
10246   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10247                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10248                               (match_operand:QI 2 "nonmemory_operand" "")))
10249               (clobber (reg:CC FLAGS_REG))])]
10250   "TARGET_64BIT"
10252   if (! immediate_operand (operands[2], QImode))
10253     {
10254       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10255       DONE;
10256     }
10257   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10258   DONE;
10261 (define_insn "ashlti3_1"
10262   [(set (match_operand:TI 0 "register_operand" "=r")
10263         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10264                    (match_operand:QI 2 "register_operand" "c")))
10265    (clobber (match_scratch:DI 3 "=&r"))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "#"
10269   [(set_attr "type" "multi")])
10271 (define_insn "*ashlti3_2"
10272   [(set (match_operand:TI 0 "register_operand" "=r")
10273         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10274                    (match_operand:QI 2 "immediate_operand" "O")))
10275    (clobber (reg:CC FLAGS_REG))]
10276   "TARGET_64BIT"
10277   "#"
10278   [(set_attr "type" "multi")])
10280 (define_split
10281   [(set (match_operand:TI 0 "register_operand" "")
10282         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10283                    (match_operand:QI 2 "register_operand" "")))
10284    (clobber (match_scratch:DI 3 ""))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_64BIT && reload_completed"
10287   [(const_int 0)]
10288   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10290 (define_split
10291   [(set (match_operand:TI 0 "register_operand" "")
10292         (ashift:TI (match_operand:TI 1 "register_operand" "")
10293                    (match_operand:QI 2 "immediate_operand" "")))
10294    (clobber (reg:CC FLAGS_REG))]
10295   "TARGET_64BIT && reload_completed"
10296   [(const_int 0)]
10297   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10299 (define_insn "x86_64_shld"
10300   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10301         (ior:DI (ashift:DI (match_dup 0)
10302                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10303                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10304                   (minus:QI (const_int 64) (match_dup 2)))))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT"
10307   "@
10308    shld{q}\t{%2, %1, %0|%0, %1, %2}
10309    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10310   [(set_attr "type" "ishift")
10311    (set_attr "prefix_0f" "1")
10312    (set_attr "mode" "DI")
10313    (set_attr "athlon_decode" "vector")])
10315 (define_expand "x86_64_shift_adj"
10316   [(set (reg:CCZ FLAGS_REG)
10317         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10318                              (const_int 64))
10319                      (const_int 0)))
10320    (set (match_operand:DI 0 "register_operand" "")
10321         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10322                          (match_operand:DI 1 "register_operand" "")
10323                          (match_dup 0)))
10324    (set (match_dup 1)
10325         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10326                          (match_operand:DI 3 "register_operand" "r")
10327                          (match_dup 1)))]
10328   "TARGET_64BIT"
10329   "")
10331 (define_expand "ashldi3"
10332   [(set (match_operand:DI 0 "shiftdi_operand" "")
10333         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10334                    (match_operand:QI 2 "nonmemory_operand" "")))]
10335   ""
10336   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10338 (define_insn "*ashldi3_1_rex64"
10339   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10340         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10341                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10345   switch (get_attr_type (insn))
10346     {
10347     case TYPE_ALU:
10348       gcc_assert (operands[2] == const1_rtx);
10349       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10350       return "add{q}\t{%0, %0|%0, %0}";
10352     case TYPE_LEA:
10353       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10354       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10355       operands[1] = gen_rtx_MULT (DImode, operands[1],
10356                                   GEN_INT (1 << INTVAL (operands[2])));
10357       return "lea{q}\t{%a1, %0|%0, %a1}";
10359     default:
10360       if (REG_P (operands[2]))
10361         return "sal{q}\t{%b2, %0|%0, %b2}";
10362       else if (operands[2] == const1_rtx
10363                && (TARGET_SHIFT1 || optimize_size))
10364         return "sal{q}\t%0";
10365       else
10366         return "sal{q}\t{%2, %0|%0, %2}";
10367     }
10369   [(set (attr "type")
10370      (cond [(eq_attr "alternative" "1")
10371               (const_string "lea")
10372             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10373                           (const_int 0))
10374                       (match_operand 0 "register_operand" ""))
10375                  (match_operand 2 "const1_operand" ""))
10376               (const_string "alu")
10377            ]
10378            (const_string "ishift")))
10379    (set_attr "mode" "DI")])
10381 ;; Convert lea to the lea pattern to avoid flags dependency.
10382 (define_split
10383   [(set (match_operand:DI 0 "register_operand" "")
10384         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10385                    (match_operand:QI 2 "immediate_operand" "")))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_64BIT && reload_completed
10388    && true_regnum (operands[0]) != true_regnum (operands[1])"
10389   [(set (match_dup 0)
10390         (mult:DI (match_dup 1)
10391                  (match_dup 2)))]
10392   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10394 ;; This pattern can't accept a variable shift count, since shifts by
10395 ;; zero don't affect the flags.  We assume that shifts by constant
10396 ;; zero are optimized away.
10397 (define_insn "*ashldi3_cmp_rex64"
10398   [(set (reg FLAGS_REG)
10399         (compare
10400           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10401                      (match_operand:QI 2 "immediate_operand" "e"))
10402           (const_int 0)))
10403    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10404         (ashift:DI (match_dup 1) (match_dup 2)))]
10405   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10406    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10407    && (optimize_size
10408        || !TARGET_PARTIAL_FLAG_REG_STALL
10409        || (operands[2] == const1_rtx
10410            && (TARGET_SHIFT1
10411                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10413   switch (get_attr_type (insn))
10414     {
10415     case TYPE_ALU:
10416       gcc_assert (operands[2] == const1_rtx);
10417       return "add{q}\t{%0, %0|%0, %0}";
10419     default:
10420       if (REG_P (operands[2]))
10421         return "sal{q}\t{%b2, %0|%0, %b2}";
10422       else if (operands[2] == const1_rtx
10423                && (TARGET_SHIFT1 || optimize_size))
10424         return "sal{q}\t%0";
10425       else
10426         return "sal{q}\t{%2, %0|%0, %2}";
10427     }
10429   [(set (attr "type")
10430      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10431                           (const_int 0))
10432                       (match_operand 0 "register_operand" ""))
10433                  (match_operand 2 "const1_operand" ""))
10434               (const_string "alu")
10435            ]
10436            (const_string "ishift")))
10437    (set_attr "mode" "DI")])
10439 (define_insn "*ashldi3_cconly_rex64"
10440   [(set (reg FLAGS_REG)
10441         (compare
10442           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10443                      (match_operand:QI 2 "immediate_operand" "e"))
10444           (const_int 0)))
10445    (clobber (match_scratch:DI 0 "=r"))]
10446   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10447    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10448    && (optimize_size
10449        || !TARGET_PARTIAL_FLAG_REG_STALL
10450        || (operands[2] == const1_rtx
10451            && (TARGET_SHIFT1
10452                || TARGET_DOUBLE_WITH_ADD)))"
10454   switch (get_attr_type (insn))
10455     {
10456     case TYPE_ALU:
10457       gcc_assert (operands[2] == const1_rtx);
10458       return "add{q}\t{%0, %0|%0, %0}";
10460     default:
10461       if (REG_P (operands[2]))
10462         return "sal{q}\t{%b2, %0|%0, %b2}";
10463       else if (operands[2] == const1_rtx
10464                && (TARGET_SHIFT1 || optimize_size))
10465         return "sal{q}\t%0";
10466       else
10467         return "sal{q}\t{%2, %0|%0, %2}";
10468     }
10470   [(set (attr "type")
10471      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10472                           (const_int 0))
10473                       (match_operand 0 "register_operand" ""))
10474                  (match_operand 2 "const1_operand" ""))
10475               (const_string "alu")
10476            ]
10477            (const_string "ishift")))
10478    (set_attr "mode" "DI")])
10480 (define_insn "*ashldi3_1"
10481   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10482         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10483                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10484    (clobber (reg:CC FLAGS_REG))]
10485   "!TARGET_64BIT"
10486   "#"
10487   [(set_attr "type" "multi")])
10489 ;; By default we don't ask for a scratch register, because when DImode
10490 ;; values are manipulated, registers are already at a premium.  But if
10491 ;; we have one handy, we won't turn it away.
10492 (define_peephole2
10493   [(match_scratch:SI 3 "r")
10494    (parallel [(set (match_operand:DI 0 "register_operand" "")
10495                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10496                               (match_operand:QI 2 "nonmemory_operand" "")))
10497               (clobber (reg:CC FLAGS_REG))])
10498    (match_dup 3)]
10499   "!TARGET_64BIT && TARGET_CMOVE"
10500   [(const_int 0)]
10501   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10503 (define_split
10504   [(set (match_operand:DI 0 "register_operand" "")
10505         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10506                    (match_operand:QI 2 "nonmemory_operand" "")))
10507    (clobber (reg:CC FLAGS_REG))]
10508   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10509                      ? flow2_completed : reload_completed)"
10510   [(const_int 0)]
10511   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10513 (define_insn "x86_shld_1"
10514   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10515         (ior:SI (ashift:SI (match_dup 0)
10516                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10517                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10518                   (minus:QI (const_int 32) (match_dup 2)))))
10519    (clobber (reg:CC FLAGS_REG))]
10520   ""
10521   "@
10522    shld{l}\t{%2, %1, %0|%0, %1, %2}
10523    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10524   [(set_attr "type" "ishift")
10525    (set_attr "prefix_0f" "1")
10526    (set_attr "mode" "SI")
10527    (set_attr "pent_pair" "np")
10528    (set_attr "athlon_decode" "vector")])
10530 (define_expand "x86_shift_adj_1"
10531   [(set (reg:CCZ FLAGS_REG)
10532         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10533                              (const_int 32))
10534                      (const_int 0)))
10535    (set (match_operand:SI 0 "register_operand" "")
10536         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10537                          (match_operand:SI 1 "register_operand" "")
10538                          (match_dup 0)))
10539    (set (match_dup 1)
10540         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10541                          (match_operand:SI 3 "register_operand" "r")
10542                          (match_dup 1)))]
10543   "TARGET_CMOVE"
10544   "")
10546 (define_expand "x86_shift_adj_2"
10547   [(use (match_operand:SI 0 "register_operand" ""))
10548    (use (match_operand:SI 1 "register_operand" ""))
10549    (use (match_operand:QI 2 "register_operand" ""))]
10550   ""
10552   rtx label = gen_label_rtx ();
10553   rtx tmp;
10555   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10557   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10558   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10559   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10560                               gen_rtx_LABEL_REF (VOIDmode, label),
10561                               pc_rtx);
10562   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10563   JUMP_LABEL (tmp) = label;
10565   emit_move_insn (operands[0], operands[1]);
10566   ix86_expand_clear (operands[1]);
10568   emit_label (label);
10569   LABEL_NUSES (label) = 1;
10571   DONE;
10574 (define_expand "ashlsi3"
10575   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10576         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10577                    (match_operand:QI 2 "nonmemory_operand" "")))
10578    (clobber (reg:CC FLAGS_REG))]
10579   ""
10580   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10582 (define_insn "*ashlsi3_1"
10583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10584         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10585                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       gcc_assert (operands[2] == const1_rtx);
10593       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10594       return "add{l}\t{%0, %0|%0, %0}";
10596     case TYPE_LEA:
10597       return "#";
10599     default:
10600       if (REG_P (operands[2]))
10601         return "sal{l}\t{%b2, %0|%0, %b2}";
10602       else if (operands[2] == const1_rtx
10603                && (TARGET_SHIFT1 || optimize_size))
10604         return "sal{l}\t%0";
10605       else
10606         return "sal{l}\t{%2, %0|%0, %2}";
10607     }
10609   [(set (attr "type")
10610      (cond [(eq_attr "alternative" "1")
10611               (const_string "lea")
10612             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613                           (const_int 0))
10614                       (match_operand 0 "register_operand" ""))
10615                  (match_operand 2 "const1_operand" ""))
10616               (const_string "alu")
10617            ]
10618            (const_string "ishift")))
10619    (set_attr "mode" "SI")])
10621 ;; Convert lea to the lea pattern to avoid flags dependency.
10622 (define_split
10623   [(set (match_operand 0 "register_operand" "")
10624         (ashift (match_operand 1 "index_register_operand" "")
10625                 (match_operand:QI 2 "const_int_operand" "")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "reload_completed
10628    && true_regnum (operands[0]) != true_regnum (operands[1])
10629    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10630   [(const_int 0)]
10632   rtx pat;
10633   enum machine_mode mode = GET_MODE (operands[0]);
10635   if (GET_MODE_SIZE (mode) < 4)
10636     operands[0] = gen_lowpart (SImode, operands[0]);
10637   if (mode != Pmode)
10638     operands[1] = gen_lowpart (Pmode, operands[1]);
10639   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10641   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10642   if (Pmode != SImode)
10643     pat = gen_rtx_SUBREG (SImode, pat, 0);
10644   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10645   DONE;
10648 ;; Rare case of shifting RSP is handled by generating move and shift
10649 (define_split
10650   [(set (match_operand 0 "register_operand" "")
10651         (ashift (match_operand 1 "register_operand" "")
10652                 (match_operand:QI 2 "const_int_operand" "")))
10653    (clobber (reg:CC FLAGS_REG))]
10654   "reload_completed
10655    && true_regnum (operands[0]) != true_regnum (operands[1])"
10656   [(const_int 0)]
10658   rtx pat, clob;
10659   emit_move_insn (operands[0], operands[1]);
10660   pat = gen_rtx_SET (VOIDmode, operands[0],
10661                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10662                                      operands[0], operands[2]));
10663   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10664   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10665   DONE;
10668 (define_insn "*ashlsi3_1_zext"
10669   [(set (match_operand:DI 0 "register_operand" "=r,r")
10670         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10671                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10672    (clobber (reg:CC FLAGS_REG))]
10673   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10675   switch (get_attr_type (insn))
10676     {
10677     case TYPE_ALU:
10678       gcc_assert (operands[2] == const1_rtx);
10679       return "add{l}\t{%k0, %k0|%k0, %k0}";
10681     case TYPE_LEA:
10682       return "#";
10684     default:
10685       if (REG_P (operands[2]))
10686         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10687       else if (operands[2] == const1_rtx
10688                && (TARGET_SHIFT1 || optimize_size))
10689         return "sal{l}\t%k0";
10690       else
10691         return "sal{l}\t{%2, %k0|%k0, %2}";
10692     }
10694   [(set (attr "type")
10695      (cond [(eq_attr "alternative" "1")
10696               (const_string "lea")
10697             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10698                      (const_int 0))
10699                  (match_operand 2 "const1_operand" ""))
10700               (const_string "alu")
10701            ]
10702            (const_string "ishift")))
10703    (set_attr "mode" "SI")])
10705 ;; Convert lea to the lea pattern to avoid flags dependency.
10706 (define_split
10707   [(set (match_operand:DI 0 "register_operand" "")
10708         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10709                                 (match_operand:QI 2 "const_int_operand" ""))))
10710    (clobber (reg:CC FLAGS_REG))]
10711   "TARGET_64BIT && reload_completed
10712    && true_regnum (operands[0]) != true_regnum (operands[1])"
10713   [(set (match_dup 0) (zero_extend:DI
10714                         (subreg:SI (mult:SI (match_dup 1)
10715                                             (match_dup 2)) 0)))]
10717   operands[1] = gen_lowpart (Pmode, operands[1]);
10718   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10721 ;; This pattern can't accept a variable shift count, since shifts by
10722 ;; zero don't affect the flags.  We assume that shifts by constant
10723 ;; zero are optimized away.
10724 (define_insn "*ashlsi3_cmp"
10725   [(set (reg FLAGS_REG)
10726         (compare
10727           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10728                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10729           (const_int 0)))
10730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10731         (ashift:SI (match_dup 1) (match_dup 2)))]
10732   "ix86_match_ccmode (insn, CCGOCmode)
10733    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10734    && (optimize_size
10735        || !TARGET_PARTIAL_FLAG_REG_STALL
10736        || (operands[2] == const1_rtx
10737            && (TARGET_SHIFT1
10738                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10740   switch (get_attr_type (insn))
10741     {
10742     case TYPE_ALU:
10743       gcc_assert (operands[2] == const1_rtx);
10744       return "add{l}\t{%0, %0|%0, %0}";
10746     default:
10747       if (REG_P (operands[2]))
10748         return "sal{l}\t{%b2, %0|%0, %b2}";
10749       else if (operands[2] == const1_rtx
10750                && (TARGET_SHIFT1 || optimize_size))
10751         return "sal{l}\t%0";
10752       else
10753         return "sal{l}\t{%2, %0|%0, %2}";
10754     }
10756   [(set (attr "type")
10757      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10758                           (const_int 0))
10759                       (match_operand 0 "register_operand" ""))
10760                  (match_operand 2 "const1_operand" ""))
10761               (const_string "alu")
10762            ]
10763            (const_string "ishift")))
10764    (set_attr "mode" "SI")])
10766 (define_insn "*ashlsi3_cconly"
10767   [(set (reg FLAGS_REG)
10768         (compare
10769           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10770                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10771           (const_int 0)))
10772    (clobber (match_scratch:SI 0 "=r"))]
10773   "ix86_match_ccmode (insn, CCGOCmode)
10774    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10775    && (optimize_size
10776        || !TARGET_PARTIAL_FLAG_REG_STALL
10777        || (operands[2] == const1_rtx
10778            && (TARGET_SHIFT1
10779                || TARGET_DOUBLE_WITH_ADD)))"
10781   switch (get_attr_type (insn))
10782     {
10783     case TYPE_ALU:
10784       gcc_assert (operands[2] == const1_rtx);
10785       return "add{l}\t{%0, %0|%0, %0}";
10787     default:
10788       if (REG_P (operands[2]))
10789         return "sal{l}\t{%b2, %0|%0, %b2}";
10790       else if (operands[2] == const1_rtx
10791                && (TARGET_SHIFT1 || optimize_size))
10792         return "sal{l}\t%0";
10793       else
10794         return "sal{l}\t{%2, %0|%0, %2}";
10795     }
10797   [(set (attr "type")
10798      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10799                           (const_int 0))
10800                       (match_operand 0 "register_operand" ""))
10801                  (match_operand 2 "const1_operand" ""))
10802               (const_string "alu")
10803            ]
10804            (const_string "ishift")))
10805    (set_attr "mode" "SI")])
10807 (define_insn "*ashlsi3_cmp_zext"
10808   [(set (reg FLAGS_REG)
10809         (compare
10810           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10811                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10812           (const_int 0)))
10813    (set (match_operand:DI 0 "register_operand" "=r")
10814         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10815   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10816    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10817    && (optimize_size
10818        || !TARGET_PARTIAL_FLAG_REG_STALL
10819        || (operands[2] == const1_rtx
10820            && (TARGET_SHIFT1
10821                || TARGET_DOUBLE_WITH_ADD)))"
10823   switch (get_attr_type (insn))
10824     {
10825     case TYPE_ALU:
10826       gcc_assert (operands[2] == const1_rtx);
10827       return "add{l}\t{%k0, %k0|%k0, %k0}";
10829     default:
10830       if (REG_P (operands[2]))
10831         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10832       else if (operands[2] == const1_rtx
10833                && (TARGET_SHIFT1 || optimize_size))
10834         return "sal{l}\t%k0";
10835       else
10836         return "sal{l}\t{%2, %k0|%k0, %2}";
10837     }
10839   [(set (attr "type")
10840      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10841                      (const_int 0))
10842                  (match_operand 2 "const1_operand" ""))
10843               (const_string "alu")
10844            ]
10845            (const_string "ishift")))
10846    (set_attr "mode" "SI")])
10848 (define_expand "ashlhi3"
10849   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10850         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10851                    (match_operand:QI 2 "nonmemory_operand" "")))
10852    (clobber (reg:CC FLAGS_REG))]
10853   "TARGET_HIMODE_MATH"
10854   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10856 (define_insn "*ashlhi3_1_lea"
10857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10858         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10859                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "!TARGET_PARTIAL_REG_STALL
10862    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10864   switch (get_attr_type (insn))
10865     {
10866     case TYPE_LEA:
10867       return "#";
10868     case TYPE_ALU:
10869       gcc_assert (operands[2] == const1_rtx);
10870       return "add{w}\t{%0, %0|%0, %0}";
10872     default:
10873       if (REG_P (operands[2]))
10874         return "sal{w}\t{%b2, %0|%0, %b2}";
10875       else if (operands[2] == const1_rtx
10876                && (TARGET_SHIFT1 || optimize_size))
10877         return "sal{w}\t%0";
10878       else
10879         return "sal{w}\t{%2, %0|%0, %2}";
10880     }
10882   [(set (attr "type")
10883      (cond [(eq_attr "alternative" "1")
10884               (const_string "lea")
10885             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10886                           (const_int 0))
10887                       (match_operand 0 "register_operand" ""))
10888                  (match_operand 2 "const1_operand" ""))
10889               (const_string "alu")
10890            ]
10891            (const_string "ishift")))
10892    (set_attr "mode" "HI,SI")])
10894 (define_insn "*ashlhi3_1"
10895   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10896         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10897                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_PARTIAL_REG_STALL
10900    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10902   switch (get_attr_type (insn))
10903     {
10904     case TYPE_ALU:
10905       gcc_assert (operands[2] == const1_rtx);
10906       return "add{w}\t{%0, %0|%0, %0}";
10908     default:
10909       if (REG_P (operands[2]))
10910         return "sal{w}\t{%b2, %0|%0, %b2}";
10911       else if (operands[2] == const1_rtx
10912                && (TARGET_SHIFT1 || optimize_size))
10913         return "sal{w}\t%0";
10914       else
10915         return "sal{w}\t{%2, %0|%0, %2}";
10916     }
10918   [(set (attr "type")
10919      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10920                           (const_int 0))
10921                       (match_operand 0 "register_operand" ""))
10922                  (match_operand 2 "const1_operand" ""))
10923               (const_string "alu")
10924            ]
10925            (const_string "ishift")))
10926    (set_attr "mode" "HI")])
10928 ;; This pattern can't accept a variable shift count, since shifts by
10929 ;; zero don't affect the flags.  We assume that shifts by constant
10930 ;; zero are optimized away.
10931 (define_insn "*ashlhi3_cmp"
10932   [(set (reg FLAGS_REG)
10933         (compare
10934           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10935                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10936           (const_int 0)))
10937    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10938         (ashift:HI (match_dup 1) (match_dup 2)))]
10939   "ix86_match_ccmode (insn, CCGOCmode)
10940    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10941    && (optimize_size
10942        || !TARGET_PARTIAL_FLAG_REG_STALL
10943        || (operands[2] == const1_rtx
10944            && (TARGET_SHIFT1
10945                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10947   switch (get_attr_type (insn))
10948     {
10949     case TYPE_ALU:
10950       gcc_assert (operands[2] == const1_rtx);
10951       return "add{w}\t{%0, %0|%0, %0}";
10953     default:
10954       if (REG_P (operands[2]))
10955         return "sal{w}\t{%b2, %0|%0, %b2}";
10956       else if (operands[2] == const1_rtx
10957                && (TARGET_SHIFT1 || optimize_size))
10958         return "sal{w}\t%0";
10959       else
10960         return "sal{w}\t{%2, %0|%0, %2}";
10961     }
10963   [(set (attr "type")
10964      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10965                           (const_int 0))
10966                       (match_operand 0 "register_operand" ""))
10967                  (match_operand 2 "const1_operand" ""))
10968               (const_string "alu")
10969            ]
10970            (const_string "ishift")))
10971    (set_attr "mode" "HI")])
10973 (define_insn "*ashlhi3_cconly"
10974   [(set (reg FLAGS_REG)
10975         (compare
10976           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10977                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10978           (const_int 0)))
10979    (clobber (match_scratch:HI 0 "=r"))]
10980   "ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10982    && (optimize_size
10983        || !TARGET_PARTIAL_FLAG_REG_STALL
10984        || (operands[2] == const1_rtx
10985            && (TARGET_SHIFT1
10986                || TARGET_DOUBLE_WITH_ADD)))"
10988   switch (get_attr_type (insn))
10989     {
10990     case TYPE_ALU:
10991       gcc_assert (operands[2] == const1_rtx);
10992       return "add{w}\t{%0, %0|%0, %0}";
10994     default:
10995       if (REG_P (operands[2]))
10996         return "sal{w}\t{%b2, %0|%0, %b2}";
10997       else if (operands[2] == const1_rtx
10998                && (TARGET_SHIFT1 || optimize_size))
10999         return "sal{w}\t%0";
11000       else
11001         return "sal{w}\t{%2, %0|%0, %2}";
11002     }
11004   [(set (attr "type")
11005      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11006                           (const_int 0))
11007                       (match_operand 0 "register_operand" ""))
11008                  (match_operand 2 "const1_operand" ""))
11009               (const_string "alu")
11010            ]
11011            (const_string "ishift")))
11012    (set_attr "mode" "HI")])
11014 (define_expand "ashlqi3"
11015   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11016         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11017                    (match_operand:QI 2 "nonmemory_operand" "")))
11018    (clobber (reg:CC FLAGS_REG))]
11019   "TARGET_QIMODE_MATH"
11020   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11022 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11024 (define_insn "*ashlqi3_1_lea"
11025   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11026         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11027                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11028    (clobber (reg:CC FLAGS_REG))]
11029   "!TARGET_PARTIAL_REG_STALL
11030    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11032   switch (get_attr_type (insn))
11033     {
11034     case TYPE_LEA:
11035       return "#";
11036     case TYPE_ALU:
11037       gcc_assert (operands[2] == const1_rtx);
11038       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11039         return "add{l}\t{%k0, %k0|%k0, %k0}";
11040       else
11041         return "add{b}\t{%0, %0|%0, %0}";
11043     default:
11044       if (REG_P (operands[2]))
11045         {
11046           if (get_attr_mode (insn) == MODE_SI)
11047             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11048           else
11049             return "sal{b}\t{%b2, %0|%0, %b2}";
11050         }
11051       else if (operands[2] == const1_rtx
11052                && (TARGET_SHIFT1 || optimize_size))
11053         {
11054           if (get_attr_mode (insn) == MODE_SI)
11055             return "sal{l}\t%0";
11056           else
11057             return "sal{b}\t%0";
11058         }
11059       else
11060         {
11061           if (get_attr_mode (insn) == MODE_SI)
11062             return "sal{l}\t{%2, %k0|%k0, %2}";
11063           else
11064             return "sal{b}\t{%2, %0|%0, %2}";
11065         }
11066     }
11068   [(set (attr "type")
11069      (cond [(eq_attr "alternative" "2")
11070               (const_string "lea")
11071             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11072                           (const_int 0))
11073                       (match_operand 0 "register_operand" ""))
11074                  (match_operand 2 "const1_operand" ""))
11075               (const_string "alu")
11076            ]
11077            (const_string "ishift")))
11078    (set_attr "mode" "QI,SI,SI")])
11080 (define_insn "*ashlqi3_1"
11081   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11082         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11083                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11084    (clobber (reg:CC FLAGS_REG))]
11085   "TARGET_PARTIAL_REG_STALL
11086    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11088   switch (get_attr_type (insn))
11089     {
11090     case TYPE_ALU:
11091       gcc_assert (operands[2] == const1_rtx);
11092       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11093         return "add{l}\t{%k0, %k0|%k0, %k0}";
11094       else
11095         return "add{b}\t{%0, %0|%0, %0}";
11097     default:
11098       if (REG_P (operands[2]))
11099         {
11100           if (get_attr_mode (insn) == MODE_SI)
11101             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11102           else
11103             return "sal{b}\t{%b2, %0|%0, %b2}";
11104         }
11105       else if (operands[2] == const1_rtx
11106                && (TARGET_SHIFT1 || optimize_size))
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t%0";
11110           else
11111             return "sal{b}\t%0";
11112         }
11113       else
11114         {
11115           if (get_attr_mode (insn) == MODE_SI)
11116             return "sal{l}\t{%2, %k0|%k0, %2}";
11117           else
11118             return "sal{b}\t{%2, %0|%0, %2}";
11119         }
11120     }
11122   [(set (attr "type")
11123      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                           (const_int 0))
11125                       (match_operand 0 "register_operand" ""))
11126                  (match_operand 2 "const1_operand" ""))
11127               (const_string "alu")
11128            ]
11129            (const_string "ishift")))
11130    (set_attr "mode" "QI,SI")])
11132 ;; This pattern can't accept a variable shift count, since shifts by
11133 ;; zero don't affect the flags.  We assume that shifts by constant
11134 ;; zero are optimized away.
11135 (define_insn "*ashlqi3_cmp"
11136   [(set (reg FLAGS_REG)
11137         (compare
11138           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11139                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11140           (const_int 0)))
11141    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11142         (ashift:QI (match_dup 1) (match_dup 2)))]
11143   "ix86_match_ccmode (insn, CCGOCmode)
11144    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11145    && (optimize_size
11146        || !TARGET_PARTIAL_FLAG_REG_STALL
11147        || (operands[2] == const1_rtx
11148            && (TARGET_SHIFT1
11149                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11151   switch (get_attr_type (insn))
11152     {
11153     case TYPE_ALU:
11154       gcc_assert (operands[2] == const1_rtx);
11155       return "add{b}\t{%0, %0|%0, %0}";
11157     default:
11158       if (REG_P (operands[2]))
11159         return "sal{b}\t{%b2, %0|%0, %b2}";
11160       else if (operands[2] == const1_rtx
11161                && (TARGET_SHIFT1 || optimize_size))
11162         return "sal{b}\t%0";
11163       else
11164         return "sal{b}\t{%2, %0|%0, %2}";
11165     }
11167   [(set (attr "type")
11168      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169                           (const_int 0))
11170                       (match_operand 0 "register_operand" ""))
11171                  (match_operand 2 "const1_operand" ""))
11172               (const_string "alu")
11173            ]
11174            (const_string "ishift")))
11175    (set_attr "mode" "QI")])
11177 (define_insn "*ashlqi3_cconly"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11181                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11182           (const_int 0)))
11183    (clobber (match_scratch:QI 0 "=q"))]
11184   "ix86_match_ccmode (insn, CCGOCmode)
11185    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11186    && (optimize_size
11187        || !TARGET_PARTIAL_FLAG_REG_STALL
11188        || (operands[2] == const1_rtx
11189            && (TARGET_SHIFT1
11190                || TARGET_DOUBLE_WITH_ADD)))"
11192   switch (get_attr_type (insn))
11193     {
11194     case TYPE_ALU:
11195       gcc_assert (operands[2] == const1_rtx);
11196       return "add{b}\t{%0, %0|%0, %0}";
11198     default:
11199       if (REG_P (operands[2]))
11200         return "sal{b}\t{%b2, %0|%0, %b2}";
11201       else if (operands[2] == const1_rtx
11202                && (TARGET_SHIFT1 || optimize_size))
11203         return "sal{b}\t%0";
11204       else
11205         return "sal{b}\t{%2, %0|%0, %2}";
11206     }
11208   [(set (attr "type")
11209      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11210                           (const_int 0))
11211                       (match_operand 0 "register_operand" ""))
11212                  (match_operand 2 "const1_operand" ""))
11213               (const_string "alu")
11214            ]
11215            (const_string "ishift")))
11216    (set_attr "mode" "QI")])
11218 ;; See comment above `ashldi3' about how this works.
11220 (define_expand "ashrti3"
11221   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11222                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11223                                 (match_operand:QI 2 "nonmemory_operand" "")))
11224               (clobber (reg:CC FLAGS_REG))])]
11225   "TARGET_64BIT"
11227   if (! immediate_operand (operands[2], QImode))
11228     {
11229       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11230       DONE;
11231     }
11232   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11233   DONE;
11236 (define_insn "ashrti3_1"
11237   [(set (match_operand:TI 0 "register_operand" "=r")
11238         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11239                      (match_operand:QI 2 "register_operand" "c")))
11240    (clobber (match_scratch:DI 3 "=&r"))
11241    (clobber (reg:CC FLAGS_REG))]
11242   "TARGET_64BIT"
11243   "#"
11244   [(set_attr "type" "multi")])
11246 (define_insn "*ashrti3_2"
11247   [(set (match_operand:TI 0 "register_operand" "=r")
11248         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11249                      (match_operand:QI 2 "immediate_operand" "O")))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "TARGET_64BIT"
11252   "#"
11253   [(set_attr "type" "multi")])
11255 (define_split
11256   [(set (match_operand:TI 0 "register_operand" "")
11257         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11258                      (match_operand:QI 2 "register_operand" "")))
11259    (clobber (match_scratch:DI 3 ""))
11260    (clobber (reg:CC FLAGS_REG))]
11261   "TARGET_64BIT && reload_completed"
11262   [(const_int 0)]
11263   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11265 (define_split
11266   [(set (match_operand:TI 0 "register_operand" "")
11267         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11268                      (match_operand:QI 2 "immediate_operand" "")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "TARGET_64BIT && reload_completed"
11271   [(const_int 0)]
11272   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11274 (define_insn "x86_64_shrd"
11275   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11276         (ior:DI (ashiftrt:DI (match_dup 0)
11277                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11278                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11279                   (minus:QI (const_int 64) (match_dup 2)))))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "TARGET_64BIT"
11282   "@
11283    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11284    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11285   [(set_attr "type" "ishift")
11286    (set_attr "prefix_0f" "1")
11287    (set_attr "mode" "DI")
11288    (set_attr "athlon_decode" "vector")])
11290 (define_expand "ashrdi3"
11291   [(set (match_operand:DI 0 "shiftdi_operand" "")
11292         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))]
11294   ""
11295   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11297 (define_insn "*ashrdi3_63_rex64"
11298   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11299         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11300                      (match_operand:DI 2 "const_int_operand" "i,i")))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_64BIT && INTVAL (operands[2]) == 63
11303    && (TARGET_USE_CLTD || optimize_size)
11304    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11305   "@
11306    {cqto|cqo}
11307    sar{q}\t{%2, %0|%0, %2}"
11308   [(set_attr "type" "imovx,ishift")
11309    (set_attr "prefix_0f" "0,*")
11310    (set_attr "length_immediate" "0,*")
11311    (set_attr "modrm" "0,1")
11312    (set_attr "mode" "DI")])
11314 (define_insn "*ashrdi3_1_one_bit_rex64"
11315   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11316         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const1_operand" "")))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{q}\t%0"
11322   [(set_attr "type" "ishift")
11323    (set (attr "length") 
11324      (if_then_else (match_operand:DI 0 "register_operand" "") 
11325         (const_string "2")
11326         (const_string "*")))])
11328 (define_insn "*ashrdi3_1_rex64"
11329   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11330         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11331                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11334   "@
11335    sar{q}\t{%2, %0|%0, %2}
11336    sar{q}\t{%b2, %0|%0, %b2}"
11337   [(set_attr "type" "ishift")
11338    (set_attr "mode" "DI")])
11340 ;; This pattern can't accept a variable shift count, since shifts by
11341 ;; zero don't affect the flags.  We assume that shifts by constant
11342 ;; zero are optimized away.
11343 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11344   [(set (reg FLAGS_REG)
11345         (compare
11346           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347                        (match_operand:QI 2 "const1_operand" ""))
11348           (const_int 0)))
11349    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11350         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11351   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11352    && (TARGET_SHIFT1 || optimize_size)
11353    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354   "sar{q}\t%0"
11355   [(set_attr "type" "ishift")
11356    (set (attr "length") 
11357      (if_then_else (match_operand:DI 0 "register_operand" "") 
11358         (const_string "2")
11359         (const_string "*")))])
11361 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365                        (match_operand:QI 2 "const1_operand" ""))
11366           (const_int 0)))
11367    (clobber (match_scratch:DI 0 "=r"))]
11368   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11369    && (TARGET_SHIFT1 || optimize_size)
11370    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11371   "sar{q}\t%0"
11372   [(set_attr "type" "ishift")
11373    (set_attr "length" "2")])
11375 ;; This pattern can't accept a variable shift count, since shifts by
11376 ;; zero don't affect the flags.  We assume that shifts by constant
11377 ;; zero are optimized away.
11378 (define_insn "*ashrdi3_cmp_rex64"
11379   [(set (reg FLAGS_REG)
11380         (compare
11381           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11382                        (match_operand:QI 2 "const_int_operand" "n"))
11383           (const_int 0)))
11384    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11386   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11387    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11388    && (optimize_size
11389        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11390   "sar{q}\t{%2, %0|%0, %2}"
11391   [(set_attr "type" "ishift")
11392    (set_attr "mode" "DI")])
11394 (define_insn "*ashrdi3_cconly_rex64"
11395   [(set (reg FLAGS_REG)
11396         (compare
11397           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11398                        (match_operand:QI 2 "const_int_operand" "n"))
11399           (const_int 0)))
11400    (clobber (match_scratch:DI 0 "=r"))]
11401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11403    && (optimize_size
11404        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11405   "sar{q}\t{%2, %0|%0, %2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "DI")])
11409 (define_insn "*ashrdi3_1"
11410   [(set (match_operand:DI 0 "register_operand" "=r")
11411         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11412                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "!TARGET_64BIT"
11415   "#"
11416   [(set_attr "type" "multi")])
11418 ;; By default we don't ask for a scratch register, because when DImode
11419 ;; values are manipulated, registers are already at a premium.  But if
11420 ;; we have one handy, we won't turn it away.
11421 (define_peephole2
11422   [(match_scratch:SI 3 "r")
11423    (parallel [(set (match_operand:DI 0 "register_operand" "")
11424                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11425                                 (match_operand:QI 2 "nonmemory_operand" "")))
11426               (clobber (reg:CC FLAGS_REG))])
11427    (match_dup 3)]
11428   "!TARGET_64BIT && TARGET_CMOVE"
11429   [(const_int 0)]
11430   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11432 (define_split
11433   [(set (match_operand:DI 0 "register_operand" "")
11434         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11435                      (match_operand:QI 2 "nonmemory_operand" "")))
11436    (clobber (reg:CC FLAGS_REG))]
11437   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11438                      ? flow2_completed : reload_completed)"
11439   [(const_int 0)]
11440   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11442 (define_insn "x86_shrd_1"
11443   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11444         (ior:SI (ashiftrt:SI (match_dup 0)
11445                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11446                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11447                   (minus:QI (const_int 32) (match_dup 2)))))
11448    (clobber (reg:CC FLAGS_REG))]
11449   ""
11450   "@
11451    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11452    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11453   [(set_attr "type" "ishift")
11454    (set_attr "prefix_0f" "1")
11455    (set_attr "pent_pair" "np")
11456    (set_attr "mode" "SI")])
11458 (define_expand "x86_shift_adj_3"
11459   [(use (match_operand:SI 0 "register_operand" ""))
11460    (use (match_operand:SI 1 "register_operand" ""))
11461    (use (match_operand:QI 2 "register_operand" ""))]
11462   ""
11464   rtx label = gen_label_rtx ();
11465   rtx tmp;
11467   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11469   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11470   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11471   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11472                               gen_rtx_LABEL_REF (VOIDmode, label),
11473                               pc_rtx);
11474   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11475   JUMP_LABEL (tmp) = label;
11477   emit_move_insn (operands[0], operands[1]);
11478   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11480   emit_label (label);
11481   LABEL_NUSES (label) = 1;
11483   DONE;
11486 (define_insn "ashrsi3_31"
11487   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11488         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11489                      (match_operand:SI 2 "const_int_operand" "i,i")))
11490    (clobber (reg:CC FLAGS_REG))]
11491   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11492    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11493   "@
11494    {cltd|cdq}
11495    sar{l}\t{%2, %0|%0, %2}"
11496   [(set_attr "type" "imovx,ishift")
11497    (set_attr "prefix_0f" "0,*")
11498    (set_attr "length_immediate" "0,*")
11499    (set_attr "modrm" "0,1")
11500    (set_attr "mode" "SI")])
11502 (define_insn "*ashrsi3_31_zext"
11503   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11504         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11505                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11506    (clobber (reg:CC FLAGS_REG))]
11507   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11508    && INTVAL (operands[2]) == 31
11509    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11510   "@
11511    {cltd|cdq}
11512    sar{l}\t{%2, %k0|%k0, %2}"
11513   [(set_attr "type" "imovx,ishift")
11514    (set_attr "prefix_0f" "0,*")
11515    (set_attr "length_immediate" "0,*")
11516    (set_attr "modrm" "0,1")
11517    (set_attr "mode" "SI")])
11519 (define_expand "ashrsi3"
11520   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11521         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11522                      (match_operand:QI 2 "nonmemory_operand" "")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   ""
11525   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11527 (define_insn "*ashrsi3_1_one_bit"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11530                      (match_operand:QI 2 "const1_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11533    && (TARGET_SHIFT1 || optimize_size)"
11534   "sar{l}\t%0"
11535   [(set_attr "type" "ishift")
11536    (set (attr "length") 
11537      (if_then_else (match_operand:SI 0 "register_operand" "") 
11538         (const_string "2")
11539         (const_string "*")))])
11541 (define_insn "*ashrsi3_1_one_bit_zext"
11542   [(set (match_operand:DI 0 "register_operand" "=r")
11543         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11544                                      (match_operand:QI 2 "const1_operand" ""))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11547    && (TARGET_SHIFT1 || optimize_size)"
11548   "sar{l}\t%k0"
11549   [(set_attr "type" "ishift")
11550    (set_attr "length" "2")])
11552 (define_insn "*ashrsi3_1"
11553   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11554         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11555                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    sar{l}\t{%2, %0|%0, %2}
11560    sar{l}\t{%b2, %0|%0, %b2}"
11561   [(set_attr "type" "ishift")
11562    (set_attr "mode" "SI")])
11564 (define_insn "*ashrsi3_1_zext"
11565   [(set (match_operand:DI 0 "register_operand" "=r,r")
11566         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11567                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570   "@
11571    sar{l}\t{%2, %k0|%k0, %2}
11572    sar{l}\t{%b2, %k0|%k0, %b2}"
11573   [(set_attr "type" "ishift")
11574    (set_attr "mode" "SI")])
11576 ;; This pattern can't accept a variable shift count, since shifts by
11577 ;; zero don't affect the flags.  We assume that shifts by constant
11578 ;; zero are optimized away.
11579 (define_insn "*ashrsi3_one_bit_cmp"
11580   [(set (reg FLAGS_REG)
11581         (compare
11582           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11583                        (match_operand:QI 2 "const1_operand" ""))
11584           (const_int 0)))
11585    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11586         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11587   "ix86_match_ccmode (insn, CCGOCmode)
11588    && (TARGET_SHIFT1 || optimize_size)
11589    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11590   "sar{l}\t%0"
11591   [(set_attr "type" "ishift")
11592    (set (attr "length") 
11593      (if_then_else (match_operand:SI 0 "register_operand" "") 
11594         (const_string "2")
11595         (const_string "*")))])
11597 (define_insn "*ashrsi3_one_bit_cconly"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601                        (match_operand:QI 2 "const1_operand" ""))
11602           (const_int 0)))
11603    (clobber (match_scratch:SI 0 "=r"))]
11604   "ix86_match_ccmode (insn, CCGOCmode)
11605    && (TARGET_SHIFT1 || optimize_size)
11606    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607   "sar{l}\t%0"
11608   [(set_attr "type" "ishift")
11609    (set_attr "length" "2")])
11611 (define_insn "*ashrsi3_one_bit_cmp_zext"
11612   [(set (reg FLAGS_REG)
11613         (compare
11614           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11615                        (match_operand:QI 2 "const1_operand" ""))
11616           (const_int 0)))
11617    (set (match_operand:DI 0 "register_operand" "=r")
11618         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11619   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11620    && (TARGET_SHIFT1 || optimize_size)
11621    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11622   "sar{l}\t%k0"
11623   [(set_attr "type" "ishift")
11624    (set_attr "length" "2")])
11626 ;; This pattern can't accept a variable shift count, since shifts by
11627 ;; zero don't affect the flags.  We assume that shifts by constant
11628 ;; zero are optimized away.
11629 (define_insn "*ashrsi3_cmp"
11630   [(set (reg FLAGS_REG)
11631         (compare
11632           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11633                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11634           (const_int 0)))
11635    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11636         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11637   "ix86_match_ccmode (insn, CCGOCmode)
11638    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11639    && (optimize_size
11640        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11641   "sar{l}\t{%2, %0|%0, %2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "SI")])
11645 (define_insn "*ashrsi3_cconly"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11650           (const_int 0)))
11651    (clobber (match_scratch:SI 0 "=r"))]
11652   "ix86_match_ccmode (insn, CCGOCmode)
11653    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11654    && (optimize_size
11655        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11656   "sar{l}\t{%2, %0|%0, %2}"
11657   [(set_attr "type" "ishift")
11658    (set_attr "mode" "SI")])
11660 (define_insn "*ashrsi3_cmp_zext"
11661   [(set (reg FLAGS_REG)
11662         (compare
11663           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11665           (const_int 0)))
11666    (set (match_operand:DI 0 "register_operand" "=r")
11667         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11669    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11670    && (optimize_size
11671        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11672   "sar{l}\t{%2, %k0|%k0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "SI")])
11676 (define_expand "ashrhi3"
11677   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11678         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11679                      (match_operand:QI 2 "nonmemory_operand" "")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "TARGET_HIMODE_MATH"
11682   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11684 (define_insn "*ashrhi3_1_one_bit"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11687                      (match_operand:QI 2 "const1_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11690    && (TARGET_SHIFT1 || optimize_size)"
11691   "sar{w}\t%0"
11692   [(set_attr "type" "ishift")
11693    (set (attr "length") 
11694      (if_then_else (match_operand 0 "register_operand" "") 
11695         (const_string "2")
11696         (const_string "*")))])
11698 (define_insn "*ashrhi3_1"
11699   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11700         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11701                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11704   "@
11705    sar{w}\t{%2, %0|%0, %2}
11706    sar{w}\t{%b2, %0|%0, %b2}"
11707   [(set_attr "type" "ishift")
11708    (set_attr "mode" "HI")])
11710 ;; This pattern can't accept a variable shift count, since shifts by
11711 ;; zero don't affect the flags.  We assume that shifts by constant
11712 ;; zero are optimized away.
11713 (define_insn "*ashrhi3_one_bit_cmp"
11714   [(set (reg FLAGS_REG)
11715         (compare
11716           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717                        (match_operand:QI 2 "const1_operand" ""))
11718           (const_int 0)))
11719    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11721   "ix86_match_ccmode (insn, CCGOCmode)
11722    && (TARGET_SHIFT1 || optimize_size)
11723    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11724   "sar{w}\t%0"
11725   [(set_attr "type" "ishift")
11726    (set (attr "length") 
11727      (if_then_else (match_operand 0 "register_operand" "") 
11728         (const_string "2")
11729         (const_string "*")))])
11731 (define_insn "*ashrhi3_one_bit_cconly"
11732   [(set (reg FLAGS_REG)
11733         (compare
11734           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735                        (match_operand:QI 2 "const1_operand" ""))
11736           (const_int 0)))
11737    (clobber (match_scratch:HI 0 "=r"))]
11738   "ix86_match_ccmode (insn, CCGOCmode)
11739    && (TARGET_SHIFT1 || optimize_size)
11740    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11741   "sar{w}\t%0"
11742   [(set_attr "type" "ishift")
11743    (set_attr "length" "2")])
11745 ;; This pattern can't accept a variable shift count, since shifts by
11746 ;; zero don't affect the flags.  We assume that shifts by constant
11747 ;; zero are optimized away.
11748 (define_insn "*ashrhi3_cmp"
11749   [(set (reg FLAGS_REG)
11750         (compare
11751           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11752                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11753           (const_int 0)))
11754    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11755         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11756   "ix86_match_ccmode (insn, CCGOCmode)
11757    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11758    && (optimize_size
11759        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11760   "sar{w}\t{%2, %0|%0, %2}"
11761   [(set_attr "type" "ishift")
11762    (set_attr "mode" "HI")])
11764 (define_insn "*ashrhi3_cconly"
11765   [(set (reg FLAGS_REG)
11766         (compare
11767           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11769           (const_int 0)))
11770    (clobber (match_scratch:HI 0 "=r"))]
11771   "ix86_match_ccmode (insn, CCGOCmode)
11772    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11773    && (optimize_size
11774        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11775   "sar{w}\t{%2, %0|%0, %2}"
11776   [(set_attr "type" "ishift")
11777    (set_attr "mode" "HI")])
11779 (define_expand "ashrqi3"
11780   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11781         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11782                      (match_operand:QI 2 "nonmemory_operand" "")))
11783    (clobber (reg:CC FLAGS_REG))]
11784   "TARGET_QIMODE_MATH"
11785   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11787 (define_insn "*ashrqi3_1_one_bit"
11788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11789         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11790                      (match_operand:QI 2 "const1_operand" "")))
11791    (clobber (reg:CC FLAGS_REG))]
11792   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11793    && (TARGET_SHIFT1 || optimize_size)"
11794   "sar{b}\t%0"
11795   [(set_attr "type" "ishift")
11796    (set (attr "length") 
11797      (if_then_else (match_operand 0 "register_operand" "") 
11798         (const_string "2")
11799         (const_string "*")))])
11801 (define_insn "*ashrqi3_1_one_bit_slp"
11802   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11803         (ashiftrt:QI (match_dup 0)
11804                      (match_operand:QI 1 "const1_operand" "")))
11805    (clobber (reg:CC FLAGS_REG))]
11806   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11807    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11808    && (TARGET_SHIFT1 || optimize_size)"
11809   "sar{b}\t%0"
11810   [(set_attr "type" "ishift1")
11811    (set (attr "length") 
11812      (if_then_else (match_operand 0 "register_operand" "") 
11813         (const_string "2")
11814         (const_string "*")))])
11816 (define_insn "*ashrqi3_1"
11817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11818         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11819                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11820    (clobber (reg:CC FLAGS_REG))]
11821   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11822   "@
11823    sar{b}\t{%2, %0|%0, %2}
11824    sar{b}\t{%b2, %0|%0, %b2}"
11825   [(set_attr "type" "ishift")
11826    (set_attr "mode" "QI")])
11828 (define_insn "*ashrqi3_1_slp"
11829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11830         (ashiftrt:QI (match_dup 0)
11831                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11832    (clobber (reg:CC FLAGS_REG))]
11833   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11834    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11835   "@
11836    sar{b}\t{%1, %0|%0, %1}
11837    sar{b}\t{%b1, %0|%0, %b1}"
11838   [(set_attr "type" "ishift1")
11839    (set_attr "mode" "QI")])
11841 ;; This pattern can't accept a variable shift count, since shifts by
11842 ;; zero don't affect the flags.  We assume that shifts by constant
11843 ;; zero are optimized away.
11844 (define_insn "*ashrqi3_one_bit_cmp"
11845   [(set (reg FLAGS_REG)
11846         (compare
11847           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11848                        (match_operand:QI 2 "const1_operand" "I"))
11849           (const_int 0)))
11850    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11851         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11852   "ix86_match_ccmode (insn, CCGOCmode)
11853    && (TARGET_SHIFT1 || optimize_size)
11854    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11855   "sar{b}\t%0"
11856   [(set_attr "type" "ishift")
11857    (set (attr "length") 
11858      (if_then_else (match_operand 0 "register_operand" "") 
11859         (const_string "2")
11860         (const_string "*")))])
11862 (define_insn "*ashrqi3_one_bit_cconly"
11863   [(set (reg FLAGS_REG)
11864         (compare
11865           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11866                        (match_operand:QI 2 "const1_operand" "I"))
11867           (const_int 0)))
11868    (clobber (match_scratch:QI 0 "=q"))]
11869   "ix86_match_ccmode (insn, CCGOCmode)
11870    && (TARGET_SHIFT1 || optimize_size)
11871    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11872   "sar{b}\t%0"
11873   [(set_attr "type" "ishift")
11874    (set_attr "length" "2")])
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags.  We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*ashrqi3_cmp"
11880   [(set (reg FLAGS_REG)
11881         (compare
11882           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11883                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11884           (const_int 0)))
11885    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11886         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11887   "ix86_match_ccmode (insn, CCGOCmode)
11888    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11889    && (optimize_size
11890        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11891   "sar{b}\t{%2, %0|%0, %2}"
11892   [(set_attr "type" "ishift")
11893    (set_attr "mode" "QI")])
11895 (define_insn "*ashrqi3_cconly"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11899                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11900           (const_int 0)))
11901    (clobber (match_scratch:QI 0 "=q"))]
11902   "ix86_match_ccmode (insn, CCGOCmode)
11903    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11904    && (optimize_size
11905        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11906   "sar{b}\t{%2, %0|%0, %2}"
11907   [(set_attr "type" "ishift")
11908    (set_attr "mode" "QI")])
11911 ;; Logical shift instructions
11913 ;; See comment above `ashldi3' about how this works.
11915 (define_expand "lshrti3"
11916   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11917                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11918                                 (match_operand:QI 2 "nonmemory_operand" "")))
11919               (clobber (reg:CC FLAGS_REG))])]
11920   "TARGET_64BIT"
11922   if (! immediate_operand (operands[2], QImode))
11923     {
11924       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11925       DONE;
11926     }
11927   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11928   DONE;
11931 (define_insn "lshrti3_1"
11932   [(set (match_operand:TI 0 "register_operand" "=r")
11933         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11934                      (match_operand:QI 2 "register_operand" "c")))
11935    (clobber (match_scratch:DI 3 "=&r"))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "TARGET_64BIT"
11938   "#"
11939   [(set_attr "type" "multi")])
11941 (define_insn "*lshrti3_2"
11942   [(set (match_operand:TI 0 "register_operand" "=r")
11943         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11944                      (match_operand:QI 2 "immediate_operand" "O")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "TARGET_64BIT"
11947   "#"
11948   [(set_attr "type" "multi")])
11950 (define_split 
11951   [(set (match_operand:TI 0 "register_operand" "")
11952         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11953                      (match_operand:QI 2 "register_operand" "")))
11954    (clobber (match_scratch:DI 3 ""))
11955    (clobber (reg:CC FLAGS_REG))]
11956   "TARGET_64BIT && reload_completed"
11957   [(const_int 0)]
11958   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11960 (define_split 
11961   [(set (match_operand:TI 0 "register_operand" "")
11962         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11963                      (match_operand:QI 2 "immediate_operand" "")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_64BIT && reload_completed"
11966   [(const_int 0)]
11967   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11969 (define_expand "lshrdi3"
11970   [(set (match_operand:DI 0 "shiftdi_operand" "")
11971         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11972                      (match_operand:QI 2 "nonmemory_operand" "")))]
11973   ""
11974   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11976 (define_insn "*lshrdi3_1_one_bit_rex64"
11977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11978         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11979                      (match_operand:QI 2 "const1_operand" "")))
11980    (clobber (reg:CC FLAGS_REG))]
11981   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11982    && (TARGET_SHIFT1 || optimize_size)"
11983   "shr{q}\t%0"
11984   [(set_attr "type" "ishift")
11985    (set (attr "length") 
11986      (if_then_else (match_operand:DI 0 "register_operand" "") 
11987         (const_string "2")
11988         (const_string "*")))])
11990 (define_insn "*lshrdi3_1_rex64"
11991   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11992         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11993                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996   "@
11997    shr{q}\t{%2, %0|%0, %2}
11998    shr{q}\t{%b2, %0|%0, %b2}"
11999   [(set_attr "type" "ishift")
12000    (set_attr "mode" "DI")])
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags.  We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12006   [(set (reg FLAGS_REG)
12007         (compare
12008           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009                        (match_operand:QI 2 "const1_operand" ""))
12010           (const_int 0)))
12011    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12012         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12013   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12014    && (TARGET_SHIFT1 || optimize_size)
12015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12016   "shr{q}\t%0"
12017   [(set_attr "type" "ishift")
12018    (set (attr "length") 
12019      (if_then_else (match_operand:DI 0 "register_operand" "") 
12020         (const_string "2")
12021         (const_string "*")))])
12023 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12024   [(set (reg FLAGS_REG)
12025         (compare
12026           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027                        (match_operand:QI 2 "const1_operand" ""))
12028           (const_int 0)))
12029    (clobber (match_scratch:DI 0 "=r"))]
12030   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12031    && (TARGET_SHIFT1 || optimize_size)
12032    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12033   "shr{q}\t%0"
12034   [(set_attr "type" "ishift")
12035    (set_attr "length" "2")])
12037 ;; This pattern can't accept a variable shift count, since shifts by
12038 ;; zero don't affect the flags.  We assume that shifts by constant
12039 ;; zero are optimized away.
12040 (define_insn "*lshrdi3_cmp_rex64"
12041   [(set (reg FLAGS_REG)
12042         (compare
12043           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044                        (match_operand:QI 2 "const_int_operand" "e"))
12045           (const_int 0)))
12046    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12048   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12049    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12050    && (optimize_size
12051        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12052   "shr{q}\t{%2, %0|%0, %2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "DI")])
12056 (define_insn "*lshrdi3_cconly_rex64"
12057   [(set (reg FLAGS_REG)
12058         (compare
12059           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                        (match_operand:QI 2 "const_int_operand" "e"))
12061           (const_int 0)))
12062    (clobber (match_scratch:DI 0 "=r"))]
12063   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12064    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12065    && (optimize_size
12066        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12067   "shr{q}\t{%2, %0|%0, %2}"
12068   [(set_attr "type" "ishift")
12069    (set_attr "mode" "DI")])
12071 (define_insn "*lshrdi3_1"
12072   [(set (match_operand:DI 0 "register_operand" "=r")
12073         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12074                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "!TARGET_64BIT"
12077   "#"
12078   [(set_attr "type" "multi")])
12080 ;; By default we don't ask for a scratch register, because when DImode
12081 ;; values are manipulated, registers are already at a premium.  But if
12082 ;; we have one handy, we won't turn it away.
12083 (define_peephole2
12084   [(match_scratch:SI 3 "r")
12085    (parallel [(set (match_operand:DI 0 "register_operand" "")
12086                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12087                                 (match_operand:QI 2 "nonmemory_operand" "")))
12088               (clobber (reg:CC FLAGS_REG))])
12089    (match_dup 3)]
12090   "!TARGET_64BIT && TARGET_CMOVE"
12091   [(const_int 0)]
12092   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12094 (define_split 
12095   [(set (match_operand:DI 0 "register_operand" "")
12096         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12097                      (match_operand:QI 2 "nonmemory_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100                      ? flow2_completed : reload_completed)"
12101   [(const_int 0)]
12102   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12104 (define_expand "lshrsi3"
12105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12106         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12107                      (match_operand:QI 2 "nonmemory_operand" "")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   ""
12110   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12112 (define_insn "*lshrsi3_1_one_bit"
12113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12114         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12115                      (match_operand:QI 2 "const1_operand" "")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12118    && (TARGET_SHIFT1 || optimize_size)"
12119   "shr{l}\t%0"
12120   [(set_attr "type" "ishift")
12121    (set (attr "length") 
12122      (if_then_else (match_operand:SI 0 "register_operand" "") 
12123         (const_string "2")
12124         (const_string "*")))])
12126 (define_insn "*lshrsi3_1_one_bit_zext"
12127   [(set (match_operand:DI 0 "register_operand" "=r")
12128         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12129                      (match_operand:QI 2 "const1_operand" "")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12132    && (TARGET_SHIFT1 || optimize_size)"
12133   "shr{l}\t%k0"
12134   [(set_attr "type" "ishift")
12135    (set_attr "length" "2")])
12137 (define_insn "*lshrsi3_1"
12138   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12139         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12140                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12143   "@
12144    shr{l}\t{%2, %0|%0, %2}
12145    shr{l}\t{%b2, %0|%0, %b2}"
12146   [(set_attr "type" "ishift")
12147    (set_attr "mode" "SI")])
12149 (define_insn "*lshrsi3_1_zext"
12150   [(set (match_operand:DI 0 "register_operand" "=r,r")
12151         (zero_extend:DI
12152           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12153                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12156   "@
12157    shr{l}\t{%2, %k0|%k0, %2}
12158    shr{l}\t{%b2, %k0|%k0, %b2}"
12159   [(set_attr "type" "ishift")
12160    (set_attr "mode" "SI")])
12162 ;; This pattern can't accept a variable shift count, since shifts by
12163 ;; zero don't affect the flags.  We assume that shifts by constant
12164 ;; zero are optimized away.
12165 (define_insn "*lshrsi3_one_bit_cmp"
12166   [(set (reg FLAGS_REG)
12167         (compare
12168           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12169                        (match_operand:QI 2 "const1_operand" ""))
12170           (const_int 0)))
12171    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12172         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12173   "ix86_match_ccmode (insn, CCGOCmode)
12174    && (TARGET_SHIFT1 || optimize_size)
12175    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12176   "shr{l}\t%0"
12177   [(set_attr "type" "ishift")
12178    (set (attr "length") 
12179      (if_then_else (match_operand:SI 0 "register_operand" "") 
12180         (const_string "2")
12181         (const_string "*")))])
12183 (define_insn "*lshrsi3_one_bit_cconly"
12184   [(set (reg FLAGS_REG)
12185         (compare
12186           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12187                        (match_operand:QI 2 "const1_operand" ""))
12188           (const_int 0)))
12189    (clobber (match_scratch:SI 0 "=r"))]
12190   "ix86_match_ccmode (insn, CCGOCmode)
12191    && (TARGET_SHIFT1 || optimize_size)
12192    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193   "shr{l}\t%0"
12194   [(set_attr "type" "ishift")
12195    (set_attr "length" "2")])
12197 (define_insn "*lshrsi3_cmp_one_bit_zext"
12198   [(set (reg FLAGS_REG)
12199         (compare
12200           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12201                        (match_operand:QI 2 "const1_operand" ""))
12202           (const_int 0)))
12203    (set (match_operand:DI 0 "register_operand" "=r")
12204         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12205   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12206    && (TARGET_SHIFT1 || optimize_size)
12207    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12208   "shr{l}\t%k0"
12209   [(set_attr "type" "ishift")
12210    (set_attr "length" "2")])
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags.  We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*lshrsi3_cmp"
12216   [(set (reg FLAGS_REG)
12217         (compare
12218           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12219                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12220           (const_int 0)))
12221    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12222         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12225    && (optimize_size
12226        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12227   "shr{l}\t{%2, %0|%0, %2}"
12228   [(set_attr "type" "ishift")
12229    (set_attr "mode" "SI")])
12231 (define_insn "*lshrsi3_cconly"
12232   [(set (reg FLAGS_REG)
12233       (compare
12234         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12236         (const_int 0)))
12237    (clobber (match_scratch:SI 0 "=r"))]
12238   "ix86_match_ccmode (insn, CCGOCmode)
12239    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12240    && (optimize_size
12241        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12242   "shr{l}\t{%2, %0|%0, %2}"
12243   [(set_attr "type" "ishift")
12244    (set_attr "mode" "SI")])
12246 (define_insn "*lshrsi3_cmp_zext"
12247   [(set (reg FLAGS_REG)
12248         (compare
12249           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12250                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12251           (const_int 0)))
12252    (set (match_operand:DI 0 "register_operand" "=r")
12253         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12254   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12256    && (optimize_size
12257        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12258   "shr{l}\t{%2, %k0|%k0, %2}"
12259   [(set_attr "type" "ishift")
12260    (set_attr "mode" "SI")])
12262 (define_expand "lshrhi3"
12263   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12264         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12265                      (match_operand:QI 2 "nonmemory_operand" "")))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "TARGET_HIMODE_MATH"
12268   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12270 (define_insn "*lshrhi3_1_one_bit"
12271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12272         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12273                      (match_operand:QI 2 "const1_operand" "")))
12274    (clobber (reg:CC FLAGS_REG))]
12275   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12276    && (TARGET_SHIFT1 || optimize_size)"
12277   "shr{w}\t%0"
12278   [(set_attr "type" "ishift")
12279    (set (attr "length") 
12280      (if_then_else (match_operand 0 "register_operand" "") 
12281         (const_string "2")
12282         (const_string "*")))])
12284 (define_insn "*lshrhi3_1"
12285   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12286         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12288    (clobber (reg:CC FLAGS_REG))]
12289   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12290   "@
12291    shr{w}\t{%2, %0|%0, %2}
12292    shr{w}\t{%b2, %0|%0, %b2}"
12293   [(set_attr "type" "ishift")
12294    (set_attr "mode" "HI")])
12296 ;; This pattern can't accept a variable shift count, since shifts by
12297 ;; zero don't affect the flags.  We assume that shifts by constant
12298 ;; zero are optimized away.
12299 (define_insn "*lshrhi3_one_bit_cmp"
12300   [(set (reg FLAGS_REG)
12301         (compare
12302           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12303                        (match_operand:QI 2 "const1_operand" ""))
12304           (const_int 0)))
12305    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12306         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12307   "ix86_match_ccmode (insn, CCGOCmode)
12308    && (TARGET_SHIFT1 || optimize_size)
12309    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12310   "shr{w}\t%0"
12311   [(set_attr "type" "ishift")
12312    (set (attr "length") 
12313      (if_then_else (match_operand:SI 0 "register_operand" "") 
12314         (const_string "2")
12315         (const_string "*")))])
12317 (define_insn "*lshrhi3_one_bit_cconly"
12318   [(set (reg FLAGS_REG)
12319         (compare
12320           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321                        (match_operand:QI 2 "const1_operand" ""))
12322           (const_int 0)))
12323    (clobber (match_scratch:HI 0 "=r"))]
12324   "ix86_match_ccmode (insn, CCGOCmode)
12325    && (TARGET_SHIFT1 || optimize_size)
12326    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12327   "shr{w}\t%0"
12328   [(set_attr "type" "ishift")
12329    (set_attr "length" "2")])
12331 ;; This pattern can't accept a variable shift count, since shifts by
12332 ;; zero don't affect the flags.  We assume that shifts by constant
12333 ;; zero are optimized away.
12334 (define_insn "*lshrhi3_cmp"
12335   [(set (reg FLAGS_REG)
12336         (compare
12337           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12339           (const_int 0)))
12340    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12341         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12342   "ix86_match_ccmode (insn, CCGOCmode)
12343    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12344    && (optimize_size
12345        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12346   "shr{w}\t{%2, %0|%0, %2}"
12347   [(set_attr "type" "ishift")
12348    (set_attr "mode" "HI")])
12350 (define_insn "*lshrhi3_cconly"
12351   [(set (reg FLAGS_REG)
12352         (compare
12353           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12355           (const_int 0)))
12356    (clobber (match_scratch:HI 0 "=r"))]
12357   "ix86_match_ccmode (insn, CCGOCmode)
12358    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12359    && (optimize_size
12360        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12361   "shr{w}\t{%2, %0|%0, %2}"
12362   [(set_attr "type" "ishift")
12363    (set_attr "mode" "HI")])
12365 (define_expand "lshrqi3"
12366   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12367         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12368                      (match_operand:QI 2 "nonmemory_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_QIMODE_MATH"
12371   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12373 (define_insn "*lshrqi3_1_one_bit"
12374   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12375         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12376                      (match_operand:QI 2 "const1_operand" "")))
12377    (clobber (reg:CC FLAGS_REG))]
12378   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12379    && (TARGET_SHIFT1 || optimize_size)"
12380   "shr{b}\t%0"
12381   [(set_attr "type" "ishift")
12382    (set (attr "length") 
12383      (if_then_else (match_operand 0 "register_operand" "") 
12384         (const_string "2")
12385         (const_string "*")))])
12387 (define_insn "*lshrqi3_1_one_bit_slp"
12388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389         (lshiftrt:QI (match_dup 0)
12390                      (match_operand:QI 1 "const1_operand" "")))
12391    (clobber (reg:CC FLAGS_REG))]
12392   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12393    && (TARGET_SHIFT1 || optimize_size)"
12394   "shr{b}\t%0"
12395   [(set_attr "type" "ishift1")
12396    (set (attr "length") 
12397      (if_then_else (match_operand 0 "register_operand" "") 
12398         (const_string "2")
12399         (const_string "*")))])
12401 (define_insn "*lshrqi3_1"
12402   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12403         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12404                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12407   "@
12408    shr{b}\t{%2, %0|%0, %2}
12409    shr{b}\t{%b2, %0|%0, %b2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "QI")])
12413 (define_insn "*lshrqi3_1_slp"
12414   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12415         (lshiftrt:QI (match_dup 0)
12416                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12419    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12420   "@
12421    shr{b}\t{%1, %0|%0, %1}
12422    shr{b}\t{%b1, %0|%0, %b1}"
12423   [(set_attr "type" "ishift1")
12424    (set_attr "mode" "QI")])
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags.  We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrqi2_one_bit_cmp"
12430   [(set (reg FLAGS_REG)
12431         (compare
12432           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12433                        (match_operand:QI 2 "const1_operand" ""))
12434           (const_int 0)))
12435    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12436         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12437   "ix86_match_ccmode (insn, CCGOCmode)
12438    && (TARGET_SHIFT1 || optimize_size)
12439    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12440   "shr{b}\t%0"
12441   [(set_attr "type" "ishift")
12442    (set (attr "length") 
12443      (if_then_else (match_operand:SI 0 "register_operand" "") 
12444         (const_string "2")
12445         (const_string "*")))])
12447 (define_insn "*lshrqi2_one_bit_cconly"
12448   [(set (reg FLAGS_REG)
12449         (compare
12450           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12451                        (match_operand:QI 2 "const1_operand" ""))
12452           (const_int 0)))
12453    (clobber (match_scratch:QI 0 "=q"))]
12454   "ix86_match_ccmode (insn, CCGOCmode)
12455    && (TARGET_SHIFT1 || optimize_size)
12456    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12457   "shr{b}\t%0"
12458   [(set_attr "type" "ishift")
12459    (set_attr "length" "2")])
12461 ;; This pattern can't accept a variable shift count, since shifts by
12462 ;; zero don't affect the flags.  We assume that shifts by constant
12463 ;; zero are optimized away.
12464 (define_insn "*lshrqi2_cmp"
12465   [(set (reg FLAGS_REG)
12466         (compare
12467           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12468                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469           (const_int 0)))
12470    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12471         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12472   "ix86_match_ccmode (insn, CCGOCmode)
12473    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474    && (optimize_size
12475        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12476   "shr{b}\t{%2, %0|%0, %2}"
12477   [(set_attr "type" "ishift")
12478    (set_attr "mode" "QI")])
12480 (define_insn "*lshrqi2_cconly"
12481   [(set (reg FLAGS_REG)
12482         (compare
12483           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12484                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12485           (const_int 0)))
12486    (clobber (match_scratch:QI 0 "=q"))]
12487   "ix86_match_ccmode (insn, CCGOCmode)
12488    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12489    && (optimize_size
12490        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12491   "shr{b}\t{%2, %0|%0, %2}"
12492   [(set_attr "type" "ishift")
12493    (set_attr "mode" "QI")])
12495 ;; Rotate instructions
12497 (define_expand "rotldi3"
12498   [(set (match_operand:DI 0 "shiftdi_operand" "")
12499         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12500                    (match_operand:QI 2 "nonmemory_operand" "")))
12501    (clobber (reg:CC FLAGS_REG))]
12502  ""
12504   if (TARGET_64BIT)
12505     {
12506       ix86_expand_binary_operator (ROTATE, DImode, operands);
12507       DONE;
12508     }
12509   if (!const_1_to_31_operand (operands[2], VOIDmode))
12510     FAIL;
12511   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12512   DONE;
12515 ;; Implement rotation using two double-precision shift instructions
12516 ;; and a scratch register.   
12517 (define_insn_and_split "ix86_rotldi3"
12518  [(set (match_operand:DI 0 "register_operand" "=r")
12519        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12520                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12521   (clobber (reg:CC FLAGS_REG))
12522   (clobber (match_scratch:SI 3 "=&r"))]
12523  "!TARGET_64BIT"
12524  "" 
12525  "&& reload_completed"
12526  [(set (match_dup 3) (match_dup 4))
12527   (parallel
12528    [(set (match_dup 4)
12529          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12530                  (lshiftrt:SI (match_dup 5)
12531                               (minus:QI (const_int 32) (match_dup 2)))))
12532     (clobber (reg:CC FLAGS_REG))])
12533   (parallel
12534    [(set (match_dup 5)
12535          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12536                  (lshiftrt:SI (match_dup 3)
12537                               (minus:QI (const_int 32) (match_dup 2)))))
12538     (clobber (reg:CC FLAGS_REG))])]
12539  "split_di (operands, 1, operands + 4, operands + 5);")
12541 (define_insn "*rotlsi3_1_one_bit_rex64"
12542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12543         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12544                    (match_operand:QI 2 "const1_operand" "")))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12547    && (TARGET_SHIFT1 || optimize_size)"
12548   "rol{q}\t%0"
12549   [(set_attr "type" "rotate")
12550    (set (attr "length") 
12551      (if_then_else (match_operand:DI 0 "register_operand" "") 
12552         (const_string "2")
12553         (const_string "*")))])
12555 (define_insn "*rotldi3_1_rex64"
12556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12557         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12558                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12559    (clobber (reg:CC FLAGS_REG))]
12560   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12561   "@
12562    rol{q}\t{%2, %0|%0, %2}
12563    rol{q}\t{%b2, %0|%0, %b2}"
12564   [(set_attr "type" "rotate")
12565    (set_attr "mode" "DI")])
12567 (define_expand "rotlsi3"
12568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12569         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12570                    (match_operand:QI 2 "nonmemory_operand" "")))
12571    (clobber (reg:CC FLAGS_REG))]
12572   ""
12573   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12575 (define_insn "*rotlsi3_1_one_bit"
12576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12577         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12578                    (match_operand:QI 2 "const1_operand" "")))
12579    (clobber (reg:CC FLAGS_REG))]
12580   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12581    && (TARGET_SHIFT1 || optimize_size)"
12582   "rol{l}\t%0"
12583   [(set_attr "type" "rotate")
12584    (set (attr "length") 
12585      (if_then_else (match_operand:SI 0 "register_operand" "") 
12586         (const_string "2")
12587         (const_string "*")))])
12589 (define_insn "*rotlsi3_1_one_bit_zext"
12590   [(set (match_operand:DI 0 "register_operand" "=r")
12591         (zero_extend:DI
12592           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12593                      (match_operand:QI 2 "const1_operand" ""))))
12594    (clobber (reg:CC FLAGS_REG))]
12595   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12596    && (TARGET_SHIFT1 || optimize_size)"
12597   "rol{l}\t%k0"
12598   [(set_attr "type" "rotate")
12599    (set_attr "length" "2")])
12601 (define_insn "*rotlsi3_1"
12602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12603         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12604                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12605    (clobber (reg:CC FLAGS_REG))]
12606   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12607   "@
12608    rol{l}\t{%2, %0|%0, %2}
12609    rol{l}\t{%b2, %0|%0, %b2}"
12610   [(set_attr "type" "rotate")
12611    (set_attr "mode" "SI")])
12613 (define_insn "*rotlsi3_1_zext"
12614   [(set (match_operand:DI 0 "register_operand" "=r,r")
12615         (zero_extend:DI
12616           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12617                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12618    (clobber (reg:CC FLAGS_REG))]
12619   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12620   "@
12621    rol{l}\t{%2, %k0|%k0, %2}
12622    rol{l}\t{%b2, %k0|%k0, %b2}"
12623   [(set_attr "type" "rotate")
12624    (set_attr "mode" "SI")])
12626 (define_expand "rotlhi3"
12627   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12628         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12629                    (match_operand:QI 2 "nonmemory_operand" "")))
12630    (clobber (reg:CC FLAGS_REG))]
12631   "TARGET_HIMODE_MATH"
12632   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12634 (define_insn "*rotlhi3_1_one_bit"
12635   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12636         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12637                    (match_operand:QI 2 "const1_operand" "")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12640    && (TARGET_SHIFT1 || optimize_size)"
12641   "rol{w}\t%0"
12642   [(set_attr "type" "rotate")
12643    (set (attr "length") 
12644      (if_then_else (match_operand 0 "register_operand" "") 
12645         (const_string "2")
12646         (const_string "*")))])
12648 (define_insn "*rotlhi3_1"
12649   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12650         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12651                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12652    (clobber (reg:CC FLAGS_REG))]
12653   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12654   "@
12655    rol{w}\t{%2, %0|%0, %2}
12656    rol{w}\t{%b2, %0|%0, %b2}"
12657   [(set_attr "type" "rotate")
12658    (set_attr "mode" "HI")])
12660 (define_expand "rotlqi3"
12661   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12662         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12663                    (match_operand:QI 2 "nonmemory_operand" "")))
12664    (clobber (reg:CC FLAGS_REG))]
12665   "TARGET_QIMODE_MATH"
12666   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12668 (define_insn "*rotlqi3_1_one_bit_slp"
12669   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12670         (rotate:QI (match_dup 0)
12671                    (match_operand:QI 1 "const1_operand" "")))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12674    && (TARGET_SHIFT1 || optimize_size)"
12675   "rol{b}\t%0"
12676   [(set_attr "type" "rotate1")
12677    (set (attr "length") 
12678      (if_then_else (match_operand 0 "register_operand" "") 
12679         (const_string "2")
12680         (const_string "*")))])
12682 (define_insn "*rotlqi3_1_one_bit"
12683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12684         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12685                    (match_operand:QI 2 "const1_operand" "")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12688    && (TARGET_SHIFT1 || optimize_size)"
12689   "rol{b}\t%0"
12690   [(set_attr "type" "rotate")
12691    (set (attr "length") 
12692      (if_then_else (match_operand 0 "register_operand" "") 
12693         (const_string "2")
12694         (const_string "*")))])
12696 (define_insn "*rotlqi3_1_slp"
12697   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12698         (rotate:QI (match_dup 0)
12699                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12703   "@
12704    rol{b}\t{%1, %0|%0, %1}
12705    rol{b}\t{%b1, %0|%0, %b1}"
12706   [(set_attr "type" "rotate1")
12707    (set_attr "mode" "QI")])
12709 (define_insn "*rotlqi3_1"
12710   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12711         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12712                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12713    (clobber (reg:CC FLAGS_REG))]
12714   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12715   "@
12716    rol{b}\t{%2, %0|%0, %2}
12717    rol{b}\t{%b2, %0|%0, %b2}"
12718   [(set_attr "type" "rotate")
12719    (set_attr "mode" "QI")])
12721 (define_expand "rotrdi3"
12722   [(set (match_operand:DI 0 "shiftdi_operand" "")
12723         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12724                    (match_operand:QI 2 "nonmemory_operand" "")))
12725    (clobber (reg:CC FLAGS_REG))]
12726  ""
12728   if (TARGET_64BIT)
12729     {
12730       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12731       DONE;
12732     }
12733   if (!const_1_to_31_operand (operands[2], VOIDmode))
12734     FAIL;
12735   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12736   DONE;
12738   
12739 ;; Implement rotation using two double-precision shift instructions
12740 ;; and a scratch register.   
12741 (define_insn_and_split "ix86_rotrdi3"
12742  [(set (match_operand:DI 0 "register_operand" "=r")
12743        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12744                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12745   (clobber (reg:CC FLAGS_REG))
12746   (clobber (match_scratch:SI 3 "=&r"))]
12747  "!TARGET_64BIT"
12748  ""
12749  "&& reload_completed"
12750  [(set (match_dup 3) (match_dup 4))
12751   (parallel
12752    [(set (match_dup 4)
12753          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12754                  (ashift:SI (match_dup 5)
12755                             (minus:QI (const_int 32) (match_dup 2)))))
12756     (clobber (reg:CC FLAGS_REG))])
12757   (parallel
12758    [(set (match_dup 5)
12759          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12760                  (ashift:SI (match_dup 3)
12761                             (minus:QI (const_int 32) (match_dup 2)))))
12762     (clobber (reg:CC FLAGS_REG))])]
12763  "split_di (operands, 1, operands + 4, operands + 5);")
12765 (define_insn "*rotrdi3_1_one_bit_rex64"
12766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12767         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12768                      (match_operand:QI 2 "const1_operand" "")))
12769    (clobber (reg:CC FLAGS_REG))]
12770   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12771    && (TARGET_SHIFT1 || optimize_size)"
12772   "ror{q}\t%0"
12773   [(set_attr "type" "rotate")
12774    (set (attr "length") 
12775      (if_then_else (match_operand:DI 0 "register_operand" "") 
12776         (const_string "2")
12777         (const_string "*")))])
12779 (define_insn "*rotrdi3_1_rex64"
12780   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12781         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12782                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12785   "@
12786    ror{q}\t{%2, %0|%0, %2}
12787    ror{q}\t{%b2, %0|%0, %b2}"
12788   [(set_attr "type" "rotate")
12789    (set_attr "mode" "DI")])
12791 (define_expand "rotrsi3"
12792   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12793         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12794                      (match_operand:QI 2 "nonmemory_operand" "")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   ""
12797   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12799 (define_insn "*rotrsi3_1_one_bit"
12800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12801         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12802                      (match_operand:QI 2 "const1_operand" "")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12805    && (TARGET_SHIFT1 || optimize_size)"
12806   "ror{l}\t%0"
12807   [(set_attr "type" "rotate")
12808    (set (attr "length") 
12809      (if_then_else (match_operand:SI 0 "register_operand" "") 
12810         (const_string "2")
12811         (const_string "*")))])
12813 (define_insn "*rotrsi3_1_one_bit_zext"
12814   [(set (match_operand:DI 0 "register_operand" "=r")
12815         (zero_extend:DI
12816           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12817                        (match_operand:QI 2 "const1_operand" ""))))
12818    (clobber (reg:CC FLAGS_REG))]
12819   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12820    && (TARGET_SHIFT1 || optimize_size)"
12821   "ror{l}\t%k0"
12822   [(set_attr "type" "rotate")
12823    (set (attr "length") 
12824      (if_then_else (match_operand:SI 0 "register_operand" "") 
12825         (const_string "2")
12826         (const_string "*")))])
12828 (define_insn "*rotrsi3_1"
12829   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12830         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12831                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12832    (clobber (reg:CC FLAGS_REG))]
12833   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12834   "@
12835    ror{l}\t{%2, %0|%0, %2}
12836    ror{l}\t{%b2, %0|%0, %b2}"
12837   [(set_attr "type" "rotate")
12838    (set_attr "mode" "SI")])
12840 (define_insn "*rotrsi3_1_zext"
12841   [(set (match_operand:DI 0 "register_operand" "=r,r")
12842         (zero_extend:DI
12843           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12844                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12845    (clobber (reg:CC FLAGS_REG))]
12846   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12847   "@
12848    ror{l}\t{%2, %k0|%k0, %2}
12849    ror{l}\t{%b2, %k0|%k0, %b2}"
12850   [(set_attr "type" "rotate")
12851    (set_attr "mode" "SI")])
12853 (define_expand "rotrhi3"
12854   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12855         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12856                      (match_operand:QI 2 "nonmemory_operand" "")))
12857    (clobber (reg:CC FLAGS_REG))]
12858   "TARGET_HIMODE_MATH"
12859   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12861 (define_insn "*rotrhi3_one_bit"
12862   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12863         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12864                      (match_operand:QI 2 "const1_operand" "")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12867    && (TARGET_SHIFT1 || optimize_size)"
12868   "ror{w}\t%0"
12869   [(set_attr "type" "rotate")
12870    (set (attr "length") 
12871      (if_then_else (match_operand 0 "register_operand" "") 
12872         (const_string "2")
12873         (const_string "*")))])
12875 (define_insn "*rotrhi3"
12876   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12877         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12878                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12881   "@
12882    ror{w}\t{%2, %0|%0, %2}
12883    ror{w}\t{%b2, %0|%0, %b2}"
12884   [(set_attr "type" "rotate")
12885    (set_attr "mode" "HI")])
12887 (define_expand "rotrqi3"
12888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12889         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12890                      (match_operand:QI 2 "nonmemory_operand" "")))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "TARGET_QIMODE_MATH"
12893   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12895 (define_insn "*rotrqi3_1_one_bit"
12896   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12897         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12898                      (match_operand:QI 2 "const1_operand" "")))
12899    (clobber (reg:CC FLAGS_REG))]
12900   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12901    && (TARGET_SHIFT1 || optimize_size)"
12902   "ror{b}\t%0"
12903   [(set_attr "type" "rotate")
12904    (set (attr "length") 
12905      (if_then_else (match_operand 0 "register_operand" "") 
12906         (const_string "2")
12907         (const_string "*")))])
12909 (define_insn "*rotrqi3_1_one_bit_slp"
12910   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12911         (rotatert:QI (match_dup 0)
12912                      (match_operand:QI 1 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{b}\t%0"
12917   [(set_attr "type" "rotate1")
12918    (set (attr "length") 
12919      (if_then_else (match_operand 0 "register_operand" "") 
12920         (const_string "2")
12921         (const_string "*")))])
12923 (define_insn "*rotrqi3_1"
12924   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12925         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12929   "@
12930    ror{b}\t{%2, %0|%0, %2}
12931    ror{b}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "QI")])
12935 (define_insn "*rotrqi3_1_slp"
12936   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12937         (rotatert:QI (match_dup 0)
12938                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12941    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12942   "@
12943    ror{b}\t{%1, %0|%0, %1}
12944    ror{b}\t{%b1, %0|%0, %b1}"
12945   [(set_attr "type" "rotate1")
12946    (set_attr "mode" "QI")])
12948 ;; Bit set / bit test instructions
12950 (define_expand "extv"
12951   [(set (match_operand:SI 0 "register_operand" "")
12952         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12953                          (match_operand:SI 2 "const8_operand" "")
12954                          (match_operand:SI 3 "const8_operand" "")))]
12955   ""
12957   /* Handle extractions from %ah et al.  */
12958   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12959     FAIL;
12961   /* From mips.md: extract_bit_field doesn't verify that our source
12962      matches the predicate, so check it again here.  */
12963   if (! ext_register_operand (operands[1], VOIDmode))
12964     FAIL;
12967 (define_expand "extzv"
12968   [(set (match_operand:SI 0 "register_operand" "")
12969         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12970                          (match_operand:SI 2 "const8_operand" "")
12971                          (match_operand:SI 3 "const8_operand" "")))]
12972   ""
12974   /* Handle extractions from %ah et al.  */
12975   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12976     FAIL;
12978   /* From mips.md: extract_bit_field doesn't verify that our source
12979      matches the predicate, so check it again here.  */
12980   if (! ext_register_operand (operands[1], VOIDmode))
12981     FAIL;
12984 (define_expand "insv"
12985   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12986                       (match_operand 1 "const8_operand" "")
12987                       (match_operand 2 "const8_operand" ""))
12988         (match_operand 3 "register_operand" ""))]
12989   ""
12991   /* Handle insertions to %ah et al.  */
12992   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12993     FAIL;
12995   /* From mips.md: insert_bit_field doesn't verify that our source
12996      matches the predicate, so check it again here.  */
12997   if (! ext_register_operand (operands[0], VOIDmode))
12998     FAIL;
13000   if (TARGET_64BIT)
13001     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13002   else
13003     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13005   DONE;
13008 ;; %%% bts, btr, btc, bt.
13009 ;; In general these instructions are *slow* when applied to memory,
13010 ;; since they enforce atomic operation.  When applied to registers,
13011 ;; it depends on the cpu implementation.  They're never faster than
13012 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13013 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13014 ;; within the instruction itself, so operating on bits in the high
13015 ;; 32-bits of a register becomes easier.
13017 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13018 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13019 ;; negdf respectively, so they can never be disabled entirely.
13021 (define_insn "*btsq"
13022   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13023                          (const_int 1)
13024                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13025         (const_int 1))
13026    (clobber (reg:CC FLAGS_REG))]
13027   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13028   "bts{q} %1,%0"
13029   [(set_attr "type" "alu1")])
13031 (define_insn "*btrq"
13032   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13033                          (const_int 1)
13034                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13035         (const_int 0))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13038   "btr{q} %1,%0"
13039   [(set_attr "type" "alu1")])
13041 (define_insn "*btcq"
13042   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13043                          (const_int 1)
13044                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13045         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13046    (clobber (reg:CC FLAGS_REG))]
13047   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13048   "btc{q} %1,%0"
13049   [(set_attr "type" "alu1")])
13051 ;; Allow Nocona to avoid these instructions if a register is available.
13053 (define_peephole2
13054   [(match_scratch:DI 2 "r")
13055    (parallel [(set (zero_extract:DI
13056                      (match_operand:DI 0 "register_operand" "")
13057                      (const_int 1)
13058                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13059                    (const_int 1))
13060               (clobber (reg:CC FLAGS_REG))])]
13061   "TARGET_64BIT && !TARGET_USE_BT"
13062   [(const_int 0)]
13064   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13065   rtx op1;
13067   if (HOST_BITS_PER_WIDE_INT >= 64)
13068     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13069   else if (i < HOST_BITS_PER_WIDE_INT)
13070     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13071   else
13072     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13074   op1 = immed_double_const (lo, hi, DImode);
13075   if (i >= 31)
13076     {
13077       emit_move_insn (operands[2], op1);
13078       op1 = operands[2];
13079     }
13081   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13082   DONE;
13085 (define_peephole2
13086   [(match_scratch:DI 2 "r")
13087    (parallel [(set (zero_extract:DI
13088                      (match_operand:DI 0 "register_operand" "")
13089                      (const_int 1)
13090                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13091                    (const_int 0))
13092               (clobber (reg:CC FLAGS_REG))])]
13093   "TARGET_64BIT && !TARGET_USE_BT"
13094   [(const_int 0)]
13096   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13097   rtx op1;
13099   if (HOST_BITS_PER_WIDE_INT >= 64)
13100     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13101   else if (i < HOST_BITS_PER_WIDE_INT)
13102     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13103   else
13104     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13106   op1 = immed_double_const (~lo, ~hi, DImode);
13107   if (i >= 32)
13108     {
13109       emit_move_insn (operands[2], op1);
13110       op1 = operands[2];
13111     }
13113   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13114   DONE;
13117 (define_peephole2
13118   [(match_scratch:DI 2 "r")
13119    (parallel [(set (zero_extract:DI
13120                      (match_operand:DI 0 "register_operand" "")
13121                      (const_int 1)
13122                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13123               (not:DI (zero_extract:DI
13124                         (match_dup 0) (const_int 1) (match_dup 1))))
13125               (clobber (reg:CC FLAGS_REG))])]
13126   "TARGET_64BIT && !TARGET_USE_BT"
13127   [(const_int 0)]
13129   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13130   rtx op1;
13132   if (HOST_BITS_PER_WIDE_INT >= 64)
13133     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134   else if (i < HOST_BITS_PER_WIDE_INT)
13135     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13136   else
13137     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13139   op1 = immed_double_const (lo, hi, DImode);
13140   if (i >= 31)
13141     {
13142       emit_move_insn (operands[2], op1);
13143       op1 = operands[2];
13144     }
13146   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13147   DONE;
13150 ;; Store-flag instructions.
13152 ;; For all sCOND expanders, also expand the compare or test insn that
13153 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13155 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13156 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13157 ;; way, which can later delete the movzx if only QImode is needed.
13159 (define_expand "seq"
13160   [(set (match_operand:QI 0 "register_operand" "")
13161         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13162   ""
13163   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13165 (define_expand "sne"
13166   [(set (match_operand:QI 0 "register_operand" "")
13167         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13168   ""
13169   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13171 (define_expand "sgt"
13172   [(set (match_operand:QI 0 "register_operand" "")
13173         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13174   ""
13175   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13177 (define_expand "sgtu"
13178   [(set (match_operand:QI 0 "register_operand" "")
13179         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13180   ""
13181   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13183 (define_expand "slt"
13184   [(set (match_operand:QI 0 "register_operand" "")
13185         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13186   ""
13187   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13189 (define_expand "sltu"
13190   [(set (match_operand:QI 0 "register_operand" "")
13191         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192   ""
13193   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13195 (define_expand "sge"
13196   [(set (match_operand:QI 0 "register_operand" "")
13197         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198   ""
13199   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13201 (define_expand "sgeu"
13202   [(set (match_operand:QI 0 "register_operand" "")
13203         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204   ""
13205   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13207 (define_expand "sle"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13213 (define_expand "sleu"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13219 (define_expand "sunordered"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   "TARGET_80387 || TARGET_SSE"
13223   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13225 (define_expand "sordered"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   "TARGET_80387"
13229   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13231 (define_expand "suneq"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   "TARGET_80387 || TARGET_SSE"
13235   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13237 (define_expand "sunge"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   "TARGET_80387 || TARGET_SSE"
13241   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13243 (define_expand "sungt"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   "TARGET_80387 || TARGET_SSE"
13247   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13249 (define_expand "sunle"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   "TARGET_80387 || TARGET_SSE"
13253   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13255 (define_expand "sunlt"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   "TARGET_80387 || TARGET_SSE"
13259   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13261 (define_expand "sltgt"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   "TARGET_80387 || TARGET_SSE"
13265   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13267 (define_insn "*setcc_1"
13268   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13269         (match_operator:QI 1 "ix86_comparison_operator"
13270           [(reg FLAGS_REG) (const_int 0)]))]
13271   ""
13272   "set%C1\t%0"
13273   [(set_attr "type" "setcc")
13274    (set_attr "mode" "QI")])
13276 (define_insn "*setcc_2"
13277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13278         (match_operator:QI 1 "ix86_comparison_operator"
13279           [(reg FLAGS_REG) (const_int 0)]))]
13280   ""
13281   "set%C1\t%0"
13282   [(set_attr "type" "setcc")
13283    (set_attr "mode" "QI")])
13285 ;; In general it is not safe to assume too much about CCmode registers,
13286 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13287 ;; conditions this is safe on x86, so help combine not create
13289 ;;      seta    %al
13290 ;;      testb   %al, %al
13291 ;;      sete    %al
13293 (define_split 
13294   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13295         (ne:QI (match_operator 1 "ix86_comparison_operator"
13296                  [(reg FLAGS_REG) (const_int 0)])
13297             (const_int 0)))]
13298   ""
13299   [(set (match_dup 0) (match_dup 1))]
13301   PUT_MODE (operands[1], QImode);
13304 (define_split 
13305   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13306         (ne:QI (match_operator 1 "ix86_comparison_operator"
13307                  [(reg FLAGS_REG) (const_int 0)])
13308             (const_int 0)))]
13309   ""
13310   [(set (match_dup 0) (match_dup 1))]
13312   PUT_MODE (operands[1], QImode);
13315 (define_split 
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13317         (eq:QI (match_operator 1 "ix86_comparison_operator"
13318                  [(reg FLAGS_REG) (const_int 0)])
13319             (const_int 0)))]
13320   ""
13321   [(set (match_dup 0) (match_dup 1))]
13323   rtx new_op1 = copy_rtx (operands[1]);
13324   operands[1] = new_op1;
13325   PUT_MODE (new_op1, QImode);
13326   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13327                                              GET_MODE (XEXP (new_op1, 0))));
13329   /* Make sure that (a) the CCmode we have for the flags is strong
13330      enough for the reversed compare or (b) we have a valid FP compare.  */
13331   if (! ix86_comparison_operator (new_op1, VOIDmode))
13332     FAIL;
13335 (define_split 
13336   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13337         (eq:QI (match_operator 1 "ix86_comparison_operator"
13338                  [(reg FLAGS_REG) (const_int 0)])
13339             (const_int 0)))]
13340   ""
13341   [(set (match_dup 0) (match_dup 1))]
13343   rtx new_op1 = copy_rtx (operands[1]);
13344   operands[1] = new_op1;
13345   PUT_MODE (new_op1, QImode);
13346   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13347                                              GET_MODE (XEXP (new_op1, 0))));
13349   /* Make sure that (a) the CCmode we have for the flags is strong
13350      enough for the reversed compare or (b) we have a valid FP compare.  */
13351   if (! ix86_comparison_operator (new_op1, VOIDmode))
13352     FAIL;
13355 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13356 ;; subsequent logical operations are used to imitate conditional moves.
13357 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13358 ;; it directly.
13360 (define_insn "*sse_setccsf"
13361   [(set (match_operand:SF 0 "register_operand" "=x")
13362         (match_operator:SF 1 "sse_comparison_operator"
13363           [(match_operand:SF 2 "register_operand" "0")
13364            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13365   "TARGET_SSE"
13366   "cmp%D1ss\t{%3, %0|%0, %3}"
13367   [(set_attr "type" "ssecmp")
13368    (set_attr "mode" "SF")])
13370 (define_insn "*sse_setccdf"
13371   [(set (match_operand:DF 0 "register_operand" "=Y")
13372         (match_operator:DF 1 "sse_comparison_operator"
13373           [(match_operand:DF 2 "register_operand" "0")
13374            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13375   "TARGET_SSE2"
13376   "cmp%D1sd\t{%3, %0|%0, %3}"
13377   [(set_attr "type" "ssecmp")
13378    (set_attr "mode" "DF")])
13380 ;; Basic conditional jump instructions.
13381 ;; We ignore the overflow flag for signed branch instructions.
13383 ;; For all bCOND expanders, also expand the compare or test insn that
13384 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13386 (define_expand "beq"
13387   [(set (pc)
13388         (if_then_else (match_dup 1)
13389                       (label_ref (match_operand 0 "" ""))
13390                       (pc)))]
13391   ""
13392   "ix86_expand_branch (EQ, operands[0]); DONE;")
13394 (define_expand "bne"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   ""
13400   "ix86_expand_branch (NE, operands[0]); DONE;")
13402 (define_expand "bgt"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   ""
13408   "ix86_expand_branch (GT, operands[0]); DONE;")
13410 (define_expand "bgtu"
13411   [(set (pc)
13412         (if_then_else (match_dup 1)
13413                       (label_ref (match_operand 0 "" ""))
13414                       (pc)))]
13415   ""
13416   "ix86_expand_branch (GTU, operands[0]); DONE;")
13418 (define_expand "blt"
13419   [(set (pc)
13420         (if_then_else (match_dup 1)
13421                       (label_ref (match_operand 0 "" ""))
13422                       (pc)))]
13423   ""
13424   "ix86_expand_branch (LT, operands[0]); DONE;")
13426 (define_expand "bltu"
13427   [(set (pc)
13428         (if_then_else (match_dup 1)
13429                       (label_ref (match_operand 0 "" ""))
13430                       (pc)))]
13431   ""
13432   "ix86_expand_branch (LTU, operands[0]); DONE;")
13434 (define_expand "bge"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (GE, operands[0]); DONE;")
13442 (define_expand "bgeu"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (GEU, operands[0]); DONE;")
13450 (define_expand "ble"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (LE, operands[0]); DONE;")
13458 (define_expand "bleu"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (LEU, operands[0]); DONE;")
13466 (define_expand "bunordered"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   "TARGET_80387 || TARGET_SSE_MATH"
13472   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13474 (define_expand "bordered"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   "TARGET_80387 || TARGET_SSE_MATH"
13480   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13482 (define_expand "buneq"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   "TARGET_80387 || TARGET_SSE_MATH"
13488   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13490 (define_expand "bunge"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   "TARGET_80387 || TARGET_SSE_MATH"
13496   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13498 (define_expand "bungt"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   "TARGET_80387 || TARGET_SSE_MATH"
13504   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13506 (define_expand "bunle"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   "TARGET_80387 || TARGET_SSE_MATH"
13512   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13514 (define_expand "bunlt"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13522 (define_expand "bltgt"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13530 (define_insn "*jcc_1"
13531   [(set (pc)
13532         (if_then_else (match_operator 1 "ix86_comparison_operator"
13533                                       [(reg FLAGS_REG) (const_int 0)])
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   ""
13537   "%+j%C1\t%l0"
13538   [(set_attr "type" "ibr")
13539    (set_attr "modrm" "0")
13540    (set (attr "length")
13541            (if_then_else (and (ge (minus (match_dup 0) (pc))
13542                                   (const_int -126))
13543                               (lt (minus (match_dup 0) (pc))
13544                                   (const_int 128)))
13545              (const_int 2)
13546              (const_int 6)))])
13548 (define_insn "*jcc_2"
13549   [(set (pc)
13550         (if_then_else (match_operator 1 "ix86_comparison_operator"
13551                                       [(reg FLAGS_REG) (const_int 0)])
13552                       (pc)
13553                       (label_ref (match_operand 0 "" ""))))]
13554   ""
13555   "%+j%c1\t%l0"
13556   [(set_attr "type" "ibr")
13557    (set_attr "modrm" "0")
13558    (set (attr "length")
13559            (if_then_else (and (ge (minus (match_dup 0) (pc))
13560                                   (const_int -126))
13561                               (lt (minus (match_dup 0) (pc))
13562                                   (const_int 128)))
13563              (const_int 2)
13564              (const_int 6)))])
13566 ;; In general it is not safe to assume too much about CCmode registers,
13567 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13568 ;; conditions this is safe on x86, so help combine not create
13570 ;;      seta    %al
13571 ;;      testb   %al, %al
13572 ;;      je      Lfoo
13574 (define_split 
13575   [(set (pc)
13576         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13577                                       [(reg FLAGS_REG) (const_int 0)])
13578                           (const_int 0))
13579                       (label_ref (match_operand 1 "" ""))
13580                       (pc)))]
13581   ""
13582   [(set (pc)
13583         (if_then_else (match_dup 0)
13584                       (label_ref (match_dup 1))
13585                       (pc)))]
13587   PUT_MODE (operands[0], VOIDmode);
13589   
13590 (define_split 
13591   [(set (pc)
13592         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13593                                       [(reg FLAGS_REG) (const_int 0)])
13594                           (const_int 0))
13595                       (label_ref (match_operand 1 "" ""))
13596                       (pc)))]
13597   ""
13598   [(set (pc)
13599         (if_then_else (match_dup 0)
13600                       (label_ref (match_dup 1))
13601                       (pc)))]
13603   rtx new_op0 = copy_rtx (operands[0]);
13604   operands[0] = new_op0;
13605   PUT_MODE (new_op0, VOIDmode);
13606   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13607                                              GET_MODE (XEXP (new_op0, 0))));
13609   /* Make sure that (a) the CCmode we have for the flags is strong
13610      enough for the reversed compare or (b) we have a valid FP compare.  */
13611   if (! ix86_comparison_operator (new_op0, VOIDmode))
13612     FAIL;
13615 ;; Define combination compare-and-branch fp compare instructions to use
13616 ;; during early optimization.  Splitting the operation apart early makes
13617 ;; for bad code when we want to reverse the operation.
13619 (define_insn "*fp_jcc_1_mixed"
13620   [(set (pc)
13621         (if_then_else (match_operator 0 "comparison_operator"
13622                         [(match_operand 1 "register_operand" "f,x")
13623                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13624           (label_ref (match_operand 3 "" ""))
13625           (pc)))
13626    (clobber (reg:CCFP FPSR_REG))
13627    (clobber (reg:CCFP FLAGS_REG))]
13628   "TARGET_MIX_SSE_I387
13629    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13630    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13631    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13632   "#")
13634 (define_insn "*fp_jcc_1_sse"
13635   [(set (pc)
13636         (if_then_else (match_operator 0 "comparison_operator"
13637                         [(match_operand 1 "register_operand" "x")
13638                          (match_operand 2 "nonimmediate_operand" "xm")])
13639           (label_ref (match_operand 3 "" ""))
13640           (pc)))
13641    (clobber (reg:CCFP FPSR_REG))
13642    (clobber (reg:CCFP FLAGS_REG))]
13643   "TARGET_SSE_MATH
13644    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13645    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13646    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13647   "#")
13649 (define_insn "*fp_jcc_1_387"
13650   [(set (pc)
13651         (if_then_else (match_operator 0 "comparison_operator"
13652                         [(match_operand 1 "register_operand" "f")
13653                          (match_operand 2 "register_operand" "f")])
13654           (label_ref (match_operand 3 "" ""))
13655           (pc)))
13656    (clobber (reg:CCFP FPSR_REG))
13657    (clobber (reg:CCFP FLAGS_REG))]
13658   "TARGET_CMOVE && TARGET_80387
13659    && FLOAT_MODE_P (GET_MODE (operands[1]))
13660    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13661    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13662   "#")
13664 (define_insn "*fp_jcc_2_mixed"
13665   [(set (pc)
13666         (if_then_else (match_operator 0 "comparison_operator"
13667                         [(match_operand 1 "register_operand" "f,x")
13668                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13669           (pc)
13670           (label_ref (match_operand 3 "" ""))))
13671    (clobber (reg:CCFP FPSR_REG))
13672    (clobber (reg:CCFP FLAGS_REG))]
13673   "TARGET_MIX_SSE_I387
13674    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13675    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13676    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13677   "#")
13679 (define_insn "*fp_jcc_2_sse"
13680   [(set (pc)
13681         (if_then_else (match_operator 0 "comparison_operator"
13682                         [(match_operand 1 "register_operand" "x")
13683                          (match_operand 2 "nonimmediate_operand" "xm")])
13684           (pc)
13685           (label_ref (match_operand 3 "" ""))))
13686    (clobber (reg:CCFP FPSR_REG))
13687    (clobber (reg:CCFP FLAGS_REG))]
13688   "TARGET_SSE_MATH
13689    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13690    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13691    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13692   "#")
13694 (define_insn "*fp_jcc_2_387"
13695   [(set (pc)
13696         (if_then_else (match_operator 0 "comparison_operator"
13697                         [(match_operand 1 "register_operand" "f")
13698                          (match_operand 2 "register_operand" "f")])
13699           (pc)
13700           (label_ref (match_operand 3 "" ""))))
13701    (clobber (reg:CCFP FPSR_REG))
13702    (clobber (reg:CCFP FLAGS_REG))]
13703   "TARGET_CMOVE && TARGET_80387
13704    && FLOAT_MODE_P (GET_MODE (operands[1]))
13705    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13706    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13707   "#")
13709 (define_insn "*fp_jcc_3_387"
13710   [(set (pc)
13711         (if_then_else (match_operator 0 "comparison_operator"
13712                         [(match_operand 1 "register_operand" "f")
13713                          (match_operand 2 "nonimmediate_operand" "fm")])
13714           (label_ref (match_operand 3 "" ""))
13715           (pc)))
13716    (clobber (reg:CCFP FPSR_REG))
13717    (clobber (reg:CCFP FLAGS_REG))
13718    (clobber (match_scratch:HI 4 "=a"))]
13719   "TARGET_80387
13720    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13721    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13722    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13723    && SELECT_CC_MODE (GET_CODE (operands[0]),
13724                       operands[1], operands[2]) == CCFPmode
13725    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726   "#")
13728 (define_insn "*fp_jcc_4_387"
13729   [(set (pc)
13730         (if_then_else (match_operator 0 "comparison_operator"
13731                         [(match_operand 1 "register_operand" "f")
13732                          (match_operand 2 "nonimmediate_operand" "fm")])
13733           (pc)
13734           (label_ref (match_operand 3 "" ""))))
13735    (clobber (reg:CCFP FPSR_REG))
13736    (clobber (reg:CCFP FLAGS_REG))
13737    (clobber (match_scratch:HI 4 "=a"))]
13738   "TARGET_80387
13739    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13742    && SELECT_CC_MODE (GET_CODE (operands[0]),
13743                       operands[1], operands[2]) == CCFPmode
13744    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13745   "#")
13747 (define_insn "*fp_jcc_5_387"
13748   [(set (pc)
13749         (if_then_else (match_operator 0 "comparison_operator"
13750                         [(match_operand 1 "register_operand" "f")
13751                          (match_operand 2 "register_operand" "f")])
13752           (label_ref (match_operand 3 "" ""))
13753           (pc)))
13754    (clobber (reg:CCFP FPSR_REG))
13755    (clobber (reg:CCFP FLAGS_REG))
13756    (clobber (match_scratch:HI 4 "=a"))]
13757   "TARGET_80387
13758    && FLOAT_MODE_P (GET_MODE (operands[1]))
13759    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13760    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13761   "#")
13763 (define_insn "*fp_jcc_6_387"
13764   [(set (pc)
13765         (if_then_else (match_operator 0 "comparison_operator"
13766                         [(match_operand 1 "register_operand" "f")
13767                          (match_operand 2 "register_operand" "f")])
13768           (pc)
13769           (label_ref (match_operand 3 "" ""))))
13770    (clobber (reg:CCFP FPSR_REG))
13771    (clobber (reg:CCFP FLAGS_REG))
13772    (clobber (match_scratch:HI 4 "=a"))]
13773   "TARGET_80387
13774    && FLOAT_MODE_P (GET_MODE (operands[1]))
13775    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13776    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777   "#")
13779 (define_insn "*fp_jcc_7_387"
13780   [(set (pc)
13781         (if_then_else (match_operator 0 "comparison_operator"
13782                         [(match_operand 1 "register_operand" "f")
13783                          (match_operand 2 "const0_operand" "X")])
13784           (label_ref (match_operand 3 "" ""))
13785           (pc)))
13786    (clobber (reg:CCFP FPSR_REG))
13787    (clobber (reg:CCFP FLAGS_REG))
13788    (clobber (match_scratch:HI 4 "=a"))]
13789   "TARGET_80387
13790    && FLOAT_MODE_P (GET_MODE (operands[1]))
13791    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13792    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13793    && SELECT_CC_MODE (GET_CODE (operands[0]),
13794                       operands[1], operands[2]) == CCFPmode
13795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13796   "#")
13798 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13799 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13800 ;; with a precedence over other operators and is always put in the first
13801 ;; place. Swap condition and operands to match ficom instruction.
13803 (define_insn "*fp_jcc_8<mode>_387"
13804   [(set (pc)
13805         (if_then_else (match_operator 0 "comparison_operator"
13806                         [(match_operator 1 "float_operator"
13807                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13808                            (match_operand 3 "register_operand" "f,f")])
13809           (label_ref (match_operand 4 "" ""))
13810           (pc)))
13811    (clobber (reg:CCFP FPSR_REG))
13812    (clobber (reg:CCFP FLAGS_REG))
13813    (clobber (match_scratch:HI 5 "=a,a"))]
13814   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13815    && FLOAT_MODE_P (GET_MODE (operands[3]))
13816    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13817    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13818    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13819    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13820   "#")
13822 (define_split
13823   [(set (pc)
13824         (if_then_else (match_operator 0 "comparison_operator"
13825                         [(match_operand 1 "register_operand" "")
13826                          (match_operand 2 "nonimmediate_operand" "")])
13827           (match_operand 3 "" "")
13828           (match_operand 4 "" "")))
13829    (clobber (reg:CCFP FPSR_REG))
13830    (clobber (reg:CCFP FLAGS_REG))]
13831   "reload_completed"
13832   [(const_int 0)]
13834   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13835                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13836   DONE;
13839 (define_split
13840   [(set (pc)
13841         (if_then_else (match_operator 0 "comparison_operator"
13842                         [(match_operand 1 "register_operand" "")
13843                          (match_operand 2 "general_operand" "")])
13844           (match_operand 3 "" "")
13845           (match_operand 4 "" "")))
13846    (clobber (reg:CCFP FPSR_REG))
13847    (clobber (reg:CCFP FLAGS_REG))
13848    (clobber (match_scratch:HI 5 "=a"))]
13849   "reload_completed"
13850   [(const_int 0)]
13852   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13853                         operands[3], operands[4], operands[5], NULL_RTX);
13854   DONE;
13857 (define_split
13858   [(set (pc)
13859         (if_then_else (match_operator 0 "comparison_operator"
13860                         [(match_operator 1 "float_operator"
13861                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13862                            (match_operand 3 "register_operand" "")])
13863           (match_operand 4 "" "")
13864           (match_operand 5 "" "")))
13865    (clobber (reg:CCFP FPSR_REG))
13866    (clobber (reg:CCFP FLAGS_REG))
13867    (clobber (match_scratch:HI 6 "=a"))]
13868   "reload_completed"
13869   [(const_int 0)]
13871   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13872   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13873                         operands[3], operands[7],
13874                         operands[4], operands[5], operands[6], NULL_RTX);
13875   DONE;
13878 ;; %%% Kill this when reload knows how to do it.
13879 (define_split
13880   [(set (pc)
13881         (if_then_else (match_operator 0 "comparison_operator"
13882                         [(match_operator 1 "float_operator"
13883                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13884                            (match_operand 3 "register_operand" "")])
13885           (match_operand 4 "" "")
13886           (match_operand 5 "" "")))
13887    (clobber (reg:CCFP FPSR_REG))
13888    (clobber (reg:CCFP FLAGS_REG))
13889    (clobber (match_scratch:HI 6 "=a"))]
13890   "reload_completed"
13891   [(const_int 0)]
13893   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13894   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13895   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13896                         operands[3], operands[7],
13897                         operands[4], operands[5], operands[6], operands[2]);
13898   DONE;
13901 ;; Unconditional and other jump instructions
13903 (define_insn "jump"
13904   [(set (pc)
13905         (label_ref (match_operand 0 "" "")))]
13906   ""
13907   "jmp\t%l0"
13908   [(set_attr "type" "ibr")
13909    (set (attr "length")
13910            (if_then_else (and (ge (minus (match_dup 0) (pc))
13911                                   (const_int -126))
13912                               (lt (minus (match_dup 0) (pc))
13913                                   (const_int 128)))
13914              (const_int 2)
13915              (const_int 5)))
13916    (set_attr "modrm" "0")])
13918 (define_expand "indirect_jump"
13919   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13920   ""
13921   "")
13923 (define_insn "*indirect_jump"
13924   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13925   "!TARGET_64BIT"
13926   "jmp\t%A0"
13927   [(set_attr "type" "ibr")
13928    (set_attr "length_immediate" "0")])
13930 (define_insn "*indirect_jump_rtx64"
13931   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13932   "TARGET_64BIT"
13933   "jmp\t%A0"
13934   [(set_attr "type" "ibr")
13935    (set_attr "length_immediate" "0")])
13937 (define_expand "tablejump"
13938   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13939               (use (label_ref (match_operand 1 "" "")))])]
13940   ""
13942   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13943      relative.  Convert the relative address to an absolute address.  */
13944   if (flag_pic)
13945     {
13946       rtx op0, op1;
13947       enum rtx_code code;
13949       if (TARGET_64BIT)
13950         {
13951           code = PLUS;
13952           op0 = operands[0];
13953           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13954         }
13955       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13956         {
13957           code = PLUS;
13958           op0 = operands[0];
13959           op1 = pic_offset_table_rtx;
13960         }
13961       else
13962         {
13963           code = MINUS;
13964           op0 = pic_offset_table_rtx;
13965           op1 = operands[0];
13966         }
13968       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13969                                          OPTAB_DIRECT);
13970     }
13973 (define_insn "*tablejump_1"
13974   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13975    (use (label_ref (match_operand 1 "" "")))]
13976   "!TARGET_64BIT"
13977   "jmp\t%A0"
13978   [(set_attr "type" "ibr")
13979    (set_attr "length_immediate" "0")])
13981 (define_insn "*tablejump_1_rtx64"
13982   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13983    (use (label_ref (match_operand 1 "" "")))]
13984   "TARGET_64BIT"
13985   "jmp\t%A0"
13986   [(set_attr "type" "ibr")
13987    (set_attr "length_immediate" "0")])
13989 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13991 (define_peephole2
13992   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13993    (set (match_operand:QI 1 "register_operand" "")
13994         (match_operator:QI 2 "ix86_comparison_operator"
13995           [(reg FLAGS_REG) (const_int 0)]))
13996    (set (match_operand 3 "q_regs_operand" "")
13997         (zero_extend (match_dup 1)))]
13998   "(peep2_reg_dead_p (3, operands[1])
13999     || operands_match_p (operands[1], operands[3]))
14000    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14001   [(set (match_dup 4) (match_dup 0))
14002    (set (strict_low_part (match_dup 5))
14003         (match_dup 2))]
14005   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14006   operands[5] = gen_lowpart (QImode, operands[3]);
14007   ix86_expand_clear (operands[3]);
14010 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14012 (define_peephole2
14013   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14014    (set (match_operand:QI 1 "register_operand" "")
14015         (match_operator:QI 2 "ix86_comparison_operator"
14016           [(reg FLAGS_REG) (const_int 0)]))
14017    (parallel [(set (match_operand 3 "q_regs_operand" "")
14018                    (zero_extend (match_dup 1)))
14019               (clobber (reg:CC FLAGS_REG))])]
14020   "(peep2_reg_dead_p (3, operands[1])
14021     || operands_match_p (operands[1], operands[3]))
14022    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14023   [(set (match_dup 4) (match_dup 0))
14024    (set (strict_low_part (match_dup 5))
14025         (match_dup 2))]
14027   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14028   operands[5] = gen_lowpart (QImode, operands[3]);
14029   ix86_expand_clear (operands[3]);
14032 ;; Call instructions.
14034 ;; The predicates normally associated with named expanders are not properly
14035 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14036 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14038 ;; Call subroutine returning no value.
14040 (define_expand "call_pop"
14041   [(parallel [(call (match_operand:QI 0 "" "")
14042                     (match_operand:SI 1 "" ""))
14043               (set (reg:SI SP_REG)
14044                    (plus:SI (reg:SI SP_REG)
14045                             (match_operand:SI 3 "" "")))])]
14046   "!TARGET_64BIT"
14048   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14049   DONE;
14052 (define_insn "*call_pop_0"
14053   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14054          (match_operand:SI 1 "" ""))
14055    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14056                             (match_operand:SI 2 "immediate_operand" "")))]
14057   "!TARGET_64BIT"
14059   if (SIBLING_CALL_P (insn))
14060     return "jmp\t%P0";
14061   else
14062     return "call\t%P0";
14064   [(set_attr "type" "call")])
14065   
14066 (define_insn "*call_pop_1"
14067   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14068          (match_operand:SI 1 "" ""))
14069    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14070                             (match_operand:SI 2 "immediate_operand" "i")))]
14071   "!TARGET_64BIT"
14073   if (constant_call_address_operand (operands[0], Pmode))
14074     {
14075       if (SIBLING_CALL_P (insn))
14076         return "jmp\t%P0";
14077       else
14078         return "call\t%P0";
14079     }
14080   if (SIBLING_CALL_P (insn))
14081     return "jmp\t%A0";
14082   else
14083     return "call\t%A0";
14085   [(set_attr "type" "call")])
14087 (define_expand "call"
14088   [(call (match_operand:QI 0 "" "")
14089          (match_operand 1 "" ""))
14090    (use (match_operand 2 "" ""))]
14091   ""
14093   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14094   DONE;
14097 (define_expand "sibcall"
14098   [(call (match_operand:QI 0 "" "")
14099          (match_operand 1 "" ""))
14100    (use (match_operand 2 "" ""))]
14101   ""
14103   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14104   DONE;
14107 (define_insn "*call_0"
14108   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14109          (match_operand 1 "" ""))]
14110   ""
14112   if (SIBLING_CALL_P (insn))
14113     return "jmp\t%P0";
14114   else
14115     return "call\t%P0";
14117   [(set_attr "type" "call")])
14119 (define_insn "*call_1"
14120   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14121          (match_operand 1 "" ""))]
14122   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14124   if (constant_call_address_operand (operands[0], Pmode))
14125     return "call\t%P0";
14126   return "call\t%A0";
14128   [(set_attr "type" "call")])
14130 (define_insn "*sibcall_1"
14131   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14132          (match_operand 1 "" ""))]
14133   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14135   if (constant_call_address_operand (operands[0], Pmode))
14136     return "jmp\t%P0";
14137   return "jmp\t%A0";
14139   [(set_attr "type" "call")])
14141 (define_insn "*call_1_rex64"
14142   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14143          (match_operand 1 "" ""))]
14144   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14146   if (constant_call_address_operand (operands[0], Pmode))
14147     return "call\t%P0";
14148   return "call\t%A0";
14150   [(set_attr "type" "call")])
14152 (define_insn "*sibcall_1_rex64"
14153   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14154          (match_operand 1 "" ""))]
14155   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14156   "jmp\t%P0"
14157   [(set_attr "type" "call")])
14159 (define_insn "*sibcall_1_rex64_v"
14160   [(call (mem:QI (reg:DI 40))
14161          (match_operand 0 "" ""))]
14162   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14163   "jmp\t*%%r11"
14164   [(set_attr "type" "call")])
14167 ;; Call subroutine, returning value in operand 0
14169 (define_expand "call_value_pop"
14170   [(parallel [(set (match_operand 0 "" "")
14171                    (call (match_operand:QI 1 "" "")
14172                          (match_operand:SI 2 "" "")))
14173               (set (reg:SI SP_REG)
14174                    (plus:SI (reg:SI SP_REG)
14175                             (match_operand:SI 4 "" "")))])]
14176   "!TARGET_64BIT"
14178   ix86_expand_call (operands[0], operands[1], operands[2],
14179                     operands[3], operands[4], 0);
14180   DONE;
14183 (define_expand "call_value"
14184   [(set (match_operand 0 "" "")
14185         (call (match_operand:QI 1 "" "")
14186               (match_operand:SI 2 "" "")))
14187    (use (match_operand:SI 3 "" ""))]
14188   ;; Operand 2 not used on the i386.
14189   ""
14191   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14192   DONE;
14195 (define_expand "sibcall_value"
14196   [(set (match_operand 0 "" "")
14197         (call (match_operand:QI 1 "" "")
14198               (match_operand:SI 2 "" "")))
14199    (use (match_operand:SI 3 "" ""))]
14200   ;; Operand 2 not used on the i386.
14201   ""
14203   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14204   DONE;
14207 ;; Call subroutine returning any type.
14209 (define_expand "untyped_call"
14210   [(parallel [(call (match_operand 0 "" "")
14211                     (const_int 0))
14212               (match_operand 1 "" "")
14213               (match_operand 2 "" "")])]
14214   ""
14216   int i;
14218   /* In order to give reg-stack an easier job in validating two
14219      coprocessor registers as containing a possible return value,
14220      simply pretend the untyped call returns a complex long double
14221      value.  */
14223   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14224                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14225                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14226                     NULL, 0);
14228   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14229     {
14230       rtx set = XVECEXP (operands[2], 0, i);
14231       emit_move_insn (SET_DEST (set), SET_SRC (set));
14232     }
14234   /* The optimizer does not know that the call sets the function value
14235      registers we stored in the result block.  We avoid problems by
14236      claiming that all hard registers are used and clobbered at this
14237      point.  */
14238   emit_insn (gen_blockage (const0_rtx));
14240   DONE;
14243 ;; Prologue and epilogue instructions
14245 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14246 ;; all of memory.  This blocks insns from being moved across this point.
14248 (define_insn "blockage"
14249   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14250   ""
14251   ""
14252   [(set_attr "length" "0")])
14254 ;; Insn emitted into the body of a function to return from a function.
14255 ;; This is only done if the function's epilogue is known to be simple.
14256 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14258 (define_expand "return"
14259   [(return)]
14260   "ix86_can_use_return_insn_p ()"
14262   if (current_function_pops_args)
14263     {
14264       rtx popc = GEN_INT (current_function_pops_args);
14265       emit_jump_insn (gen_return_pop_internal (popc));
14266       DONE;
14267     }
14270 (define_insn "return_internal"
14271   [(return)]
14272   "reload_completed"
14273   "ret"
14274   [(set_attr "length" "1")
14275    (set_attr "length_immediate" "0")
14276    (set_attr "modrm" "0")])
14278 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14279 ;; instruction Athlon and K8 have.
14281 (define_insn "return_internal_long"
14282   [(return)
14283    (unspec [(const_int 0)] UNSPEC_REP)]
14284   "reload_completed"
14285   "rep {;} ret"
14286   [(set_attr "length" "1")
14287    (set_attr "length_immediate" "0")
14288    (set_attr "prefix_rep" "1")
14289    (set_attr "modrm" "0")])
14291 (define_insn "return_pop_internal"
14292   [(return)
14293    (use (match_operand:SI 0 "const_int_operand" ""))]
14294   "reload_completed"
14295   "ret\t%0"
14296   [(set_attr "length" "3")
14297    (set_attr "length_immediate" "2")
14298    (set_attr "modrm" "0")])
14300 (define_insn "return_indirect_internal"
14301   [(return)
14302    (use (match_operand:SI 0 "register_operand" "r"))]
14303   "reload_completed"
14304   "jmp\t%A0"
14305   [(set_attr "type" "ibr")
14306    (set_attr "length_immediate" "0")])
14308 (define_insn "nop"
14309   [(const_int 0)]
14310   ""
14311   "nop"
14312   [(set_attr "length" "1")
14313    (set_attr "length_immediate" "0")
14314    (set_attr "modrm" "0")])
14316 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14317 ;; branch prediction penalty for the third jump in a 16-byte
14318 ;; block on K8.
14320 (define_insn "align"
14321   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14322   ""
14324 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14325   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14326 #else
14327   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14328      The align insn is used to avoid 3 jump instructions in the row to improve
14329      branch prediction and the benefits hardly outweigh the cost of extra 8
14330      nops on the average inserted by full alignment pseudo operation.  */
14331 #endif
14332   return "";
14334   [(set_attr "length" "16")])
14336 (define_expand "prologue"
14337   [(const_int 1)]
14338   ""
14339   "ix86_expand_prologue (); DONE;")
14341 (define_insn "set_got"
14342   [(set (match_operand:SI 0 "register_operand" "=r")
14343         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14344    (clobber (reg:CC FLAGS_REG))]
14345   "!TARGET_64BIT"
14346   { return output_set_got (operands[0], NULL_RTX); }
14347   [(set_attr "type" "multi")
14348    (set_attr "length" "12")])
14350 (define_insn "set_got_labelled"
14351   [(set (match_operand:SI 0 "register_operand" "=r")
14352         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14353          UNSPEC_SET_GOT))
14354    (clobber (reg:CC FLAGS_REG))]
14355   "!TARGET_64BIT"
14356   { return output_set_got (operands[0], operands[1]); }
14357   [(set_attr "type" "multi")
14358    (set_attr "length" "12")])
14360 (define_insn "set_got_rex64"
14361   [(set (match_operand:DI 0 "register_operand" "=r")
14362         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14363   "TARGET_64BIT"
14364   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14365   [(set_attr "type" "lea")
14366    (set_attr "length" "6")])
14368 (define_expand "epilogue"
14369   [(const_int 1)]
14370   ""
14371   "ix86_expand_epilogue (1); DONE;")
14373 (define_expand "sibcall_epilogue"
14374   [(const_int 1)]
14375   ""
14376   "ix86_expand_epilogue (0); DONE;")
14378 (define_expand "eh_return"
14379   [(use (match_operand 0 "register_operand" ""))]
14380   ""
14382   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14384   /* Tricky bit: we write the address of the handler to which we will
14385      be returning into someone else's stack frame, one word below the
14386      stack address we wish to restore.  */
14387   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14388   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14389   tmp = gen_rtx_MEM (Pmode, tmp);
14390   emit_move_insn (tmp, ra);
14392   if (Pmode == SImode)
14393     emit_jump_insn (gen_eh_return_si (sa));
14394   else
14395     emit_jump_insn (gen_eh_return_di (sa));
14396   emit_barrier ();
14397   DONE;
14400 (define_insn_and_split "eh_return_si"
14401   [(set (pc) 
14402         (unspec [(match_operand:SI 0 "register_operand" "c")]
14403                  UNSPEC_EH_RETURN))]
14404   "!TARGET_64BIT"
14405   "#"
14406   "reload_completed"
14407   [(const_int 1)]
14408   "ix86_expand_epilogue (2); DONE;")
14410 (define_insn_and_split "eh_return_di"
14411   [(set (pc) 
14412         (unspec [(match_operand:DI 0 "register_operand" "c")]
14413                  UNSPEC_EH_RETURN))]
14414   "TARGET_64BIT"
14415   "#"
14416   "reload_completed"
14417   [(const_int 1)]
14418   "ix86_expand_epilogue (2); DONE;")
14420 (define_insn "leave"
14421   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14422    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14423    (clobber (mem:BLK (scratch)))]
14424   "!TARGET_64BIT"
14425   "leave"
14426   [(set_attr "type" "leave")])
14428 (define_insn "leave_rex64"
14429   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14430    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14431    (clobber (mem:BLK (scratch)))]
14432   "TARGET_64BIT"
14433   "leave"
14434   [(set_attr "type" "leave")])
14436 (define_expand "ffssi2"
14437   [(parallel
14438      [(set (match_operand:SI 0 "register_operand" "") 
14439            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14440       (clobber (match_scratch:SI 2 ""))
14441       (clobber (reg:CC FLAGS_REG))])]
14442   ""
14443   "")
14445 (define_insn_and_split "*ffs_cmove"
14446   [(set (match_operand:SI 0 "register_operand" "=r") 
14447         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14448    (clobber (match_scratch:SI 2 "=&r"))
14449    (clobber (reg:CC FLAGS_REG))]
14450   "TARGET_CMOVE"
14451   "#"
14452   "&& reload_completed"
14453   [(set (match_dup 2) (const_int -1))
14454    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14455               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14456    (set (match_dup 0) (if_then_else:SI
14457                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14458                         (match_dup 2)
14459                         (match_dup 0)))
14460    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14461               (clobber (reg:CC FLAGS_REG))])]
14462   "")
14464 (define_insn_and_split "*ffs_no_cmove"
14465   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14466         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14467    (clobber (match_scratch:SI 2 "=&q"))
14468    (clobber (reg:CC FLAGS_REG))]
14469   ""
14470   "#"
14471   "reload_completed"
14472   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14473               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14474    (set (strict_low_part (match_dup 3))
14475         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14476    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14477               (clobber (reg:CC FLAGS_REG))])
14478    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14479               (clobber (reg:CC FLAGS_REG))])
14480    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14481               (clobber (reg:CC FLAGS_REG))])]
14483   operands[3] = gen_lowpart (QImode, operands[2]);
14484   ix86_expand_clear (operands[2]);
14487 (define_insn "*ffssi_1"
14488   [(set (reg:CCZ FLAGS_REG)
14489         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14490                      (const_int 0)))
14491    (set (match_operand:SI 0 "register_operand" "=r")
14492         (ctz:SI (match_dup 1)))]
14493   ""
14494   "bsf{l}\t{%1, %0|%0, %1}"
14495   [(set_attr "prefix_0f" "1")])
14497 (define_expand "ffsdi2"
14498   [(parallel
14499      [(set (match_operand:DI 0 "register_operand" "") 
14500            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14501       (clobber (match_scratch:DI 2 ""))
14502       (clobber (reg:CC FLAGS_REG))])]
14503   "TARGET_64BIT && TARGET_CMOVE"
14504   "")
14506 (define_insn_and_split "*ffs_rex64"
14507   [(set (match_operand:DI 0 "register_operand" "=r") 
14508         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14509    (clobber (match_scratch:DI 2 "=&r"))
14510    (clobber (reg:CC FLAGS_REG))]
14511   "TARGET_64BIT && TARGET_CMOVE"
14512   "#"
14513   "&& reload_completed"
14514   [(set (match_dup 2) (const_int -1))
14515    (parallel [(set (reg:CCZ FLAGS_REG)
14516                    (compare:CCZ (match_dup 1) (const_int 0)))
14517               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14518    (set (match_dup 0) (if_then_else:DI
14519                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14520                         (match_dup 2)
14521                         (match_dup 0)))
14522    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14523               (clobber (reg:CC FLAGS_REG))])]
14524   "")
14526 (define_insn "*ffsdi_1"
14527   [(set (reg:CCZ FLAGS_REG)
14528         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14529                      (const_int 0)))
14530    (set (match_operand:DI 0 "register_operand" "=r")
14531         (ctz:DI (match_dup 1)))]
14532   "TARGET_64BIT"
14533   "bsf{q}\t{%1, %0|%0, %1}"
14534   [(set_attr "prefix_0f" "1")])
14536 (define_insn "ctzsi2"
14537   [(set (match_operand:SI 0 "register_operand" "=r")
14538         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14539    (clobber (reg:CC FLAGS_REG))]
14540   ""
14541   "bsf{l}\t{%1, %0|%0, %1}"
14542   [(set_attr "prefix_0f" "1")])
14544 (define_insn "ctzdi2"
14545   [(set (match_operand:DI 0 "register_operand" "=r")
14546         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14547    (clobber (reg:CC FLAGS_REG))]
14548   "TARGET_64BIT"
14549   "bsf{q}\t{%1, %0|%0, %1}"
14550   [(set_attr "prefix_0f" "1")])
14552 (define_expand "clzsi2"
14553   [(parallel
14554      [(set (match_operand:SI 0 "register_operand" "")
14555            (minus:SI (const_int 31)
14556                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14557       (clobber (reg:CC FLAGS_REG))])
14558    (parallel
14559      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14560       (clobber (reg:CC FLAGS_REG))])]
14561   ""
14562   "")
14564 (define_insn "*bsr"
14565   [(set (match_operand:SI 0 "register_operand" "=r")
14566         (minus:SI (const_int 31)
14567                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14568    (clobber (reg:CC FLAGS_REG))]
14569   ""
14570   "bsr{l}\t{%1, %0|%0, %1}"
14571   [(set_attr "prefix_0f" "1")])
14573 (define_expand "clzdi2"
14574   [(parallel
14575      [(set (match_operand:DI 0 "register_operand" "")
14576            (minus:DI (const_int 63)
14577                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14578       (clobber (reg:CC FLAGS_REG))])
14579    (parallel
14580      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14581       (clobber (reg:CC FLAGS_REG))])]
14582   "TARGET_64BIT"
14583   "")
14585 (define_insn "*bsr_rex64"
14586   [(set (match_operand:DI 0 "register_operand" "=r")
14587         (minus:DI (const_int 63)
14588                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14589    (clobber (reg:CC FLAGS_REG))]
14590   "TARGET_64BIT"
14591   "bsr{q}\t{%1, %0|%0, %1}"
14592   [(set_attr "prefix_0f" "1")])
14594 ;; Thread-local storage patterns for ELF.
14596 ;; Note that these code sequences must appear exactly as shown
14597 ;; in order to allow linker relaxation.
14599 (define_insn "*tls_global_dynamic_32_gnu"
14600   [(set (match_operand:SI 0 "register_operand" "=a")
14601         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14602                     (match_operand:SI 2 "tls_symbolic_operand" "")
14603                     (match_operand:SI 3 "call_insn_operand" "")]
14604                     UNSPEC_TLS_GD))
14605    (clobber (match_scratch:SI 4 "=d"))
14606    (clobber (match_scratch:SI 5 "=c"))
14607    (clobber (reg:CC FLAGS_REG))]
14608   "!TARGET_64BIT && TARGET_GNU_TLS"
14609   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14610   [(set_attr "type" "multi")
14611    (set_attr "length" "12")])
14613 (define_insn "*tls_global_dynamic_32_sun"
14614   [(set (match_operand:SI 0 "register_operand" "=a")
14615         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14616                     (match_operand:SI 2 "tls_symbolic_operand" "")
14617                     (match_operand:SI 3 "call_insn_operand" "")]
14618                     UNSPEC_TLS_GD))
14619    (clobber (match_scratch:SI 4 "=d"))
14620    (clobber (match_scratch:SI 5 "=c"))
14621    (clobber (reg:CC FLAGS_REG))]
14622   "!TARGET_64BIT && TARGET_SUN_TLS"
14623   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14624         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14625   [(set_attr "type" "multi")
14626    (set_attr "length" "14")])
14628 (define_expand "tls_global_dynamic_32"
14629   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14630                    (unspec:SI
14631                     [(match_dup 2)
14632                      (match_operand:SI 1 "tls_symbolic_operand" "")
14633                      (match_dup 3)]
14634                     UNSPEC_TLS_GD))
14635               (clobber (match_scratch:SI 4 ""))
14636               (clobber (match_scratch:SI 5 ""))
14637               (clobber (reg:CC FLAGS_REG))])]
14638   ""
14640   if (flag_pic)
14641     operands[2] = pic_offset_table_rtx;
14642   else
14643     {
14644       operands[2] = gen_reg_rtx (Pmode);
14645       emit_insn (gen_set_got (operands[2]));
14646     }
14647   if (TARGET_GNU2_TLS)
14648     {
14649        emit_insn (gen_tls_dynamic_gnu2_32
14650                   (operands[0], operands[1], operands[2]));
14651        DONE;
14652     }
14653   operands[3] = ix86_tls_get_addr ();
14656 (define_insn "*tls_global_dynamic_64"
14657   [(set (match_operand:DI 0 "register_operand" "=a")
14658         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14659                  (match_operand:DI 3 "" "")))
14660    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14661               UNSPEC_TLS_GD)]
14662   "TARGET_64BIT"
14663   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14664   [(set_attr "type" "multi")
14665    (set_attr "length" "16")])
14667 (define_expand "tls_global_dynamic_64"
14668   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14669                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14670               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14671                          UNSPEC_TLS_GD)])]
14672   ""
14674   if (TARGET_GNU2_TLS)
14675     {
14676        emit_insn (gen_tls_dynamic_gnu2_64
14677                   (operands[0], operands[1]));
14678        DONE;
14679     }
14680   operands[2] = ix86_tls_get_addr ();
14683 (define_insn "*tls_local_dynamic_base_32_gnu"
14684   [(set (match_operand:SI 0 "register_operand" "=a")
14685         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14686                     (match_operand:SI 2 "call_insn_operand" "")]
14687                    UNSPEC_TLS_LD_BASE))
14688    (clobber (match_scratch:SI 3 "=d"))
14689    (clobber (match_scratch:SI 4 "=c"))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "!TARGET_64BIT && TARGET_GNU_TLS"
14692   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14693   [(set_attr "type" "multi")
14694    (set_attr "length" "11")])
14696 (define_insn "*tls_local_dynamic_base_32_sun"
14697   [(set (match_operand:SI 0 "register_operand" "=a")
14698         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14699                     (match_operand:SI 2 "call_insn_operand" "")]
14700                    UNSPEC_TLS_LD_BASE))
14701    (clobber (match_scratch:SI 3 "=d"))
14702    (clobber (match_scratch:SI 4 "=c"))
14703    (clobber (reg:CC FLAGS_REG))]
14704   "!TARGET_64BIT && TARGET_SUN_TLS"
14705   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14706         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14707   [(set_attr "type" "multi")
14708    (set_attr "length" "13")])
14710 (define_expand "tls_local_dynamic_base_32"
14711   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14712                    (unspec:SI [(match_dup 1) (match_dup 2)]
14713                               UNSPEC_TLS_LD_BASE))
14714               (clobber (match_scratch:SI 3 ""))
14715               (clobber (match_scratch:SI 4 ""))
14716               (clobber (reg:CC FLAGS_REG))])]
14717   ""
14719   if (flag_pic)
14720     operands[1] = pic_offset_table_rtx;
14721   else
14722     {
14723       operands[1] = gen_reg_rtx (Pmode);
14724       emit_insn (gen_set_got (operands[1]));
14725     }
14726   if (TARGET_GNU2_TLS)
14727     {
14728        emit_insn (gen_tls_dynamic_gnu2_32
14729                   (operands[0], ix86_tls_module_base (), operands[1]));
14730        DONE;
14731     }
14732   operands[2] = ix86_tls_get_addr ();
14735 (define_insn "*tls_local_dynamic_base_64"
14736   [(set (match_operand:DI 0 "register_operand" "=a")
14737         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14738                  (match_operand:DI 2 "" "")))
14739    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14740   "TARGET_64BIT"
14741   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14742   [(set_attr "type" "multi")
14743    (set_attr "length" "12")])
14745 (define_expand "tls_local_dynamic_base_64"
14746   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14747                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14748               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14749   ""
14751   if (TARGET_GNU2_TLS)
14752     {
14753        emit_insn (gen_tls_dynamic_gnu2_64
14754                   (operands[0], ix86_tls_module_base ()));
14755        DONE;
14756     }
14757   operands[1] = ix86_tls_get_addr ();
14760 ;; Local dynamic of a single variable is a lose.  Show combine how
14761 ;; to convert that back to global dynamic.
14763 (define_insn_and_split "*tls_local_dynamic_32_once"
14764   [(set (match_operand:SI 0 "register_operand" "=a")
14765         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14766                              (match_operand:SI 2 "call_insn_operand" "")]
14767                             UNSPEC_TLS_LD_BASE)
14768                  (const:SI (unspec:SI
14769                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14770                             UNSPEC_DTPOFF))))
14771    (clobber (match_scratch:SI 4 "=d"))
14772    (clobber (match_scratch:SI 5 "=c"))
14773    (clobber (reg:CC FLAGS_REG))]
14774   ""
14775   "#"
14776   ""
14777   [(parallel [(set (match_dup 0)
14778                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14779                               UNSPEC_TLS_GD))
14780               (clobber (match_dup 4))
14781               (clobber (match_dup 5))
14782               (clobber (reg:CC FLAGS_REG))])]
14783   "")
14785 ;; Load and add the thread base pointer from %gs:0.
14787 (define_insn "*load_tp_si"
14788   [(set (match_operand:SI 0 "register_operand" "=r")
14789         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14790   "!TARGET_64BIT"
14791   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14792   [(set_attr "type" "imov")
14793    (set_attr "modrm" "0")
14794    (set_attr "length" "7")
14795    (set_attr "memory" "load")
14796    (set_attr "imm_disp" "false")])
14798 (define_insn "*add_tp_si"
14799   [(set (match_operand:SI 0 "register_operand" "=r")
14800         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14801                  (match_operand:SI 1 "register_operand" "0")))
14802    (clobber (reg:CC FLAGS_REG))]
14803   "!TARGET_64BIT"
14804   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14805   [(set_attr "type" "alu")
14806    (set_attr "modrm" "0")
14807    (set_attr "length" "7")
14808    (set_attr "memory" "load")
14809    (set_attr "imm_disp" "false")])
14811 (define_insn "*load_tp_di"
14812   [(set (match_operand:DI 0 "register_operand" "=r")
14813         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14814   "TARGET_64BIT"
14815   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14816   [(set_attr "type" "imov")
14817    (set_attr "modrm" "0")
14818    (set_attr "length" "7")
14819    (set_attr "memory" "load")
14820    (set_attr "imm_disp" "false")])
14822 (define_insn "*add_tp_di"
14823   [(set (match_operand:DI 0 "register_operand" "=r")
14824         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14825                  (match_operand:DI 1 "register_operand" "0")))
14826    (clobber (reg:CC FLAGS_REG))]
14827   "TARGET_64BIT"
14828   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14829   [(set_attr "type" "alu")
14830    (set_attr "modrm" "0")
14831    (set_attr "length" "7")
14832    (set_attr "memory" "load")
14833    (set_attr "imm_disp" "false")])
14835 ;; GNU2 TLS patterns can be split.
14837 (define_expand "tls_dynamic_gnu2_32"
14838   [(set (match_dup 3)
14839         (plus:SI (match_operand:SI 2 "register_operand" "")
14840                  (const:SI
14841                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14842                              UNSPEC_TLSDESC))))
14843    (parallel
14844     [(set (match_operand:SI 0 "register_operand" "")
14845           (unspec:SI [(match_dup 1) (match_dup 3)
14846                       (match_dup 2) (reg:SI SP_REG)]
14847                       UNSPEC_TLSDESC))
14848      (clobber (reg:CC FLAGS_REG))])]
14849   "!TARGET_64BIT && TARGET_GNU2_TLS"
14851   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14852   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14855 (define_insn "*tls_dynamic_lea_32"
14856   [(set (match_operand:SI 0 "register_operand" "=r")
14857         (plus:SI (match_operand:SI 1 "register_operand" "b")
14858                  (const:SI
14859                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14860                               UNSPEC_TLSDESC))))]
14861   "!TARGET_64BIT && TARGET_GNU2_TLS"
14862   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14863   [(set_attr "type" "lea")
14864    (set_attr "mode" "SI")
14865    (set_attr "length" "6")
14866    (set_attr "length_address" "4")])
14868 (define_insn "*tls_dynamic_call_32"
14869   [(set (match_operand:SI 0 "register_operand" "=a")
14870         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14871                     (match_operand:SI 2 "register_operand" "0")
14872                     ;; we have to make sure %ebx still points to the GOT
14873                     (match_operand:SI 3 "register_operand" "b")
14874                     (reg:SI SP_REG)]
14875                    UNSPEC_TLSDESC))
14876    (clobber (reg:CC FLAGS_REG))]
14877   "!TARGET_64BIT && TARGET_GNU2_TLS"
14878   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14879   [(set_attr "type" "call")
14880    (set_attr "length" "2")
14881    (set_attr "length_address" "0")])
14883 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14884   [(set (match_operand:SI 0 "register_operand" "=&a")
14885         (plus:SI
14886          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14887                      (match_operand:SI 4 "" "")
14888                      (match_operand:SI 2 "register_operand" "b")
14889                      (reg:SI SP_REG)]
14890                     UNSPEC_TLSDESC)
14891          (const:SI (unspec:SI
14892                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14893                     UNSPEC_DTPOFF))))
14894    (clobber (reg:CC FLAGS_REG))]
14895   "!TARGET_64BIT && TARGET_GNU2_TLS"
14896   "#"
14897   ""
14898   [(set (match_dup 0) (match_dup 5))]
14900   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14901   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14904 (define_expand "tls_dynamic_gnu2_64"
14905   [(set (match_dup 2)
14906         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14907                    UNSPEC_TLSDESC))
14908    (parallel
14909     [(set (match_operand:DI 0 "register_operand" "")
14910           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14911                      UNSPEC_TLSDESC))
14912      (clobber (reg:CC FLAGS_REG))])]
14913   "TARGET_64BIT && TARGET_GNU2_TLS"
14915   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14916   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14919 (define_insn "*tls_dynamic_lea_64"
14920   [(set (match_operand:DI 0 "register_operand" "=r")
14921         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14922                    UNSPEC_TLSDESC))]
14923   "TARGET_64BIT && TARGET_GNU2_TLS"
14924   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14925   [(set_attr "type" "lea")
14926    (set_attr "mode" "DI")
14927    (set_attr "length" "7")
14928    (set_attr "length_address" "4")])
14930 (define_insn "*tls_dynamic_call_64"
14931   [(set (match_operand:DI 0 "register_operand" "=a")
14932         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14933                     (match_operand:DI 2 "register_operand" "0")
14934                     (reg:DI SP_REG)]
14935                    UNSPEC_TLSDESC))
14936    (clobber (reg:CC FLAGS_REG))]
14937   "TARGET_64BIT && TARGET_GNU2_TLS"
14938   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14939   [(set_attr "type" "call")
14940    (set_attr "length" "2")
14941    (set_attr "length_address" "0")])
14943 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14944   [(set (match_operand:DI 0 "register_operand" "=&a")
14945         (plus:DI
14946          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14947                      (match_operand:DI 3 "" "")
14948                      (reg:DI SP_REG)]
14949                     UNSPEC_TLSDESC)
14950          (const:DI (unspec:DI
14951                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14952                     UNSPEC_DTPOFF))))
14953    (clobber (reg:CC FLAGS_REG))]
14954   "TARGET_64BIT && TARGET_GNU2_TLS"
14955   "#"
14956   ""
14957   [(set (match_dup 0) (match_dup 4))]
14959   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14960   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14965 ;; These patterns match the binary 387 instructions for addM3, subM3,
14966 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14967 ;; SFmode.  The first is the normal insn, the second the same insn but
14968 ;; with one operand a conversion, and the third the same insn but with
14969 ;; the other operand a conversion.  The conversion may be SFmode or
14970 ;; SImode if the target mode DFmode, but only SImode if the target mode
14971 ;; is SFmode.
14973 ;; Gcc is slightly more smart about handling normal two address instructions
14974 ;; so use special patterns for add and mull.
14976 (define_insn "*fop_sf_comm_mixed"
14977   [(set (match_operand:SF 0 "register_operand" "=f,x")
14978         (match_operator:SF 3 "binary_fp_operator"
14979                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14980                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14981   "TARGET_MIX_SSE_I387
14982    && COMMUTATIVE_ARITH_P (operands[3])
14983    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14984   "* return output_387_binary_op (insn, operands);"
14985   [(set (attr "type") 
14986         (if_then_else (eq_attr "alternative" "1")
14987            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14988               (const_string "ssemul")
14989               (const_string "sseadd"))
14990            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14991               (const_string "fmul")
14992               (const_string "fop"))))
14993    (set_attr "mode" "SF")])
14995 (define_insn "*fop_sf_comm_sse"
14996   [(set (match_operand:SF 0 "register_operand" "=x")
14997         (match_operator:SF 3 "binary_fp_operator"
14998                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14999                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15000   "TARGET_SSE_MATH
15001    && COMMUTATIVE_ARITH_P (operands[3])
15002    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15003   "* return output_387_binary_op (insn, operands);"
15004   [(set (attr "type") 
15005         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15006            (const_string "ssemul")
15007            (const_string "sseadd")))
15008    (set_attr "mode" "SF")])
15010 (define_insn "*fop_sf_comm_i387"
15011   [(set (match_operand:SF 0 "register_operand" "=f")
15012         (match_operator:SF 3 "binary_fp_operator"
15013                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15014                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15015   "TARGET_80387
15016    && COMMUTATIVE_ARITH_P (operands[3])
15017    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15018   "* return output_387_binary_op (insn, operands);"
15019   [(set (attr "type") 
15020         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15021            (const_string "fmul")
15022            (const_string "fop")))
15023    (set_attr "mode" "SF")])
15025 (define_insn "*fop_sf_1_mixed"
15026   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15027         (match_operator:SF 3 "binary_fp_operator"
15028                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15029                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15030   "TARGET_MIX_SSE_I387
15031    && !COMMUTATIVE_ARITH_P (operands[3])
15032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15033   "* return output_387_binary_op (insn, operands);"
15034   [(set (attr "type") 
15035         (cond [(and (eq_attr "alternative" "2")
15036                     (match_operand:SF 3 "mult_operator" ""))
15037                  (const_string "ssemul")
15038                (and (eq_attr "alternative" "2")
15039                     (match_operand:SF 3 "div_operator" ""))
15040                  (const_string "ssediv")
15041                (eq_attr "alternative" "2")
15042                  (const_string "sseadd")
15043                (match_operand:SF 3 "mult_operator" "") 
15044                  (const_string "fmul")
15045                (match_operand:SF 3 "div_operator" "") 
15046                  (const_string "fdiv")
15047               ]
15048               (const_string "fop")))
15049    (set_attr "mode" "SF")])
15051 (define_insn "*fop_sf_1_sse"
15052   [(set (match_operand:SF 0 "register_operand" "=x")
15053         (match_operator:SF 3 "binary_fp_operator"
15054                         [(match_operand:SF 1 "register_operand" "0")
15055                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15056   "TARGET_SSE_MATH
15057    && !COMMUTATIVE_ARITH_P (operands[3])"
15058   "* return output_387_binary_op (insn, operands);"
15059   [(set (attr "type") 
15060         (cond [(match_operand:SF 3 "mult_operator" "")
15061                  (const_string "ssemul")
15062                (match_operand:SF 3 "div_operator" "")
15063                  (const_string "ssediv")
15064               ]
15065               (const_string "sseadd")))
15066    (set_attr "mode" "SF")])
15068 ;; This pattern is not fully shadowed by the pattern above.
15069 (define_insn "*fop_sf_1_i387"
15070   [(set (match_operand:SF 0 "register_operand" "=f,f")
15071         (match_operator:SF 3 "binary_fp_operator"
15072                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15073                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15074   "TARGET_80387 && !TARGET_SSE_MATH
15075    && !COMMUTATIVE_ARITH_P (operands[3])
15076    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15077   "* return output_387_binary_op (insn, operands);"
15078   [(set (attr "type") 
15079         (cond [(match_operand:SF 3 "mult_operator" "") 
15080                  (const_string "fmul")
15081                (match_operand:SF 3 "div_operator" "") 
15082                  (const_string "fdiv")
15083               ]
15084               (const_string "fop")))
15085    (set_attr "mode" "SF")])
15087 ;; ??? Add SSE splitters for these!
15088 (define_insn "*fop_sf_2<mode>_i387"
15089   [(set (match_operand:SF 0 "register_operand" "=f,f")
15090         (match_operator:SF 3 "binary_fp_operator"
15091           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15092            (match_operand:SF 2 "register_operand" "0,0")]))]
15093   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15094   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15095   [(set (attr "type") 
15096         (cond [(match_operand:SF 3 "mult_operator" "") 
15097                  (const_string "fmul")
15098                (match_operand:SF 3 "div_operator" "") 
15099                  (const_string "fdiv")
15100               ]
15101               (const_string "fop")))
15102    (set_attr "fp_int_src" "true")
15103    (set_attr "mode" "<MODE>")])
15105 (define_insn "*fop_sf_3<mode>_i387"
15106   [(set (match_operand:SF 0 "register_operand" "=f,f")
15107         (match_operator:SF 3 "binary_fp_operator"
15108           [(match_operand:SF 1 "register_operand" "0,0")
15109            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15110   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15111   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15112   [(set (attr "type") 
15113         (cond [(match_operand:SF 3 "mult_operator" "") 
15114                  (const_string "fmul")
15115                (match_operand:SF 3 "div_operator" "") 
15116                  (const_string "fdiv")
15117               ]
15118               (const_string "fop")))
15119    (set_attr "fp_int_src" "true")
15120    (set_attr "mode" "<MODE>")])
15122 (define_insn "*fop_df_comm_mixed"
15123   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15124         (match_operator:DF 3 "binary_fp_operator"
15125                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15126                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15127   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15128    && COMMUTATIVE_ARITH_P (operands[3])
15129    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15130   "* return output_387_binary_op (insn, operands);"
15131   [(set (attr "type") 
15132         (if_then_else (eq_attr "alternative" "1")
15133            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15134               (const_string "ssemul")
15135               (const_string "sseadd"))
15136            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15137               (const_string "fmul")
15138               (const_string "fop"))))
15139    (set_attr "mode" "DF")])
15141 (define_insn "*fop_df_comm_sse"
15142   [(set (match_operand:DF 0 "register_operand" "=Y")
15143         (match_operator:DF 3 "binary_fp_operator"
15144                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15145                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15146   "TARGET_SSE2 && TARGET_SSE_MATH
15147    && COMMUTATIVE_ARITH_P (operands[3])
15148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15149   "* return output_387_binary_op (insn, operands);"
15150   [(set (attr "type") 
15151         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15152            (const_string "ssemul")
15153            (const_string "sseadd")))
15154    (set_attr "mode" "DF")])
15156 (define_insn "*fop_df_comm_i387"
15157   [(set (match_operand:DF 0 "register_operand" "=f")
15158         (match_operator:DF 3 "binary_fp_operator"
15159                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15160                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15161   "TARGET_80387
15162    && COMMUTATIVE_ARITH_P (operands[3])
15163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15164   "* return output_387_binary_op (insn, operands);"
15165   [(set (attr "type") 
15166         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15167            (const_string "fmul")
15168            (const_string "fop")))
15169    (set_attr "mode" "DF")])
15171 (define_insn "*fop_df_1_mixed"
15172   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15173         (match_operator:DF 3 "binary_fp_operator"
15174                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15175                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15176   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15177    && !COMMUTATIVE_ARITH_P (operands[3])
15178    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15179   "* return output_387_binary_op (insn, operands);"
15180   [(set (attr "type") 
15181         (cond [(and (eq_attr "alternative" "2")
15182                     (match_operand:DF 3 "mult_operator" ""))
15183                  (const_string "ssemul")
15184                (and (eq_attr "alternative" "2")
15185                     (match_operand:DF 3 "div_operator" ""))
15186                  (const_string "ssediv")
15187                (eq_attr "alternative" "2")
15188                  (const_string "sseadd")
15189                (match_operand:DF 3 "mult_operator" "") 
15190                  (const_string "fmul")
15191                (match_operand:DF 3 "div_operator" "") 
15192                  (const_string "fdiv")
15193               ]
15194               (const_string "fop")))
15195    (set_attr "mode" "DF")])
15197 (define_insn "*fop_df_1_sse"
15198   [(set (match_operand:DF 0 "register_operand" "=Y")
15199         (match_operator:DF 3 "binary_fp_operator"
15200                         [(match_operand:DF 1 "register_operand" "0")
15201                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15202   "TARGET_SSE2 && TARGET_SSE_MATH
15203    && !COMMUTATIVE_ARITH_P (operands[3])"
15204   "* return output_387_binary_op (insn, operands);"
15205   [(set_attr "mode" "DF")
15206    (set (attr "type") 
15207         (cond [(match_operand:DF 3 "mult_operator" "")
15208                  (const_string "ssemul")
15209                (match_operand:DF 3 "div_operator" "")
15210                  (const_string "ssediv")
15211               ]
15212               (const_string "sseadd")))])
15214 ;; This pattern is not fully shadowed by the pattern above.
15215 (define_insn "*fop_df_1_i387"
15216   [(set (match_operand:DF 0 "register_operand" "=f,f")
15217         (match_operator:DF 3 "binary_fp_operator"
15218                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15219                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15220   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15221    && !COMMUTATIVE_ARITH_P (operands[3])
15222    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15223   "* return output_387_binary_op (insn, operands);"
15224   [(set (attr "type") 
15225         (cond [(match_operand:DF 3 "mult_operator" "") 
15226                  (const_string "fmul")
15227                (match_operand:DF 3 "div_operator" "")
15228                  (const_string "fdiv")
15229               ]
15230               (const_string "fop")))
15231    (set_attr "mode" "DF")])
15233 ;; ??? Add SSE splitters for these!
15234 (define_insn "*fop_df_2<mode>_i387"
15235   [(set (match_operand:DF 0 "register_operand" "=f,f")
15236         (match_operator:DF 3 "binary_fp_operator"
15237            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15238             (match_operand:DF 2 "register_operand" "0,0")]))]
15239   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15240    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15241   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15242   [(set (attr "type") 
15243         (cond [(match_operand:DF 3 "mult_operator" "") 
15244                  (const_string "fmul")
15245                (match_operand:DF 3 "div_operator" "") 
15246                  (const_string "fdiv")
15247               ]
15248               (const_string "fop")))
15249    (set_attr "fp_int_src" "true")
15250    (set_attr "mode" "<MODE>")])
15252 (define_insn "*fop_df_3<mode>_i387"
15253   [(set (match_operand:DF 0 "register_operand" "=f,f")
15254         (match_operator:DF 3 "binary_fp_operator"
15255            [(match_operand:DF 1 "register_operand" "0,0")
15256             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15257   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15258    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15259   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15260   [(set (attr "type") 
15261         (cond [(match_operand:DF 3 "mult_operator" "") 
15262                  (const_string "fmul")
15263                (match_operand:DF 3 "div_operator" "") 
15264                  (const_string "fdiv")
15265               ]
15266               (const_string "fop")))
15267    (set_attr "fp_int_src" "true")
15268    (set_attr "mode" "<MODE>")])
15270 (define_insn "*fop_df_4_i387"
15271   [(set (match_operand:DF 0 "register_operand" "=f,f")
15272         (match_operator:DF 3 "binary_fp_operator"
15273            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15274             (match_operand:DF 2 "register_operand" "0,f")]))]
15275   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15276    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15277   "* return output_387_binary_op (insn, operands);"
15278   [(set (attr "type") 
15279         (cond [(match_operand:DF 3 "mult_operator" "") 
15280                  (const_string "fmul")
15281                (match_operand:DF 3 "div_operator" "") 
15282                  (const_string "fdiv")
15283               ]
15284               (const_string "fop")))
15285    (set_attr "mode" "SF")])
15287 (define_insn "*fop_df_5_i387"
15288   [(set (match_operand:DF 0 "register_operand" "=f,f")
15289         (match_operator:DF 3 "binary_fp_operator"
15290           [(match_operand:DF 1 "register_operand" "0,f")
15291            (float_extend:DF
15292             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15293   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15294   "* return output_387_binary_op (insn, operands);"
15295   [(set (attr "type") 
15296         (cond [(match_operand:DF 3 "mult_operator" "") 
15297                  (const_string "fmul")
15298                (match_operand:DF 3 "div_operator" "") 
15299                  (const_string "fdiv")
15300               ]
15301               (const_string "fop")))
15302    (set_attr "mode" "SF")])
15304 (define_insn "*fop_df_6_i387"
15305   [(set (match_operand:DF 0 "register_operand" "=f,f")
15306         (match_operator:DF 3 "binary_fp_operator"
15307           [(float_extend:DF
15308             (match_operand:SF 1 "register_operand" "0,f"))
15309            (float_extend:DF
15310             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15311   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15312   "* return output_387_binary_op (insn, operands);"
15313   [(set (attr "type") 
15314         (cond [(match_operand:DF 3 "mult_operator" "") 
15315                  (const_string "fmul")
15316                (match_operand:DF 3 "div_operator" "") 
15317                  (const_string "fdiv")
15318               ]
15319               (const_string "fop")))
15320    (set_attr "mode" "SF")])
15322 (define_insn "*fop_xf_comm_i387"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (match_operator:XF 3 "binary_fp_operator"
15325                         [(match_operand:XF 1 "register_operand" "%0")
15326                          (match_operand:XF 2 "register_operand" "f")]))]
15327   "TARGET_80387
15328    && COMMUTATIVE_ARITH_P (operands[3])"
15329   "* return output_387_binary_op (insn, operands);"
15330   [(set (attr "type") 
15331         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15332            (const_string "fmul")
15333            (const_string "fop")))
15334    (set_attr "mode" "XF")])
15336 (define_insn "*fop_xf_1_i387"
15337   [(set (match_operand:XF 0 "register_operand" "=f,f")
15338         (match_operator:XF 3 "binary_fp_operator"
15339                         [(match_operand:XF 1 "register_operand" "0,f")
15340                          (match_operand:XF 2 "register_operand" "f,0")]))]
15341   "TARGET_80387
15342    && !COMMUTATIVE_ARITH_P (operands[3])"
15343   "* return output_387_binary_op (insn, operands);"
15344   [(set (attr "type") 
15345         (cond [(match_operand:XF 3 "mult_operator" "") 
15346                  (const_string "fmul")
15347                (match_operand:XF 3 "div_operator" "") 
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "mode" "XF")])
15353 (define_insn "*fop_xf_2<mode>_i387"
15354   [(set (match_operand:XF 0 "register_operand" "=f,f")
15355         (match_operator:XF 3 "binary_fp_operator"
15356            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15357             (match_operand:XF 2 "register_operand" "0,0")]))]
15358   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15359   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15360   [(set (attr "type") 
15361         (cond [(match_operand:XF 3 "mult_operator" "") 
15362                  (const_string "fmul")
15363                (match_operand:XF 3 "div_operator" "") 
15364                  (const_string "fdiv")
15365               ]
15366               (const_string "fop")))
15367    (set_attr "fp_int_src" "true")
15368    (set_attr "mode" "<MODE>")])
15370 (define_insn "*fop_xf_3<mode>_i387"
15371   [(set (match_operand:XF 0 "register_operand" "=f,f")
15372         (match_operator:XF 3 "binary_fp_operator"
15373           [(match_operand:XF 1 "register_operand" "0,0")
15374            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15375   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15376   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15377   [(set (attr "type") 
15378         (cond [(match_operand:XF 3 "mult_operator" "") 
15379                  (const_string "fmul")
15380                (match_operand:XF 3 "div_operator" "") 
15381                  (const_string "fdiv")
15382               ]
15383               (const_string "fop")))
15384    (set_attr "fp_int_src" "true")
15385    (set_attr "mode" "<MODE>")])
15387 (define_insn "*fop_xf_4_i387"
15388   [(set (match_operand:XF 0 "register_operand" "=f,f")
15389         (match_operator:XF 3 "binary_fp_operator"
15390            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15391             (match_operand:XF 2 "register_operand" "0,f")]))]
15392   "TARGET_80387"
15393   "* return output_387_binary_op (insn, operands);"
15394   [(set (attr "type") 
15395         (cond [(match_operand:XF 3 "mult_operator" "") 
15396                  (const_string "fmul")
15397                (match_operand:XF 3 "div_operator" "") 
15398                  (const_string "fdiv")
15399               ]
15400               (const_string "fop")))
15401    (set_attr "mode" "SF")])
15403 (define_insn "*fop_xf_5_i387"
15404   [(set (match_operand:XF 0 "register_operand" "=f,f")
15405         (match_operator:XF 3 "binary_fp_operator"
15406           [(match_operand:XF 1 "register_operand" "0,f")
15407            (float_extend:XF
15408             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15409   "TARGET_80387"
15410   "* return output_387_binary_op (insn, operands);"
15411   [(set (attr "type") 
15412         (cond [(match_operand:XF 3 "mult_operator" "") 
15413                  (const_string "fmul")
15414                (match_operand:XF 3 "div_operator" "") 
15415                  (const_string "fdiv")
15416               ]
15417               (const_string "fop")))
15418    (set_attr "mode" "SF")])
15420 (define_insn "*fop_xf_6_i387"
15421   [(set (match_operand:XF 0 "register_operand" "=f,f")
15422         (match_operator:XF 3 "binary_fp_operator"
15423           [(float_extend:XF
15424             (match_operand 1 "register_operand" "0,f"))
15425            (float_extend:XF
15426             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15427   "TARGET_80387"
15428   "* return output_387_binary_op (insn, operands);"
15429   [(set (attr "type") 
15430         (cond [(match_operand:XF 3 "mult_operator" "") 
15431                  (const_string "fmul")
15432                (match_operand:XF 3 "div_operator" "") 
15433                  (const_string "fdiv")
15434               ]
15435               (const_string "fop")))
15436    (set_attr "mode" "SF")])
15438 (define_split
15439   [(set (match_operand 0 "register_operand" "")
15440         (match_operator 3 "binary_fp_operator"
15441            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15442             (match_operand 2 "register_operand" "")]))]
15443   "TARGET_80387 && reload_completed
15444    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15445   [(const_int 0)]
15447   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15448   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15449   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15450                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15451                                           GET_MODE (operands[3]),
15452                                           operands[4],
15453                                           operands[2])));
15454   ix86_free_from_memory (GET_MODE (operands[1]));
15455   DONE;
15458 (define_split
15459   [(set (match_operand 0 "register_operand" "")
15460         (match_operator 3 "binary_fp_operator"
15461            [(match_operand 1 "register_operand" "")
15462             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15463   "TARGET_80387 && reload_completed
15464    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15465   [(const_int 0)]
15467   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15468   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15469   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15470                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15471                                           GET_MODE (operands[3]),
15472                                           operands[1],
15473                                           operands[4])));
15474   ix86_free_from_memory (GET_MODE (operands[2]));
15475   DONE;
15478 ;; FPU special functions.
15480 (define_expand "sqrtsf2"
15481   [(set (match_operand:SF 0 "register_operand" "")
15482         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15483   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15485   if (!TARGET_SSE_MATH)
15486     operands[1] = force_reg (SFmode, operands[1]);
15489 (define_insn "*sqrtsf2_mixed"
15490   [(set (match_operand:SF 0 "register_operand" "=f,x")
15491         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15492   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15493   "@
15494    fsqrt
15495    sqrtss\t{%1, %0|%0, %1}"
15496   [(set_attr "type" "fpspc,sse")
15497    (set_attr "mode" "SF,SF")
15498    (set_attr "athlon_decode" "direct,*")])
15500 (define_insn "*sqrtsf2_sse"
15501   [(set (match_operand:SF 0 "register_operand" "=x")
15502         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15503   "TARGET_SSE_MATH"
15504   "sqrtss\t{%1, %0|%0, %1}"
15505   [(set_attr "type" "sse")
15506    (set_attr "mode" "SF")
15507    (set_attr "athlon_decode" "*")])
15509 (define_insn "*sqrtsf2_i387"
15510   [(set (match_operand:SF 0 "register_operand" "=f")
15511         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15512   "TARGET_USE_FANCY_MATH_387"
15513   "fsqrt"
15514   [(set_attr "type" "fpspc")
15515    (set_attr "mode" "SF")
15516    (set_attr "athlon_decode" "direct")])
15518 (define_expand "sqrtdf2"
15519   [(set (match_operand:DF 0 "register_operand" "")
15520         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15521   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15523   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15524     operands[1] = force_reg (DFmode, operands[1]);
15527 (define_insn "*sqrtdf2_mixed"
15528   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15529         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15530   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15531   "@
15532    fsqrt
15533    sqrtsd\t{%1, %0|%0, %1}"
15534   [(set_attr "type" "fpspc,sse")
15535    (set_attr "mode" "DF,DF")
15536    (set_attr "athlon_decode" "direct,*")])
15538 (define_insn "*sqrtdf2_sse"
15539   [(set (match_operand:DF 0 "register_operand" "=Y")
15540         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15541   "TARGET_SSE2 && TARGET_SSE_MATH"
15542   "sqrtsd\t{%1, %0|%0, %1}"
15543   [(set_attr "type" "sse")
15544    (set_attr "mode" "DF")
15545    (set_attr "athlon_decode" "*")])
15547 (define_insn "*sqrtdf2_i387"
15548   [(set (match_operand:DF 0 "register_operand" "=f")
15549         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15550   "TARGET_USE_FANCY_MATH_387"
15551   "fsqrt"
15552   [(set_attr "type" "fpspc")
15553    (set_attr "mode" "DF")
15554    (set_attr "athlon_decode" "direct")])
15556 (define_insn "*sqrtextendsfdf2_i387"
15557   [(set (match_operand:DF 0 "register_operand" "=f")
15558         (sqrt:DF (float_extend:DF
15559                   (match_operand:SF 1 "register_operand" "0"))))]
15560   "TARGET_USE_FANCY_MATH_387
15561    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15562   "fsqrt"
15563   [(set_attr "type" "fpspc")
15564    (set_attr "mode" "DF")
15565    (set_attr "athlon_decode" "direct")])
15567 (define_insn "sqrtxf2"
15568   [(set (match_operand:XF 0 "register_operand" "=f")
15569         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15570   "TARGET_USE_FANCY_MATH_387"
15571   "fsqrt"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "mode" "XF")
15574    (set_attr "athlon_decode" "direct")])
15576 (define_insn "*sqrtextendsfxf2_i387"
15577   [(set (match_operand:XF 0 "register_operand" "=f")
15578         (sqrt:XF (float_extend:XF
15579                   (match_operand:SF 1 "register_operand" "0"))))]
15580   "TARGET_USE_FANCY_MATH_387"
15581   "fsqrt"
15582   [(set_attr "type" "fpspc")
15583    (set_attr "mode" "XF")
15584    (set_attr "athlon_decode" "direct")])
15586 (define_insn "*sqrtextenddfxf2_i387"
15587   [(set (match_operand:XF 0 "register_operand" "=f")
15588         (sqrt:XF (float_extend:XF
15589                   (match_operand:DF 1 "register_operand" "0"))))]
15590   "TARGET_USE_FANCY_MATH_387"
15591   "fsqrt"
15592   [(set_attr "type" "fpspc")
15593    (set_attr "mode" "XF")
15594    (set_attr "athlon_decode" "direct")])
15596 (define_insn "fpremxf4"
15597   [(set (match_operand:XF 0 "register_operand" "=f")
15598         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15599                     (match_operand:XF 3 "register_operand" "1")]
15600                    UNSPEC_FPREM_F))
15601    (set (match_operand:XF 1 "register_operand" "=u")
15602         (unspec:XF [(match_dup 2) (match_dup 3)]
15603                    UNSPEC_FPREM_U))
15604    (set (reg:CCFP FPSR_REG)
15605         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && flag_unsafe_math_optimizations"
15608   "fprem"
15609   [(set_attr "type" "fpspc")
15610    (set_attr "mode" "XF")])
15612 (define_expand "fmodsf3"
15613   [(use (match_operand:SF 0 "register_operand" ""))
15614    (use (match_operand:SF 1 "register_operand" ""))
15615    (use (match_operand:SF 2 "register_operand" ""))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15618    && flag_unsafe_math_optimizations"
15620   rtx label = gen_label_rtx ();
15622   rtx op1 = gen_reg_rtx (XFmode);
15623   rtx op2 = gen_reg_rtx (XFmode);
15625   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15626   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15628   emit_label (label);
15630   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15631   ix86_emit_fp_unordered_jump (label);
15633   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15634   DONE;
15637 (define_expand "fmoddf3"
15638   [(use (match_operand:DF 0 "register_operand" ""))
15639    (use (match_operand:DF 1 "register_operand" ""))
15640    (use (match_operand:DF 2 "register_operand" ""))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15643    && flag_unsafe_math_optimizations"
15645   rtx label = gen_label_rtx ();
15647   rtx op1 = gen_reg_rtx (XFmode);
15648   rtx op2 = gen_reg_rtx (XFmode);
15650   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15651   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15653   emit_label (label);
15655   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15656   ix86_emit_fp_unordered_jump (label);
15658   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15659   DONE;
15662 (define_expand "fmodxf3"
15663   [(use (match_operand:XF 0 "register_operand" ""))
15664    (use (match_operand:XF 1 "register_operand" ""))
15665    (use (match_operand:XF 2 "register_operand" ""))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && flag_unsafe_math_optimizations"
15669   rtx label = gen_label_rtx ();
15671   emit_label (label);
15673   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15674                            operands[1], operands[2]));
15675   ix86_emit_fp_unordered_jump (label);
15677   emit_move_insn (operands[0], operands[1]);
15678   DONE;
15681 (define_insn "fprem1xf4"
15682   [(set (match_operand:XF 0 "register_operand" "=f")
15683         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15684                     (match_operand:XF 3 "register_operand" "1")]
15685                    UNSPEC_FPREM1_F))
15686    (set (match_operand:XF 1 "register_operand" "=u")
15687         (unspec:XF [(match_dup 2) (match_dup 3)]
15688                    UNSPEC_FPREM1_U))
15689    (set (reg:CCFP FPSR_REG)
15690         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && flag_unsafe_math_optimizations"
15693   "fprem1"
15694   [(set_attr "type" "fpspc")
15695    (set_attr "mode" "XF")])
15697 (define_expand "dremsf3"
15698   [(use (match_operand:SF 0 "register_operand" ""))
15699    (use (match_operand:SF 1 "register_operand" ""))
15700    (use (match_operand:SF 2 "register_operand" ""))]
15701   "TARGET_USE_FANCY_MATH_387
15702    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15703    && flag_unsafe_math_optimizations"
15705   rtx label = gen_label_rtx ();
15707   rtx op1 = gen_reg_rtx (XFmode);
15708   rtx op2 = gen_reg_rtx (XFmode);
15710   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15711   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15713   emit_label (label);
15715   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15716   ix86_emit_fp_unordered_jump (label);
15718   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15719   DONE;
15722 (define_expand "dremdf3"
15723   [(use (match_operand:DF 0 "register_operand" ""))
15724    (use (match_operand:DF 1 "register_operand" ""))
15725    (use (match_operand:DF 2 "register_operand" ""))]
15726   "TARGET_USE_FANCY_MATH_387
15727    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728    && flag_unsafe_math_optimizations"
15730   rtx label = gen_label_rtx ();
15732   rtx op1 = gen_reg_rtx (XFmode);
15733   rtx op2 = gen_reg_rtx (XFmode);
15735   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15736   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15738   emit_label (label);
15740   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15741   ix86_emit_fp_unordered_jump (label);
15743   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15744   DONE;
15747 (define_expand "dremxf3"
15748   [(use (match_operand:XF 0 "register_operand" ""))
15749    (use (match_operand:XF 1 "register_operand" ""))
15750    (use (match_operand:XF 2 "register_operand" ""))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && flag_unsafe_math_optimizations"
15754   rtx label = gen_label_rtx ();
15756   emit_label (label);
15758   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759                             operands[1], operands[2]));
15760   ix86_emit_fp_unordered_jump (label);
15762   emit_move_insn (operands[0], operands[1]);
15763   DONE;
15766 (define_insn "*sindf2"
15767   [(set (match_operand:DF 0 "register_operand" "=f")
15768         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771    && flag_unsafe_math_optimizations"
15772   "fsin"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "DF")])
15776 (define_insn "*sinsf2"
15777   [(set (match_operand:SF 0 "register_operand" "=f")
15778         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782   "fsin"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "SF")])
15786 (define_insn "*sinextendsfdf2"
15787   [(set (match_operand:DF 0 "register_operand" "=f")
15788         (unspec:DF [(float_extend:DF
15789                      (match_operand:SF 1 "register_operand" "0"))]
15790                    UNSPEC_SIN))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15794   "fsin"
15795   [(set_attr "type" "fpspc")
15796    (set_attr "mode" "DF")])
15798 (define_insn "*sinxf2"
15799   [(set (match_operand:XF 0 "register_operand" "=f")
15800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && flag_unsafe_math_optimizations"
15803   "fsin"
15804   [(set_attr "type" "fpspc")
15805    (set_attr "mode" "XF")])
15807 (define_insn "*cosdf2"
15808   [(set (match_operand:DF 0 "register_operand" "=f")
15809         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813   "fcos"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "DF")])
15817 (define_insn "*cossf2"
15818   [(set (match_operand:SF 0 "register_operand" "=f")
15819         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820   "TARGET_USE_FANCY_MATH_387
15821    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822    && flag_unsafe_math_optimizations"
15823   "fcos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "SF")])
15827 (define_insn "*cosextendsfdf2"
15828   [(set (match_operand:DF 0 "register_operand" "=f")
15829         (unspec:DF [(float_extend:DF
15830                      (match_operand:SF 1 "register_operand" "0"))]
15831                    UNSPEC_COS))]
15832   "TARGET_USE_FANCY_MATH_387
15833    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15835   "fcos"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")])
15839 (define_insn "*cosxf2"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15844   "fcos"
15845   [(set_attr "type" "fpspc")
15846    (set_attr "mode" "XF")])
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused. 
15850 ;; Cse pass  will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15854 (define_insn "sincosdf3"
15855   [(set (match_operand:DF 0 "register_operand" "=f")
15856         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857                    UNSPEC_SINCOS_COS))
15858    (set (match_operand:DF 1 "register_operand" "=u")
15859         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862    && flag_unsafe_math_optimizations"
15863   "fsincos"
15864   [(set_attr "type" "fpspc")
15865    (set_attr "mode" "DF")])
15867 (define_split
15868   [(set (match_operand:DF 0 "register_operand" "")
15869         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870                    UNSPEC_SINCOS_COS))
15871    (set (match_operand:DF 1 "register_operand" "")
15872         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874    && !reload_completed && !reload_in_progress"
15875   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15876   "")
15878 (define_split
15879   [(set (match_operand:DF 0 "register_operand" "")
15880         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881                    UNSPEC_SINCOS_COS))
15882    (set (match_operand:DF 1 "register_operand" "")
15883         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885    && !reload_completed && !reload_in_progress"
15886   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15887   "")
15889 (define_insn "sincossf3"
15890   [(set (match_operand:SF 0 "register_operand" "=f")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:SF 1 "register_operand" "=u")
15894         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fsincos"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "SF")])
15902 (define_split
15903   [(set (match_operand:SF 0 "register_operand" "")
15904         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905                    UNSPEC_SINCOS_COS))
15906    (set (match_operand:SF 1 "register_operand" "")
15907         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909    && !reload_completed && !reload_in_progress"
15910   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15911   "")
15913 (define_split
15914   [(set (match_operand:SF 0 "register_operand" "")
15915         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916                    UNSPEC_SINCOS_COS))
15917    (set (match_operand:SF 1 "register_operand" "")
15918         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920    && !reload_completed && !reload_in_progress"
15921   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15922   "")
15924 (define_insn "*sincosextendsfdf3"
15925   [(set (match_operand:DF 0 "register_operand" "=f")
15926         (unspec:DF [(float_extend:DF
15927                      (match_operand:SF 2 "register_operand" "0"))]
15928                    UNSPEC_SINCOS_COS))
15929    (set (match_operand:DF 1 "register_operand" "=u")
15930         (unspec:DF [(float_extend:DF
15931                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15935   "fsincos"
15936   [(set_attr "type" "fpspc")
15937    (set_attr "mode" "DF")])
15939 (define_split
15940   [(set (match_operand:DF 0 "register_operand" "")
15941         (unspec:DF [(float_extend:DF
15942                      (match_operand:SF 2 "register_operand" ""))]
15943                    UNSPEC_SINCOS_COS))
15944    (set (match_operand:DF 1 "register_operand" "")
15945         (unspec:DF [(float_extend:DF
15946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948    && !reload_completed && !reload_in_progress"
15949   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950                                    (match_dup 2))] UNSPEC_SIN))]
15951   "")
15953 (define_split
15954   [(set (match_operand:DF 0 "register_operand" "")
15955         (unspec:DF [(float_extend:DF
15956                      (match_operand:SF 2 "register_operand" ""))]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:DF 1 "register_operand" "")
15959         (unspec:DF [(float_extend:DF
15960                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962    && !reload_completed && !reload_in_progress"
15963   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964                                    (match_dup 2))] UNSPEC_COS))]
15965   "")
15967 (define_insn "sincosxf3"
15968   [(set (match_operand:XF 0 "register_operand" "=f")
15969         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970                    UNSPEC_SINCOS_COS))
15971    (set (match_operand:XF 1 "register_operand" "=u")
15972         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973   "TARGET_USE_FANCY_MATH_387
15974    && flag_unsafe_math_optimizations"
15975   "fsincos"
15976   [(set_attr "type" "fpspc")
15977    (set_attr "mode" "XF")])
15979 (define_split
15980   [(set (match_operand:XF 0 "register_operand" "")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982                    UNSPEC_SINCOS_COS))
15983    (set (match_operand:XF 1 "register_operand" "")
15984         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986    && !reload_completed && !reload_in_progress"
15987   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15988   "")
15990 (define_split
15991   [(set (match_operand:XF 0 "register_operand" "")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993                    UNSPEC_SINCOS_COS))
15994    (set (match_operand:XF 1 "register_operand" "")
15995         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997    && !reload_completed && !reload_in_progress"
15998   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15999   "")
16001 (define_insn "*tandf3_1"
16002   [(set (match_operand:DF 0 "register_operand" "=f")
16003         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004                    UNSPEC_TAN_ONE))
16005    (set (match_operand:DF 1 "register_operand" "=u")
16006         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007   "TARGET_USE_FANCY_MATH_387
16008    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009    && flag_unsafe_math_optimizations"
16010   "fptan"
16011   [(set_attr "type" "fpspc")
16012    (set_attr "mode" "DF")])
16014 ;; optimize sequence: fptan
16015 ;;                    fstp    %st(0)
16016 ;;                    fld1
16017 ;; into fptan insn.
16019 (define_peephole2
16020   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022                              UNSPEC_TAN_ONE))
16023              (set (match_operand:DF 1 "register_operand" "")
16024                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025    (set (match_dup 0)
16026         (match_operand:DF 3 "immediate_operand" ""))]
16027   "standard_80387_constant_p (operands[3]) == 2"
16028   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16030   "")
16032 (define_expand "tandf2"
16033   [(parallel [(set (match_dup 2)
16034                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035                               UNSPEC_TAN_ONE))
16036               (set (match_operand:DF 0 "register_operand" "")
16037                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16042   operands[2] = gen_reg_rtx (DFmode);
16045 (define_insn "*tansf3_1"
16046   [(set (match_operand:SF 0 "register_operand" "=f")
16047         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048                    UNSPEC_TAN_ONE))
16049    (set (match_operand:SF 1 "register_operand" "=u")
16050         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054   "fptan"
16055   [(set_attr "type" "fpspc")
16056    (set_attr "mode" "SF")])
16058 ;; optimize sequence: fptan
16059 ;;                    fstp    %st(0)
16060 ;;                    fld1
16061 ;; into fptan insn.
16063 (define_peephole2
16064   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066                              UNSPEC_TAN_ONE))
16067              (set (match_operand:SF 1 "register_operand" "")
16068                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069    (set (match_dup 0)
16070         (match_operand:SF 3 "immediate_operand" ""))]
16071   "standard_80387_constant_p (operands[3]) == 2"
16072   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16074   "")
16076 (define_expand "tansf2"
16077   [(parallel [(set (match_dup 2)
16078                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079                               UNSPEC_TAN_ONE))
16080               (set (match_operand:SF 0 "register_operand" "")
16081                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082   "TARGET_USE_FANCY_MATH_387
16083    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084    && flag_unsafe_math_optimizations"
16086   operands[2] = gen_reg_rtx (SFmode);
16089 (define_insn "*tanxf3_1"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092                    UNSPEC_TAN_ONE))
16093    (set (match_operand:XF 1 "register_operand" "=u")
16094         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16097   "fptan"
16098   [(set_attr "type" "fpspc")
16099    (set_attr "mode" "XF")])
16101 ;; optimize sequence: fptan
16102 ;;                    fstp    %st(0)
16103 ;;                    fld1
16104 ;; into fptan insn.
16106 (define_peephole2
16107   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109                              UNSPEC_TAN_ONE))
16110              (set (match_operand:XF 1 "register_operand" "")
16111                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112    (set (match_dup 0)
16113         (match_operand:XF 3 "immediate_operand" ""))]
16114   "standard_80387_constant_p (operands[3]) == 2"
16115   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16117   "")
16119 (define_expand "tanxf2"
16120   [(parallel [(set (match_dup 2)
16121                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122                               UNSPEC_TAN_ONE))
16123               (set (match_operand:XF 0 "register_operand" "")
16124                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16128   operands[2] = gen_reg_rtx (XFmode);
16131 (define_insn "atan2df3_1"
16132   [(set (match_operand:DF 0 "register_operand" "=f")
16133         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134                     (match_operand:DF 1 "register_operand" "u")]
16135                    UNSPEC_FPATAN))
16136    (clobber (match_scratch:DF 3 "=1"))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139    && flag_unsafe_math_optimizations"
16140   "fpatan"
16141   [(set_attr "type" "fpspc")
16142    (set_attr "mode" "DF")])
16144 (define_expand "atan2df3"
16145   [(use (match_operand:DF 0 "register_operand" ""))
16146    (use (match_operand:DF 2 "register_operand" ""))
16147    (use (match_operand:DF 1 "register_operand" ""))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16152   rtx copy = gen_reg_rtx (DFmode);
16153   emit_move_insn (copy, operands[1]);
16154   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16155   DONE;
16158 (define_expand "atandf2"
16159   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160                    (unspec:DF [(match_dup 2)
16161                                (match_operand:DF 1 "register_operand" "")]
16162                     UNSPEC_FPATAN))
16163               (clobber (match_scratch:DF 3 ""))])]
16164   "TARGET_USE_FANCY_MATH_387
16165    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166    && flag_unsafe_math_optimizations"
16168   operands[2] = gen_reg_rtx (DFmode);
16169   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16172 (define_insn "atan2sf3_1"
16173   [(set (match_operand:SF 0 "register_operand" "=f")
16174         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175                     (match_operand:SF 1 "register_operand" "u")]
16176                    UNSPEC_FPATAN))
16177    (clobber (match_scratch:SF 3 "=1"))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16181   "fpatan"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "SF")])
16185 (define_expand "atan2sf3"
16186   [(use (match_operand:SF 0 "register_operand" ""))
16187    (use (match_operand:SF 2 "register_operand" ""))
16188    (use (match_operand:SF 1 "register_operand" ""))]
16189   "TARGET_USE_FANCY_MATH_387
16190    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16193   rtx copy = gen_reg_rtx (SFmode);
16194   emit_move_insn (copy, operands[1]);
16195   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16196   DONE;
16199 (define_expand "atansf2"
16200   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201                    (unspec:SF [(match_dup 2)
16202                                (match_operand:SF 1 "register_operand" "")]
16203                     UNSPEC_FPATAN))
16204               (clobber (match_scratch:SF 3 ""))])]
16205   "TARGET_USE_FANCY_MATH_387
16206    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207    && flag_unsafe_math_optimizations"
16209   operands[2] = gen_reg_rtx (SFmode);
16210   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16213 (define_insn "atan2xf3_1"
16214   [(set (match_operand:XF 0 "register_operand" "=f")
16215         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216                     (match_operand:XF 1 "register_operand" "u")]
16217                    UNSPEC_FPATAN))
16218    (clobber (match_scratch:XF 3 "=1"))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221   "fpatan"
16222   [(set_attr "type" "fpspc")
16223    (set_attr "mode" "XF")])
16225 (define_expand "atan2xf3"
16226   [(use (match_operand:XF 0 "register_operand" ""))
16227    (use (match_operand:XF 2 "register_operand" ""))
16228    (use (match_operand:XF 1 "register_operand" ""))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && flag_unsafe_math_optimizations"
16232   rtx copy = gen_reg_rtx (XFmode);
16233   emit_move_insn (copy, operands[1]);
16234   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16235   DONE;
16238 (define_expand "atanxf2"
16239   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240                    (unspec:XF [(match_dup 2)
16241                                (match_operand:XF 1 "register_operand" "")]
16242                     UNSPEC_FPATAN))
16243               (clobber (match_scratch:XF 3 ""))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16247   operands[2] = gen_reg_rtx (XFmode);
16248   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16251 (define_expand "asindf2"
16252   [(set (match_dup 2)
16253         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257    (parallel [(set (match_dup 7)
16258                    (unspec:XF [(match_dup 6) (match_dup 2)]
16259                               UNSPEC_FPATAN))
16260               (clobber (match_scratch:XF 8 ""))])
16261    (set (match_operand:DF 0 "register_operand" "")
16262         (float_truncate:DF (match_dup 7)))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16267   int i;
16269   for (i=2; i<8; i++)
16270     operands[i] = gen_reg_rtx (XFmode);
16272   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16275 (define_expand "asinsf2"
16276   [(set (match_dup 2)
16277         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281    (parallel [(set (match_dup 7)
16282                    (unspec:XF [(match_dup 6) (match_dup 2)]
16283                               UNSPEC_FPATAN))
16284               (clobber (match_scratch:XF 8 ""))])
16285    (set (match_operand:SF 0 "register_operand" "")
16286         (float_truncate:SF (match_dup 7)))]
16287   "TARGET_USE_FANCY_MATH_387
16288    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289    && flag_unsafe_math_optimizations"
16291   int i;
16293   for (i=2; i<8; i++)
16294     operands[i] = gen_reg_rtx (XFmode);
16296   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16299 (define_expand "asinxf2"
16300   [(set (match_dup 2)
16301         (mult:XF (match_operand:XF 1 "register_operand" "")
16302                  (match_dup 1)))
16303    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305    (parallel [(set (match_operand:XF 0 "register_operand" "")
16306                    (unspec:XF [(match_dup 5) (match_dup 1)]
16307                               UNSPEC_FPATAN))
16308               (clobber (match_scratch:XF 6 ""))])]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16312   int i;
16314   for (i=2; i<6; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16317   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16320 (define_expand "acosdf2"
16321   [(set (match_dup 2)
16322         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326    (parallel [(set (match_dup 7)
16327                    (unspec:XF [(match_dup 2) (match_dup 6)]
16328                               UNSPEC_FPATAN))
16329               (clobber (match_scratch:XF 8 ""))])
16330    (set (match_operand:DF 0 "register_operand" "")
16331         (float_truncate:DF (match_dup 7)))]
16332   "TARGET_USE_FANCY_MATH_387
16333    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334    && flag_unsafe_math_optimizations"
16336   int i;
16338   for (i=2; i<8; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16341   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16344 (define_expand "acossf2"
16345   [(set (match_dup 2)
16346         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350    (parallel [(set (match_dup 7)
16351                    (unspec:XF [(match_dup 2) (match_dup 6)]
16352                               UNSPEC_FPATAN))
16353               (clobber (match_scratch:XF 8 ""))])
16354    (set (match_operand:SF 0 "register_operand" "")
16355         (float_truncate:SF (match_dup 7)))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358    && flag_unsafe_math_optimizations"
16360   int i;
16362   for (i=2; i<8; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16365   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16368 (define_expand "acosxf2"
16369   [(set (match_dup 2)
16370         (mult:XF (match_operand:XF 1 "register_operand" "")
16371                  (match_dup 1)))
16372    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374    (parallel [(set (match_operand:XF 0 "register_operand" "")
16375                    (unspec:XF [(match_dup 1) (match_dup 5)]
16376                               UNSPEC_FPATAN))
16377               (clobber (match_scratch:XF 6 ""))])]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16381   int i;
16383   for (i=2; i<6; i++)
16384     operands[i] = gen_reg_rtx (XFmode);
16386   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16389 (define_insn "fyl2x_xf3"
16390   [(set (match_operand:XF 0 "register_operand" "=f")
16391         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392                     (match_operand:XF 1 "register_operand" "u")]
16393                    UNSPEC_FYL2X))
16394    (clobber (match_scratch:XF 3 "=1"))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && flag_unsafe_math_optimizations"
16397   "fyl2x"
16398   [(set_attr "type" "fpspc")
16399    (set_attr "mode" "XF")])
16401 (define_expand "logsf2"
16402   [(set (match_dup 2)
16403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404    (parallel [(set (match_dup 4)
16405                    (unspec:XF [(match_dup 2)
16406                                (match_dup 3)] UNSPEC_FYL2X))
16407               (clobber (match_scratch:XF 5 ""))])
16408    (set (match_operand:SF 0 "register_operand" "")
16409         (float_truncate:SF (match_dup 4)))]
16410   "TARGET_USE_FANCY_MATH_387
16411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412    && flag_unsafe_math_optimizations"
16414   rtx temp;
16416   operands[2] = gen_reg_rtx (XFmode);
16417   operands[3] = gen_reg_rtx (XFmode);
16418   operands[4] = gen_reg_rtx (XFmode);
16420   temp = standard_80387_constant_rtx (4); /* fldln2 */
16421   emit_move_insn (operands[3], temp);
16424 (define_expand "logdf2"
16425   [(set (match_dup 2)
16426         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427    (parallel [(set (match_dup 4)
16428                    (unspec:XF [(match_dup 2)
16429                                (match_dup 3)] UNSPEC_FYL2X))
16430               (clobber (match_scratch:XF 5 ""))])
16431    (set (match_operand:DF 0 "register_operand" "")
16432         (float_truncate:DF (match_dup 4)))]
16433   "TARGET_USE_FANCY_MATH_387
16434    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations"
16437   rtx temp;
16439   operands[2] = gen_reg_rtx (XFmode);
16440   operands[3] = gen_reg_rtx (XFmode);
16441   operands[4] = gen_reg_rtx (XFmode);
16443   temp = standard_80387_constant_rtx (4); /* fldln2 */
16444   emit_move_insn (operands[3], temp);
16447 (define_expand "logxf2"
16448   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450                                (match_dup 2)] UNSPEC_FYL2X))
16451               (clobber (match_scratch:XF 3 ""))])]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16455   rtx temp;
16457   operands[2] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (4); /* fldln2 */
16459   emit_move_insn (operands[2], temp);
16462 (define_expand "log10sf2"
16463   [(set (match_dup 2)
16464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465    (parallel [(set (match_dup 4)
16466                    (unspec:XF [(match_dup 2)
16467                                (match_dup 3)] UNSPEC_FYL2X))
16468               (clobber (match_scratch:XF 5 ""))])
16469    (set (match_operand:SF 0 "register_operand" "")
16470         (float_truncate:SF (match_dup 4)))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473    && flag_unsafe_math_optimizations"
16475   rtx temp;
16477   operands[2] = gen_reg_rtx (XFmode);
16478   operands[3] = gen_reg_rtx (XFmode);
16479   operands[4] = gen_reg_rtx (XFmode);
16481   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482   emit_move_insn (operands[3], temp);
16485 (define_expand "log10df2"
16486   [(set (match_dup 2)
16487         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488    (parallel [(set (match_dup 4)
16489                    (unspec:XF [(match_dup 2)
16490                                (match_dup 3)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 5 ""))])
16492    (set (match_operand:DF 0 "register_operand" "")
16493         (float_truncate:DF (match_dup 4)))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496    && flag_unsafe_math_optimizations"
16498   rtx temp;
16500   operands[2] = gen_reg_rtx (XFmode);
16501   operands[3] = gen_reg_rtx (XFmode);
16502   operands[4] = gen_reg_rtx (XFmode);
16504   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505   emit_move_insn (operands[3], temp);
16508 (define_expand "log10xf2"
16509   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511                                (match_dup 2)] UNSPEC_FYL2X))
16512               (clobber (match_scratch:XF 3 ""))])]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16516   rtx temp;
16518   operands[2] = gen_reg_rtx (XFmode);
16519   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520   emit_move_insn (operands[2], temp);
16523 (define_expand "log2sf2"
16524   [(set (match_dup 2)
16525         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526    (parallel [(set (match_dup 4)
16527                    (unspec:XF [(match_dup 2)
16528                                (match_dup 3)] UNSPEC_FYL2X))
16529               (clobber (match_scratch:XF 5 ""))])
16530    (set (match_operand:SF 0 "register_operand" "")
16531         (float_truncate:SF (match_dup 4)))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534    && flag_unsafe_math_optimizations"
16536   operands[2] = gen_reg_rtx (XFmode);
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16540   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16543 (define_expand "log2df2"
16544   [(set (match_dup 2)
16545         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546    (parallel [(set (match_dup 4)
16547                    (unspec:XF [(match_dup 2)
16548                                (match_dup 3)] UNSPEC_FYL2X))
16549               (clobber (match_scratch:XF 5 ""))])
16550    (set (match_operand:DF 0 "register_operand" "")
16551         (float_truncate:DF (match_dup 4)))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations"
16556   operands[2] = gen_reg_rtx (XFmode);
16557   operands[3] = gen_reg_rtx (XFmode);
16558   operands[4] = gen_reg_rtx (XFmode);
16560   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16563 (define_expand "log2xf2"
16564   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566                                (match_dup 2)] UNSPEC_FYL2X))
16567               (clobber (match_scratch:XF 3 ""))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16571   operands[2] = gen_reg_rtx (XFmode);
16572   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16575 (define_insn "fyl2xp1_xf3"
16576   [(set (match_operand:XF 0 "register_operand" "=f")
16577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578                     (match_operand:XF 1 "register_operand" "u")]
16579                    UNSPEC_FYL2XP1))
16580    (clobber (match_scratch:XF 3 "=1"))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && flag_unsafe_math_optimizations"
16583   "fyl2xp1"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16587 (define_expand "log1psf2"
16588   [(use (match_operand:SF 0 "register_operand" ""))
16589    (use (match_operand:SF 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592    && flag_unsafe_math_optimizations"
16594   rtx op0 = gen_reg_rtx (XFmode);
16595   rtx op1 = gen_reg_rtx (XFmode);
16597   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598   ix86_emit_i387_log1p (op0, op1);
16599   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16600   DONE;
16603 (define_expand "log1pdf2"
16604   [(use (match_operand:DF 0 "register_operand" ""))
16605    (use (match_operand:DF 1 "register_operand" ""))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608    && flag_unsafe_math_optimizations"
16610   rtx op0 = gen_reg_rtx (XFmode);
16611   rtx op1 = gen_reg_rtx (XFmode);
16613   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614   ix86_emit_i387_log1p (op0, op1);
16615   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16616   DONE;
16619 (define_expand "log1pxf2"
16620   [(use (match_operand:XF 0 "register_operand" ""))
16621    (use (match_operand:XF 1 "register_operand" ""))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16625   ix86_emit_i387_log1p (operands[0], operands[1]);
16626   DONE;
16629 (define_insn "*fxtractxf3"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632                    UNSPEC_XTRACT_FRACT))
16633    (set (match_operand:XF 1 "register_operand" "=u")
16634         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations"
16637   "fxtract"
16638   [(set_attr "type" "fpspc")
16639    (set_attr "mode" "XF")])
16641 (define_expand "logbsf2"
16642   [(set (match_dup 2)
16643         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644    (parallel [(set (match_dup 3)
16645                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646               (set (match_dup 4)
16647                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648    (set (match_operand:SF 0 "register_operand" "")
16649         (float_truncate:SF (match_dup 4)))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652    && flag_unsafe_math_optimizations"
16654   operands[2] = gen_reg_rtx (XFmode);
16655   operands[3] = gen_reg_rtx (XFmode);
16656   operands[4] = gen_reg_rtx (XFmode);
16659 (define_expand "logbdf2"
16660   [(set (match_dup 2)
16661         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662    (parallel [(set (match_dup 3)
16663                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664               (set (match_dup 4)
16665                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666    (set (match_operand:DF 0 "register_operand" "")
16667         (float_truncate:DF (match_dup 4)))]
16668   "TARGET_USE_FANCY_MATH_387
16669    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations"
16672   operands[2] = gen_reg_rtx (XFmode);
16673   operands[3] = gen_reg_rtx (XFmode);
16674   operands[4] = gen_reg_rtx (XFmode);
16677 (define_expand "logbxf2"
16678   [(parallel [(set (match_dup 2)
16679                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680                               UNSPEC_XTRACT_FRACT))
16681               (set (match_operand:XF 0 "register_operand" "")
16682                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16686   operands[2] = gen_reg_rtx (XFmode);
16689 (define_expand "ilogbsi2"
16690   [(parallel [(set (match_dup 2)
16691                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692                               UNSPEC_XTRACT_FRACT))
16693               (set (match_operand:XF 3 "register_operand" "")
16694                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695    (parallel [(set (match_operand:SI 0 "register_operand" "")
16696                    (fix:SI (match_dup 3)))
16697               (clobber (reg:CC FLAGS_REG))])]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16702   operands[2] = gen_reg_rtx (XFmode);
16703   operands[3] = gen_reg_rtx (XFmode);
16706 (define_insn "*f2xm1xf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709          UNSPEC_F2XM1))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations"
16712   "f2xm1"
16713   [(set_attr "type" "fpspc")
16714    (set_attr "mode" "XF")])
16716 (define_insn "*fscalexf4"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719                     (match_operand:XF 3 "register_operand" "1")]
16720                    UNSPEC_FSCALE_FRACT))
16721    (set (match_operand:XF 1 "register_operand" "=u")
16722         (unspec:XF [(match_dup 2) (match_dup 3)]
16723                    UNSPEC_FSCALE_EXP))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && flag_unsafe_math_optimizations"
16726   "fscale"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")])
16730 (define_expand "expsf2"
16731   [(set (match_dup 2)
16732         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738    (parallel [(set (match_dup 10)
16739                    (unspec:XF [(match_dup 9) (match_dup 5)]
16740                               UNSPEC_FSCALE_FRACT))
16741               (set (match_dup 11)
16742                    (unspec:XF [(match_dup 9) (match_dup 5)]
16743                               UNSPEC_FSCALE_EXP))])
16744    (set (match_operand:SF 0 "register_operand" "")
16745         (float_truncate:SF (match_dup 10)))]
16746   "TARGET_USE_FANCY_MATH_387
16747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748    && flag_unsafe_math_optimizations"
16750   rtx temp;
16751   int i;
16753   for (i=2; i<12; i++)
16754     operands[i] = gen_reg_rtx (XFmode);
16755   temp = standard_80387_constant_rtx (5); /* fldl2e */
16756   emit_move_insn (operands[3], temp);
16757   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16760 (define_expand "expdf2"
16761   [(set (match_dup 2)
16762         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768    (parallel [(set (match_dup 10)
16769                    (unspec:XF [(match_dup 9) (match_dup 5)]
16770                               UNSPEC_FSCALE_FRACT))
16771               (set (match_dup 11)
16772                    (unspec:XF [(match_dup 9) (match_dup 5)]
16773                               UNSPEC_FSCALE_EXP))])
16774    (set (match_operand:DF 0 "register_operand" "")
16775         (float_truncate:DF (match_dup 10)))]
16776   "TARGET_USE_FANCY_MATH_387
16777    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations"
16780   rtx temp;
16781   int i;
16783   for (i=2; i<12; i++)
16784     operands[i] = gen_reg_rtx (XFmode);
16785   temp = standard_80387_constant_rtx (5); /* fldl2e */
16786   emit_move_insn (operands[3], temp);
16787   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16790 (define_expand "expxf2"
16791   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792                                (match_dup 2)))
16793    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797    (parallel [(set (match_operand:XF 0 "register_operand" "")
16798                    (unspec:XF [(match_dup 8) (match_dup 4)]
16799                               UNSPEC_FSCALE_FRACT))
16800               (set (match_dup 9)
16801                    (unspec:XF [(match_dup 8) (match_dup 4)]
16802                               UNSPEC_FSCALE_EXP))])]
16803   "TARGET_USE_FANCY_MATH_387
16804    && flag_unsafe_math_optimizations"
16806   rtx temp;
16807   int i;
16809   for (i=2; i<10; i++)
16810     operands[i] = gen_reg_rtx (XFmode);
16811   temp = standard_80387_constant_rtx (5); /* fldl2e */
16812   emit_move_insn (operands[2], temp);
16813   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16816 (define_expand "exp10sf2"
16817   [(set (match_dup 2)
16818         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824    (parallel [(set (match_dup 10)
16825                    (unspec:XF [(match_dup 9) (match_dup 5)]
16826                               UNSPEC_FSCALE_FRACT))
16827               (set (match_dup 11)
16828                    (unspec:XF [(match_dup 9) (match_dup 5)]
16829                               UNSPEC_FSCALE_EXP))])
16830    (set (match_operand:SF 0 "register_operand" "")
16831         (float_truncate:SF (match_dup 10)))]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16836   rtx temp;
16837   int i;
16839   for (i=2; i<12; i++)
16840     operands[i] = gen_reg_rtx (XFmode);
16841   temp = standard_80387_constant_rtx (6); /* fldl2t */
16842   emit_move_insn (operands[3], temp);
16843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16846 (define_expand "exp10df2"
16847   [(set (match_dup 2)
16848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854    (parallel [(set (match_dup 10)
16855                    (unspec:XF [(match_dup 9) (match_dup 5)]
16856                               UNSPEC_FSCALE_FRACT))
16857               (set (match_dup 11)
16858                    (unspec:XF [(match_dup 9) (match_dup 5)]
16859                               UNSPEC_FSCALE_EXP))])
16860    (set (match_operand:DF 0 "register_operand" "")
16861         (float_truncate:DF (match_dup 10)))]
16862   "TARGET_USE_FANCY_MATH_387
16863    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864    && flag_unsafe_math_optimizations"
16866   rtx temp;
16867   int i;
16869   for (i=2; i<12; i++)
16870     operands[i] = gen_reg_rtx (XFmode);
16871   temp = standard_80387_constant_rtx (6); /* fldl2t */
16872   emit_move_insn (operands[3], temp);
16873   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16876 (define_expand "exp10xf2"
16877   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878                                (match_dup 2)))
16879    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883    (parallel [(set (match_operand:XF 0 "register_operand" "")
16884                    (unspec:XF [(match_dup 8) (match_dup 4)]
16885                               UNSPEC_FSCALE_FRACT))
16886               (set (match_dup 9)
16887                    (unspec:XF [(match_dup 8) (match_dup 4)]
16888                               UNSPEC_FSCALE_EXP))])]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16892   rtx temp;
16893   int i;
16895   for (i=2; i<10; i++)
16896     operands[i] = gen_reg_rtx (XFmode);
16897   temp = standard_80387_constant_rtx (6); /* fldl2t */
16898   emit_move_insn (operands[2], temp);
16899   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16902 (define_expand "exp2sf2"
16903   [(set (match_dup 2)
16904         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909    (parallel [(set (match_dup 8)
16910                    (unspec:XF [(match_dup 7) (match_dup 3)]
16911                               UNSPEC_FSCALE_FRACT))
16912               (set (match_dup 9)
16913                    (unspec:XF [(match_dup 7) (match_dup 3)]
16914                               UNSPEC_FSCALE_EXP))])
16915    (set (match_operand:SF 0 "register_operand" "")
16916         (float_truncate:SF (match_dup 8)))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations"
16921   int i;
16923   for (i=2; i<10; i++)
16924     operands[i] = gen_reg_rtx (XFmode);
16925   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16928 (define_expand "exp2df2"
16929   [(set (match_dup 2)
16930         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935    (parallel [(set (match_dup 8)
16936                    (unspec:XF [(match_dup 7) (match_dup 3)]
16937                               UNSPEC_FSCALE_FRACT))
16938               (set (match_dup 9)
16939                    (unspec:XF [(match_dup 7) (match_dup 3)]
16940                               UNSPEC_FSCALE_EXP))])
16941    (set (match_operand:DF 0 "register_operand" "")
16942         (float_truncate:DF (match_dup 8)))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16947   int i;
16949   for (i=2; i<10; i++)
16950     operands[i] = gen_reg_rtx (XFmode);
16951   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16954 (define_expand "exp2xf2"
16955   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960    (parallel [(set (match_operand:XF 0 "register_operand" "")
16961                    (unspec:XF [(match_dup 7) (match_dup 3)]
16962                               UNSPEC_FSCALE_FRACT))
16963               (set (match_dup 8)
16964                    (unspec:XF [(match_dup 7) (match_dup 3)]
16965                               UNSPEC_FSCALE_EXP))])]
16966   "TARGET_USE_FANCY_MATH_387
16967    && flag_unsafe_math_optimizations"
16969   int i;
16971   for (i=2; i<9; i++)
16972     operands[i] = gen_reg_rtx (XFmode);
16973   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16976 (define_expand "expm1df2"
16977   [(set (match_dup 2)
16978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983    (parallel [(set (match_dup 8)
16984                    (unspec:XF [(match_dup 7) (match_dup 5)]
16985                               UNSPEC_FSCALE_FRACT))
16986                    (set (match_dup 9)
16987                    (unspec:XF [(match_dup 7) (match_dup 5)]
16988                               UNSPEC_FSCALE_EXP))])
16989    (parallel [(set (match_dup 11)
16990                    (unspec:XF [(match_dup 10) (match_dup 9)]
16991                               UNSPEC_FSCALE_FRACT))
16992               (set (match_dup 12)
16993                    (unspec:XF [(match_dup 10) (match_dup 9)]
16994                               UNSPEC_FSCALE_EXP))])
16995    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997    (set (match_operand:DF 0 "register_operand" "")
16998         (float_truncate:DF (match_dup 14)))]
16999   "TARGET_USE_FANCY_MATH_387
17000    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17003   rtx temp;
17004   int i;
17006   for (i=2; i<15; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008   temp = standard_80387_constant_rtx (5); /* fldl2e */
17009   emit_move_insn (operands[3], temp);
17010   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17013 (define_expand "expm1sf2"
17014   [(set (match_dup 2)
17015         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020    (parallel [(set (match_dup 8)
17021                    (unspec:XF [(match_dup 7) (match_dup 5)]
17022                               UNSPEC_FSCALE_FRACT))
17023                    (set (match_dup 9)
17024                    (unspec:XF [(match_dup 7) (match_dup 5)]
17025                               UNSPEC_FSCALE_EXP))])
17026    (parallel [(set (match_dup 11)
17027                    (unspec:XF [(match_dup 10) (match_dup 9)]
17028                               UNSPEC_FSCALE_FRACT))
17029               (set (match_dup 12)
17030                    (unspec:XF [(match_dup 10) (match_dup 9)]
17031                               UNSPEC_FSCALE_EXP))])
17032    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034    (set (match_operand:SF 0 "register_operand" "")
17035         (float_truncate:SF (match_dup 14)))]
17036   "TARGET_USE_FANCY_MATH_387
17037    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038    && flag_unsafe_math_optimizations"
17040   rtx temp;
17041   int i;
17043   for (i=2; i<15; i++)
17044     operands[i] = gen_reg_rtx (XFmode);
17045   temp = standard_80387_constant_rtx (5); /* fldl2e */
17046   emit_move_insn (operands[3], temp);
17047   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17050 (define_expand "expm1xf2"
17051   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052                                (match_dup 2)))
17053    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056    (parallel [(set (match_dup 7)
17057                    (unspec:XF [(match_dup 6) (match_dup 4)]
17058                               UNSPEC_FSCALE_FRACT))
17059                    (set (match_dup 8)
17060                    (unspec:XF [(match_dup 6) (match_dup 4)]
17061                               UNSPEC_FSCALE_EXP))])
17062    (parallel [(set (match_dup 10)
17063                    (unspec:XF [(match_dup 9) (match_dup 8)]
17064                               UNSPEC_FSCALE_FRACT))
17065               (set (match_dup 11)
17066                    (unspec:XF [(match_dup 9) (match_dup 8)]
17067                               UNSPEC_FSCALE_EXP))])
17068    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069    (set (match_operand:XF 0 "register_operand" "")
17070         (plus:XF (match_dup 12) (match_dup 7)))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17074   rtx temp;
17075   int i;
17077   for (i=2; i<13; i++)
17078     operands[i] = gen_reg_rtx (XFmode);
17079   temp = standard_80387_constant_rtx (5); /* fldl2e */
17080   emit_move_insn (operands[2], temp);
17081   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17084 (define_expand "ldexpdf3"
17085   [(set (match_dup 3)
17086         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087    (set (match_dup 4)
17088         (float:XF (match_operand:SI 2 "register_operand" "")))
17089    (parallel [(set (match_dup 5)
17090                    (unspec:XF [(match_dup 3) (match_dup 4)]
17091                               UNSPEC_FSCALE_FRACT))
17092               (set (match_dup 6)
17093                    (unspec:XF [(match_dup 3) (match_dup 4)]
17094                               UNSPEC_FSCALE_EXP))])
17095    (set (match_operand:DF 0 "register_operand" "")
17096         (float_truncate:DF (match_dup 5)))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17101   int i;
17103   for (i=3; i<7; i++)
17104     operands[i] = gen_reg_rtx (XFmode);
17107 (define_expand "ldexpsf3"
17108   [(set (match_dup 3)
17109         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110    (set (match_dup 4)
17111         (float:XF (match_operand:SI 2 "register_operand" "")))
17112    (parallel [(set (match_dup 5)
17113                    (unspec:XF [(match_dup 3) (match_dup 4)]
17114                               UNSPEC_FSCALE_FRACT))
17115               (set (match_dup 6)
17116                    (unspec:XF [(match_dup 3) (match_dup 4)]
17117                               UNSPEC_FSCALE_EXP))])
17118    (set (match_operand:SF 0 "register_operand" "")
17119         (float_truncate:SF (match_dup 5)))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122    && flag_unsafe_math_optimizations"
17124   int i;
17126   for (i=3; i<7; i++)
17127     operands[i] = gen_reg_rtx (XFmode);
17130 (define_expand "ldexpxf3"
17131   [(set (match_dup 3)
17132         (float:XF (match_operand:SI 2 "register_operand" "")))
17133    (parallel [(set (match_operand:XF 0 " register_operand" "")
17134                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135                                (match_dup 3)]
17136                               UNSPEC_FSCALE_FRACT))
17137               (set (match_dup 4)
17138                    (unspec:XF [(match_dup 1) (match_dup 3)]
17139                               UNSPEC_FSCALE_EXP))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && flag_unsafe_math_optimizations"
17143   int i;
17145   for (i=3; i<5; i++)
17146     operands[i] = gen_reg_rtx (XFmode);
17150 (define_insn "frndintxf2"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153          UNSPEC_FRNDINT))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "frndint"
17157   [(set_attr "type" "fpspc")
17158    (set_attr "mode" "XF")])
17160 (define_expand "rintdf2"
17161   [(use (match_operand:DF 0 "register_operand" ""))
17162    (use (match_operand:DF 1 "register_operand" ""))]
17163   "TARGET_USE_FANCY_MATH_387
17164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165    && flag_unsafe_math_optimizations"
17167   rtx op0 = gen_reg_rtx (XFmode);
17168   rtx op1 = gen_reg_rtx (XFmode);
17170   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17171   emit_insn (gen_frndintxf2 (op0, op1));
17173   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17174   DONE;
17177 (define_expand "rintsf2"
17178   [(use (match_operand:SF 0 "register_operand" ""))
17179    (use (match_operand:SF 1 "register_operand" ""))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182    && flag_unsafe_math_optimizations"
17184   rtx op0 = gen_reg_rtx (XFmode);
17185   rtx op1 = gen_reg_rtx (XFmode);
17187   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17188   emit_insn (gen_frndintxf2 (op0, op1));
17190   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17191   DONE;
17194 (define_expand "rintxf2"
17195   [(use (match_operand:XF 0 "register_operand" ""))
17196    (use (match_operand:XF 1 "register_operand" ""))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && flag_unsafe_math_optimizations"
17200   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17201   DONE;
17204 (define_insn_and_split "*fistdi2_1"
17205   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17206         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17207          UNSPEC_FIST))]
17208   "TARGET_USE_FANCY_MATH_387
17209    && flag_unsafe_math_optimizations
17210    && !(reload_completed || reload_in_progress)"
17211   "#"
17212   "&& 1"
17213   [(const_int 0)]
17215   if (memory_operand (operands[0], VOIDmode))
17216     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17217   else
17218     {
17219       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17220       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17221                                          operands[2]));
17222     }
17223   DONE;
17225   [(set_attr "type" "fpspc")
17226    (set_attr "mode" "DI")])
17228 (define_insn "fistdi2"
17229   [(set (match_operand:DI 0 "memory_operand" "=m")
17230         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17231          UNSPEC_FIST))
17232    (clobber (match_scratch:XF 2 "=&1f"))]
17233   "TARGET_USE_FANCY_MATH_387
17234    && flag_unsafe_math_optimizations"
17235   "* return output_fix_trunc (insn, operands, 0);"
17236   [(set_attr "type" "fpspc")
17237    (set_attr "mode" "DI")])
17239 (define_insn "fistdi2_with_temp"
17240   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17241         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17242          UNSPEC_FIST))
17243    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17244    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17245   "TARGET_USE_FANCY_MATH_387
17246    && flag_unsafe_math_optimizations"
17247   "#"
17248   [(set_attr "type" "fpspc")
17249    (set_attr "mode" "DI")])
17251 (define_split 
17252   [(set (match_operand:DI 0 "register_operand" "")
17253         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17254          UNSPEC_FIST))
17255    (clobber (match_operand:DI 2 "memory_operand" ""))
17256    (clobber (match_scratch 3 ""))]
17257   "reload_completed"
17258   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17259               (clobber (match_dup 3))])
17260    (set (match_dup 0) (match_dup 2))]
17261   "")
17263 (define_split 
17264   [(set (match_operand:DI 0 "memory_operand" "")
17265         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17266          UNSPEC_FIST))
17267    (clobber (match_operand:DI 2 "memory_operand" ""))
17268    (clobber (match_scratch 3 ""))]
17269   "reload_completed"
17270   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17271               (clobber (match_dup 3))])]
17272   "")
17274 (define_insn_and_split "*fist<mode>2_1"
17275   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17276         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17277          UNSPEC_FIST))]
17278   "TARGET_USE_FANCY_MATH_387
17279    && flag_unsafe_math_optimizations
17280    && !(reload_completed || reload_in_progress)"
17281   "#"
17282   "&& 1"
17283   [(const_int 0)]
17285   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17286   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17287                                         operands[2]));
17288   DONE;
17290   [(set_attr "type" "fpspc")
17291    (set_attr "mode" "<MODE>")])
17293 (define_insn "fist<mode>2"
17294   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17295         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17296          UNSPEC_FIST))]
17297   "TARGET_USE_FANCY_MATH_387
17298    && flag_unsafe_math_optimizations"
17299   "* return output_fix_trunc (insn, operands, 0);"
17300   [(set_attr "type" "fpspc")
17301    (set_attr "mode" "<MODE>")])
17303 (define_insn "fist<mode>2_with_temp"
17304   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17305         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17306          UNSPEC_FIST))
17307    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && flag_unsafe_math_optimizations"
17310   "#"
17311   [(set_attr "type" "fpspc")
17312    (set_attr "mode" "<MODE>")])
17314 (define_split 
17315   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17316         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17317          UNSPEC_FIST))
17318    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17319   "reload_completed"
17320   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17321                        UNSPEC_FIST))
17322    (set (match_dup 0) (match_dup 2))]
17323   "")
17325 (define_split 
17326   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17327         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17328          UNSPEC_FIST))
17329    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17330   "reload_completed"
17331   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17332                        UNSPEC_FIST))]
17333   "")
17335 (define_expand "lrint<mode>2"
17336   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17337         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17338          UNSPEC_FIST))]
17339   "TARGET_USE_FANCY_MATH_387
17340    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17341    && flag_unsafe_math_optimizations"
17342   "")
17344 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17345 (define_insn_and_split "frndintxf2_floor"
17346   [(set (match_operand:XF 0 "register_operand" "=f")
17347         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17348          UNSPEC_FRNDINT_FLOOR))
17349    (clobber (reg:CC FLAGS_REG))]
17350   "TARGET_USE_FANCY_MATH_387
17351    && flag_unsafe_math_optimizations
17352    && !(reload_completed || reload_in_progress)"
17353   "#"
17354   "&& 1"
17355   [(const_int 0)]
17357   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17359   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17360   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17362   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17363                                         operands[2], operands[3]));
17364   DONE;
17366   [(set_attr "type" "frndint")
17367    (set_attr "i387_cw" "floor")
17368    (set_attr "mode" "XF")])
17370 (define_insn "frndintxf2_floor_i387"
17371   [(set (match_operand:XF 0 "register_operand" "=f")
17372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17373          UNSPEC_FRNDINT_FLOOR))
17374    (use (match_operand:HI 2 "memory_operand" "m"))
17375    (use (match_operand:HI 3 "memory_operand" "m"))]
17376   "TARGET_USE_FANCY_MATH_387
17377    && flag_unsafe_math_optimizations"
17378   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17379   [(set_attr "type" "frndint")
17380    (set_attr "i387_cw" "floor")
17381    (set_attr "mode" "XF")])
17383 (define_expand "floorxf2"
17384   [(use (match_operand:XF 0 "register_operand" ""))
17385    (use (match_operand:XF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && flag_unsafe_math_optimizations"
17389   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17390   DONE;
17393 (define_expand "floordf2"
17394   [(use (match_operand:DF 0 "register_operand" ""))
17395    (use (match_operand:DF 1 "register_operand" ""))]
17396   "TARGET_USE_FANCY_MATH_387
17397    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17398    && flag_unsafe_math_optimizations"
17400   rtx op0 = gen_reg_rtx (XFmode);
17401   rtx op1 = gen_reg_rtx (XFmode);
17403   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17404   emit_insn (gen_frndintxf2_floor (op0, op1));
17406   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17407   DONE;
17410 (define_expand "floorsf2"
17411   [(use (match_operand:SF 0 "register_operand" ""))
17412    (use (match_operand:SF 1 "register_operand" ""))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17415    && flag_unsafe_math_optimizations"
17417   rtx op0 = gen_reg_rtx (XFmode);
17418   rtx op1 = gen_reg_rtx (XFmode);
17420   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17421   emit_insn (gen_frndintxf2_floor (op0, op1));
17423   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17424   DONE;
17427 (define_insn_and_split "*fist<mode>2_floor_1"
17428   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17429         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17430          UNSPEC_FIST_FLOOR))
17431    (clobber (reg:CC FLAGS_REG))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && flag_unsafe_math_optimizations
17434    && !(reload_completed || reload_in_progress)"
17435   "#"
17436   "&& 1"
17437   [(const_int 0)]
17439   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17441   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17442   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17443   if (memory_operand (operands[0], VOIDmode))
17444     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17445                                       operands[2], operands[3]));
17446   else
17447     {
17448       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17449       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17450                                                   operands[2], operands[3],
17451                                                   operands[4]));
17452     }
17453   DONE;
17455   [(set_attr "type" "fistp")
17456    (set_attr "i387_cw" "floor")
17457    (set_attr "mode" "<MODE>")])
17459 (define_insn "fistdi2_floor"
17460   [(set (match_operand:DI 0 "memory_operand" "=m")
17461         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17462          UNSPEC_FIST_FLOOR))
17463    (use (match_operand:HI 2 "memory_operand" "m"))
17464    (use (match_operand:HI 3 "memory_operand" "m"))
17465    (clobber (match_scratch:XF 4 "=&1f"))]
17466   "TARGET_USE_FANCY_MATH_387
17467    && flag_unsafe_math_optimizations"
17468   "* return output_fix_trunc (insn, operands, 0);"
17469   [(set_attr "type" "fistp")
17470    (set_attr "i387_cw" "floor")
17471    (set_attr "mode" "DI")])
17473 (define_insn "fistdi2_floor_with_temp"
17474   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17475         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17476          UNSPEC_FIST_FLOOR))
17477    (use (match_operand:HI 2 "memory_operand" "m,m"))
17478    (use (match_operand:HI 3 "memory_operand" "m,m"))
17479    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17480    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17481   "TARGET_USE_FANCY_MATH_387
17482    && flag_unsafe_math_optimizations"
17483   "#"
17484   [(set_attr "type" "fistp")
17485    (set_attr "i387_cw" "floor")
17486    (set_attr "mode" "DI")])
17488 (define_split 
17489   [(set (match_operand:DI 0 "register_operand" "")
17490         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17491          UNSPEC_FIST_FLOOR))
17492    (use (match_operand:HI 2 "memory_operand" ""))
17493    (use (match_operand:HI 3 "memory_operand" ""))
17494    (clobber (match_operand:DI 4 "memory_operand" ""))
17495    (clobber (match_scratch 5 ""))]
17496   "reload_completed"
17497   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17498               (use (match_dup 2))
17499               (use (match_dup 3))
17500               (clobber (match_dup 5))])
17501    (set (match_dup 0) (match_dup 4))]
17502   "")
17504 (define_split 
17505   [(set (match_operand:DI 0 "memory_operand" "")
17506         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17507          UNSPEC_FIST_FLOOR))
17508    (use (match_operand:HI 2 "memory_operand" ""))
17509    (use (match_operand:HI 3 "memory_operand" ""))
17510    (clobber (match_operand:DI 4 "memory_operand" ""))
17511    (clobber (match_scratch 5 ""))]
17512   "reload_completed"
17513   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17514               (use (match_dup 2))
17515               (use (match_dup 3))
17516               (clobber (match_dup 5))])]
17517   "")
17519 (define_insn "fist<mode>2_floor"
17520   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17521         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17522          UNSPEC_FIST_FLOOR))
17523    (use (match_operand:HI 2 "memory_operand" "m"))
17524    (use (match_operand:HI 3 "memory_operand" "m"))]
17525   "TARGET_USE_FANCY_MATH_387
17526    && flag_unsafe_math_optimizations"
17527   "* return output_fix_trunc (insn, operands, 0);"
17528   [(set_attr "type" "fistp")
17529    (set_attr "i387_cw" "floor")
17530    (set_attr "mode" "<MODE>")])
17532 (define_insn "fist<mode>2_floor_with_temp"
17533   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17534         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17535          UNSPEC_FIST_FLOOR))
17536    (use (match_operand:HI 2 "memory_operand" "m,m"))
17537    (use (match_operand:HI 3 "memory_operand" "m,m"))
17538    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17539   "TARGET_USE_FANCY_MATH_387
17540    && flag_unsafe_math_optimizations"
17541   "#"
17542   [(set_attr "type" "fistp")
17543    (set_attr "i387_cw" "floor")
17544    (set_attr "mode" "<MODE>")])
17546 (define_split 
17547   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17548         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17549          UNSPEC_FIST_FLOOR))
17550    (use (match_operand:HI 2 "memory_operand" ""))
17551    (use (match_operand:HI 3 "memory_operand" ""))
17552    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17553   "reload_completed"
17554   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17555                                   UNSPEC_FIST_FLOOR))
17556               (use (match_dup 2))
17557               (use (match_dup 3))])
17558    (set (match_dup 0) (match_dup 4))]
17559   "")
17561 (define_split 
17562   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17563         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17564          UNSPEC_FIST_FLOOR))
17565    (use (match_operand:HI 2 "memory_operand" ""))
17566    (use (match_operand:HI 3 "memory_operand" ""))
17567    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17568   "reload_completed"
17569   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17570                                   UNSPEC_FIST_FLOOR))
17571               (use (match_dup 2))
17572               (use (match_dup 3))])]
17573   "")
17575 (define_expand "lfloor<mode>2"
17576   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17577                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17578                     UNSPEC_FIST_FLOOR))
17579               (clobber (reg:CC FLAGS_REG))])]
17580   "TARGET_USE_FANCY_MATH_387
17581    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17582    && flag_unsafe_math_optimizations"
17583   "")
17585 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17586 (define_insn_and_split "frndintxf2_ceil"
17587   [(set (match_operand:XF 0 "register_operand" "=f")
17588         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17589          UNSPEC_FRNDINT_CEIL))
17590    (clobber (reg:CC FLAGS_REG))]
17591   "TARGET_USE_FANCY_MATH_387
17592    && flag_unsafe_math_optimizations
17593    && !(reload_completed || reload_in_progress)"
17594   "#"
17595   "&& 1"
17596   [(const_int 0)]
17598   ix86_optimize_mode_switching[I387_CEIL] = 1;
17600   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17601   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17603   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17604                                        operands[2], operands[3]));
17605   DONE;
17607   [(set_attr "type" "frndint")
17608    (set_attr "i387_cw" "ceil")
17609    (set_attr "mode" "XF")])
17611 (define_insn "frndintxf2_ceil_i387"
17612   [(set (match_operand:XF 0 "register_operand" "=f")
17613         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17614          UNSPEC_FRNDINT_CEIL))
17615    (use (match_operand:HI 2 "memory_operand" "m"))
17616    (use (match_operand:HI 3 "memory_operand" "m"))]
17617   "TARGET_USE_FANCY_MATH_387
17618    && flag_unsafe_math_optimizations"
17619   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17620   [(set_attr "type" "frndint")
17621    (set_attr "i387_cw" "ceil")
17622    (set_attr "mode" "XF")])
17624 (define_expand "ceilxf2"
17625   [(use (match_operand:XF 0 "register_operand" ""))
17626    (use (match_operand:XF 1 "register_operand" ""))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17630   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17631   DONE;
17634 (define_expand "ceildf2"
17635   [(use (match_operand:DF 0 "register_operand" ""))
17636    (use (match_operand:DF 1 "register_operand" ""))]
17637   "TARGET_USE_FANCY_MATH_387
17638    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17639    && flag_unsafe_math_optimizations"
17641   rtx op0 = gen_reg_rtx (XFmode);
17642   rtx op1 = gen_reg_rtx (XFmode);
17644   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17645   emit_insn (gen_frndintxf2_ceil (op0, op1));
17647   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17648   DONE;
17651 (define_expand "ceilsf2"
17652   [(use (match_operand:SF 0 "register_operand" ""))
17653    (use (match_operand:SF 1 "register_operand" ""))]
17654   "TARGET_USE_FANCY_MATH_387
17655    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17656    && flag_unsafe_math_optimizations"
17658   rtx op0 = gen_reg_rtx (XFmode);
17659   rtx op1 = gen_reg_rtx (XFmode);
17661   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17662   emit_insn (gen_frndintxf2_ceil (op0, op1));
17664   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17665   DONE;
17668 (define_insn_and_split "*fist<mode>2_ceil_1"
17669   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17670         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17671          UNSPEC_FIST_CEIL))
17672    (clobber (reg:CC FLAGS_REG))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && flag_unsafe_math_optimizations
17675    && !(reload_completed || reload_in_progress)"
17676   "#"
17677   "&& 1"
17678   [(const_int 0)]
17680   ix86_optimize_mode_switching[I387_CEIL] = 1;
17682   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17683   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17684   if (memory_operand (operands[0], VOIDmode))
17685     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17686                                      operands[2], operands[3]));
17687   else
17688     {
17689       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17690       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17691                                                  operands[2], operands[3],
17692                                                  operands[4]));
17693     }
17694   DONE;
17696   [(set_attr "type" "fistp")
17697    (set_attr "i387_cw" "ceil")
17698    (set_attr "mode" "<MODE>")])
17700 (define_insn "fistdi2_ceil"
17701   [(set (match_operand:DI 0 "memory_operand" "=m")
17702         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17703          UNSPEC_FIST_CEIL))
17704    (use (match_operand:HI 2 "memory_operand" "m"))
17705    (use (match_operand:HI 3 "memory_operand" "m"))
17706    (clobber (match_scratch:XF 4 "=&1f"))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17709   "* return output_fix_trunc (insn, operands, 0);"
17710   [(set_attr "type" "fistp")
17711    (set_attr "i387_cw" "ceil")
17712    (set_attr "mode" "DI")])
17714 (define_insn "fistdi2_ceil_with_temp"
17715   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17716         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17717          UNSPEC_FIST_CEIL))
17718    (use (match_operand:HI 2 "memory_operand" "m,m"))
17719    (use (match_operand:HI 3 "memory_operand" "m,m"))
17720    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17721    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17722   "TARGET_USE_FANCY_MATH_387
17723    && flag_unsafe_math_optimizations"
17724   "#"
17725   [(set_attr "type" "fistp")
17726    (set_attr "i387_cw" "ceil")
17727    (set_attr "mode" "DI")])
17729 (define_split 
17730   [(set (match_operand:DI 0 "register_operand" "")
17731         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17732          UNSPEC_FIST_CEIL))
17733    (use (match_operand:HI 2 "memory_operand" ""))
17734    (use (match_operand:HI 3 "memory_operand" ""))
17735    (clobber (match_operand:DI 4 "memory_operand" ""))
17736    (clobber (match_scratch 5 ""))]
17737   "reload_completed"
17738   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17739               (use (match_dup 2))
17740               (use (match_dup 3))
17741               (clobber (match_dup 5))])
17742    (set (match_dup 0) (match_dup 4))]
17743   "")
17745 (define_split 
17746   [(set (match_operand:DI 0 "memory_operand" "")
17747         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17748          UNSPEC_FIST_CEIL))
17749    (use (match_operand:HI 2 "memory_operand" ""))
17750    (use (match_operand:HI 3 "memory_operand" ""))
17751    (clobber (match_operand:DI 4 "memory_operand" ""))
17752    (clobber (match_scratch 5 ""))]
17753   "reload_completed"
17754   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17755               (use (match_dup 2))
17756               (use (match_dup 3))
17757               (clobber (match_dup 5))])]
17758   "")
17760 (define_insn "fist<mode>2_ceil"
17761   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17762         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17763          UNSPEC_FIST_CEIL))
17764    (use (match_operand:HI 2 "memory_operand" "m"))
17765    (use (match_operand:HI 3 "memory_operand" "m"))]
17766   "TARGET_USE_FANCY_MATH_387
17767    && flag_unsafe_math_optimizations"
17768   "* return output_fix_trunc (insn, operands, 0);"
17769   [(set_attr "type" "fistp")
17770    (set_attr "i387_cw" "ceil")
17771    (set_attr "mode" "<MODE>")])
17773 (define_insn "fist<mode>2_ceil_with_temp"
17774   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17775         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17776          UNSPEC_FIST_CEIL))
17777    (use (match_operand:HI 2 "memory_operand" "m,m"))
17778    (use (match_operand:HI 3 "memory_operand" "m,m"))
17779    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17780   "TARGET_USE_FANCY_MATH_387
17781    && flag_unsafe_math_optimizations"
17782   "#"
17783   [(set_attr "type" "fistp")
17784    (set_attr "i387_cw" "ceil")
17785    (set_attr "mode" "<MODE>")])
17787 (define_split 
17788   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17789         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17790          UNSPEC_FIST_CEIL))
17791    (use (match_operand:HI 2 "memory_operand" ""))
17792    (use (match_operand:HI 3 "memory_operand" ""))
17793    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17794   "reload_completed"
17795   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17796                                   UNSPEC_FIST_CEIL))
17797               (use (match_dup 2))
17798               (use (match_dup 3))])
17799    (set (match_dup 0) (match_dup 4))]
17800   "")
17802 (define_split 
17803   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17804         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17805          UNSPEC_FIST_CEIL))
17806    (use (match_operand:HI 2 "memory_operand" ""))
17807    (use (match_operand:HI 3 "memory_operand" ""))
17808    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17809   "reload_completed"
17810   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17811                                   UNSPEC_FIST_CEIL))
17812               (use (match_dup 2))
17813               (use (match_dup 3))])]
17814   "")
17816 (define_expand "lceil<mode>2"
17817   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17818                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17819                     UNSPEC_FIST_CEIL))
17820               (clobber (reg:CC FLAGS_REG))])]
17821   "TARGET_USE_FANCY_MATH_387
17822    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17823    && flag_unsafe_math_optimizations"
17824   "")
17826 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17827 (define_insn_and_split "frndintxf2_trunc"
17828   [(set (match_operand:XF 0 "register_operand" "=f")
17829         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17830          UNSPEC_FRNDINT_TRUNC))
17831    (clobber (reg:CC FLAGS_REG))]
17832   "TARGET_USE_FANCY_MATH_387
17833    && flag_unsafe_math_optimizations
17834    && !(reload_completed || reload_in_progress)"
17835   "#"
17836   "&& 1"
17837   [(const_int 0)]
17839   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17841   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17842   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17844   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17845                                         operands[2], operands[3]));
17846   DONE;
17848   [(set_attr "type" "frndint")
17849    (set_attr "i387_cw" "trunc")
17850    (set_attr "mode" "XF")])
17852 (define_insn "frndintxf2_trunc_i387"
17853   [(set (match_operand:XF 0 "register_operand" "=f")
17854         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17855          UNSPEC_FRNDINT_TRUNC))
17856    (use (match_operand:HI 2 "memory_operand" "m"))
17857    (use (match_operand:HI 3 "memory_operand" "m"))]
17858   "TARGET_USE_FANCY_MATH_387
17859    && flag_unsafe_math_optimizations"
17860   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17861   [(set_attr "type" "frndint")
17862    (set_attr "i387_cw" "trunc")
17863    (set_attr "mode" "XF")])
17865 (define_expand "btruncxf2"
17866   [(use (match_operand:XF 0 "register_operand" ""))
17867    (use (match_operand:XF 1 "register_operand" ""))]
17868   "TARGET_USE_FANCY_MATH_387
17869    && flag_unsafe_math_optimizations"
17871   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17872   DONE;
17875 (define_expand "btruncdf2"
17876   [(use (match_operand:DF 0 "register_operand" ""))
17877    (use (match_operand:DF 1 "register_operand" ""))]
17878   "TARGET_USE_FANCY_MATH_387
17879    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17880    && flag_unsafe_math_optimizations"
17882   rtx op0 = gen_reg_rtx (XFmode);
17883   rtx op1 = gen_reg_rtx (XFmode);
17885   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17886   emit_insn (gen_frndintxf2_trunc (op0, op1));
17888   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17889   DONE;
17892 (define_expand "btruncsf2"
17893   [(use (match_operand:SF 0 "register_operand" ""))
17894    (use (match_operand:SF 1 "register_operand" ""))]
17895   "TARGET_USE_FANCY_MATH_387
17896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17897    && flag_unsafe_math_optimizations"
17899   rtx op0 = gen_reg_rtx (XFmode);
17900   rtx op1 = gen_reg_rtx (XFmode);
17902   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17903   emit_insn (gen_frndintxf2_trunc (op0, op1));
17905   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17906   DONE;
17909 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17910 (define_insn_and_split "frndintxf2_mask_pm"
17911   [(set (match_operand:XF 0 "register_operand" "=f")
17912         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17913          UNSPEC_FRNDINT_MASK_PM))
17914    (clobber (reg:CC FLAGS_REG))]
17915   "TARGET_USE_FANCY_MATH_387
17916    && flag_unsafe_math_optimizations
17917    && !(reload_completed || reload_in_progress)"
17918   "#"
17919   "&& 1"
17920   [(const_int 0)]
17922   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17924   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17925   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17927   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17928                                           operands[2], operands[3]));
17929   DONE;
17931   [(set_attr "type" "frndint")
17932    (set_attr "i387_cw" "mask_pm")
17933    (set_attr "mode" "XF")])
17935 (define_insn "frndintxf2_mask_pm_i387"
17936   [(set (match_operand:XF 0 "register_operand" "=f")
17937         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17938          UNSPEC_FRNDINT_MASK_PM))
17939    (use (match_operand:HI 2 "memory_operand" "m"))
17940    (use (match_operand:HI 3 "memory_operand" "m"))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && flag_unsafe_math_optimizations"
17943   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17944   [(set_attr "type" "frndint")
17945    (set_attr "i387_cw" "mask_pm")
17946    (set_attr "mode" "XF")])
17948 (define_expand "nearbyintxf2"
17949   [(use (match_operand:XF 0 "register_operand" ""))
17950    (use (match_operand:XF 1 "register_operand" ""))]
17951   "TARGET_USE_FANCY_MATH_387
17952    && flag_unsafe_math_optimizations"
17954   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17956   DONE;
17959 (define_expand "nearbyintdf2"
17960   [(use (match_operand:DF 0 "register_operand" ""))
17961    (use (match_operand:DF 1 "register_operand" ""))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17964    && flag_unsafe_math_optimizations"
17966   rtx op0 = gen_reg_rtx (XFmode);
17967   rtx op1 = gen_reg_rtx (XFmode);
17969   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17970   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17972   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17973   DONE;
17976 (define_expand "nearbyintsf2"
17977   [(use (match_operand:SF 0 "register_operand" ""))
17978    (use (match_operand:SF 1 "register_operand" ""))]
17979   "TARGET_USE_FANCY_MATH_387
17980    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17981    && flag_unsafe_math_optimizations"
17983   rtx op0 = gen_reg_rtx (XFmode);
17984   rtx op1 = gen_reg_rtx (XFmode);
17986   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17987   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17989   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17990   DONE;
17994 ;; Block operation instructions
17996 (define_insn "cld"
17997  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17998  ""
17999  "cld"
18000   [(set_attr "type" "cld")])
18002 (define_expand "movmemsi"
18003   [(use (match_operand:BLK 0 "memory_operand" ""))
18004    (use (match_operand:BLK 1 "memory_operand" ""))
18005    (use (match_operand:SI 2 "nonmemory_operand" ""))
18006    (use (match_operand:SI 3 "const_int_operand" ""))]
18007   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18009  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18010    DONE;
18011  else
18012    FAIL;
18015 (define_expand "movmemdi"
18016   [(use (match_operand:BLK 0 "memory_operand" ""))
18017    (use (match_operand:BLK 1 "memory_operand" ""))
18018    (use (match_operand:DI 2 "nonmemory_operand" ""))
18019    (use (match_operand:DI 3 "const_int_operand" ""))]
18020   "TARGET_64BIT"
18022  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18023    DONE;
18024  else
18025    FAIL;
18028 ;; Most CPUs don't like single string operations
18029 ;; Handle this case here to simplify previous expander.
18031 (define_expand "strmov"
18032   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18033    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18034    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18035               (clobber (reg:CC FLAGS_REG))])
18036    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18037               (clobber (reg:CC FLAGS_REG))])]
18038   ""
18040   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18042   /* If .md ever supports :P for Pmode, these can be directly
18043      in the pattern above.  */
18044   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18045   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18047   if (TARGET_SINGLE_STRINGOP || optimize_size)
18048     {
18049       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18050                                       operands[2], operands[3],
18051                                       operands[5], operands[6]));
18052       DONE;
18053     }
18055   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18058 (define_expand "strmov_singleop"
18059   [(parallel [(set (match_operand 1 "memory_operand" "")
18060                    (match_operand 3 "memory_operand" ""))
18061               (set (match_operand 0 "register_operand" "")
18062                    (match_operand 4 "" ""))
18063               (set (match_operand 2 "register_operand" "")
18064                    (match_operand 5 "" ""))
18065               (use (reg:SI DIRFLAG_REG))])]
18066   "TARGET_SINGLE_STRINGOP || optimize_size"
18067   "")
18069 (define_insn "*strmovdi_rex_1"
18070   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18071         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18072    (set (match_operand:DI 0 "register_operand" "=D")
18073         (plus:DI (match_dup 2)
18074                  (const_int 8)))
18075    (set (match_operand:DI 1 "register_operand" "=S")
18076         (plus:DI (match_dup 3)
18077                  (const_int 8)))
18078    (use (reg:SI DIRFLAG_REG))]
18079   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18080   "movsq"
18081   [(set_attr "type" "str")
18082    (set_attr "mode" "DI")
18083    (set_attr "memory" "both")])
18085 (define_insn "*strmovsi_1"
18086   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18087         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18088    (set (match_operand:SI 0 "register_operand" "=D")
18089         (plus:SI (match_dup 2)
18090                  (const_int 4)))
18091    (set (match_operand:SI 1 "register_operand" "=S")
18092         (plus:SI (match_dup 3)
18093                  (const_int 4)))
18094    (use (reg:SI DIRFLAG_REG))]
18095   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18096   "{movsl|movsd}"
18097   [(set_attr "type" "str")
18098    (set_attr "mode" "SI")
18099    (set_attr "memory" "both")])
18101 (define_insn "*strmovsi_rex_1"
18102   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18103         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18104    (set (match_operand:DI 0 "register_operand" "=D")
18105         (plus:DI (match_dup 2)
18106                  (const_int 4)))
18107    (set (match_operand:DI 1 "register_operand" "=S")
18108         (plus:DI (match_dup 3)
18109                  (const_int 4)))
18110    (use (reg:SI DIRFLAG_REG))]
18111   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18112   "{movsl|movsd}"
18113   [(set_attr "type" "str")
18114    (set_attr "mode" "SI")
18115    (set_attr "memory" "both")])
18117 (define_insn "*strmovhi_1"
18118   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18119         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18120    (set (match_operand:SI 0 "register_operand" "=D")
18121         (plus:SI (match_dup 2)
18122                  (const_int 2)))
18123    (set (match_operand:SI 1 "register_operand" "=S")
18124         (plus:SI (match_dup 3)
18125                  (const_int 2)))
18126    (use (reg:SI DIRFLAG_REG))]
18127   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18128   "movsw"
18129   [(set_attr "type" "str")
18130    (set_attr "memory" "both")
18131    (set_attr "mode" "HI")])
18133 (define_insn "*strmovhi_rex_1"
18134   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18135         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18136    (set (match_operand:DI 0 "register_operand" "=D")
18137         (plus:DI (match_dup 2)
18138                  (const_int 2)))
18139    (set (match_operand:DI 1 "register_operand" "=S")
18140         (plus:DI (match_dup 3)
18141                  (const_int 2)))
18142    (use (reg:SI DIRFLAG_REG))]
18143   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18144   "movsw"
18145   [(set_attr "type" "str")
18146    (set_attr "memory" "both")
18147    (set_attr "mode" "HI")])
18149 (define_insn "*strmovqi_1"
18150   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18151         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18152    (set (match_operand:SI 0 "register_operand" "=D")
18153         (plus:SI (match_dup 2)
18154                  (const_int 1)))
18155    (set (match_operand:SI 1 "register_operand" "=S")
18156         (plus:SI (match_dup 3)
18157                  (const_int 1)))
18158    (use (reg:SI DIRFLAG_REG))]
18159   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18160   "movsb"
18161   [(set_attr "type" "str")
18162    (set_attr "memory" "both")
18163    (set_attr "mode" "QI")])
18165 (define_insn "*strmovqi_rex_1"
18166   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18167         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18168    (set (match_operand:DI 0 "register_operand" "=D")
18169         (plus:DI (match_dup 2)
18170                  (const_int 1)))
18171    (set (match_operand:DI 1 "register_operand" "=S")
18172         (plus:DI (match_dup 3)
18173                  (const_int 1)))
18174    (use (reg:SI DIRFLAG_REG))]
18175   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18176   "movsb"
18177   [(set_attr "type" "str")
18178    (set_attr "memory" "both")
18179    (set_attr "mode" "QI")])
18181 (define_expand "rep_mov"
18182   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18183               (set (match_operand 0 "register_operand" "")
18184                    (match_operand 5 "" ""))
18185               (set (match_operand 2 "register_operand" "")
18186                    (match_operand 6 "" ""))
18187               (set (match_operand 1 "memory_operand" "")
18188                    (match_operand 3 "memory_operand" ""))
18189               (use (match_dup 4))
18190               (use (reg:SI DIRFLAG_REG))])]
18191   ""
18192   "")
18194 (define_insn "*rep_movdi_rex64"
18195   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18196    (set (match_operand:DI 0 "register_operand" "=D") 
18197         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18198                             (const_int 3))
18199                  (match_operand:DI 3 "register_operand" "0")))
18200    (set (match_operand:DI 1 "register_operand" "=S") 
18201         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18202                  (match_operand:DI 4 "register_operand" "1")))
18203    (set (mem:BLK (match_dup 3))
18204         (mem:BLK (match_dup 4)))
18205    (use (match_dup 5))
18206    (use (reg:SI DIRFLAG_REG))]
18207   "TARGET_64BIT"
18208   "{rep\;movsq|rep movsq}"
18209   [(set_attr "type" "str")
18210    (set_attr "prefix_rep" "1")
18211    (set_attr "memory" "both")
18212    (set_attr "mode" "DI")])
18214 (define_insn "*rep_movsi"
18215   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18216    (set (match_operand:SI 0 "register_operand" "=D") 
18217         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18218                             (const_int 2))
18219                  (match_operand:SI 3 "register_operand" "0")))
18220    (set (match_operand:SI 1 "register_operand" "=S") 
18221         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18222                  (match_operand:SI 4 "register_operand" "1")))
18223    (set (mem:BLK (match_dup 3))
18224         (mem:BLK (match_dup 4)))
18225    (use (match_dup 5))
18226    (use (reg:SI DIRFLAG_REG))]
18227   "!TARGET_64BIT"
18228   "{rep\;movsl|rep movsd}"
18229   [(set_attr "type" "str")
18230    (set_attr "prefix_rep" "1")
18231    (set_attr "memory" "both")
18232    (set_attr "mode" "SI")])
18234 (define_insn "*rep_movsi_rex64"
18235   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18236    (set (match_operand:DI 0 "register_operand" "=D") 
18237         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18238                             (const_int 2))
18239                  (match_operand:DI 3 "register_operand" "0")))
18240    (set (match_operand:DI 1 "register_operand" "=S") 
18241         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18242                  (match_operand:DI 4 "register_operand" "1")))
18243    (set (mem:BLK (match_dup 3))
18244         (mem:BLK (match_dup 4)))
18245    (use (match_dup 5))
18246    (use (reg:SI DIRFLAG_REG))]
18247   "TARGET_64BIT"
18248   "{rep\;movsl|rep movsd}"
18249   [(set_attr "type" "str")
18250    (set_attr "prefix_rep" "1")
18251    (set_attr "memory" "both")
18252    (set_attr "mode" "SI")])
18254 (define_insn "*rep_movqi"
18255   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18256    (set (match_operand:SI 0 "register_operand" "=D") 
18257         (plus:SI (match_operand:SI 3 "register_operand" "0")
18258                  (match_operand:SI 5 "register_operand" "2")))
18259    (set (match_operand:SI 1 "register_operand" "=S") 
18260         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18261    (set (mem:BLK (match_dup 3))
18262         (mem:BLK (match_dup 4)))
18263    (use (match_dup 5))
18264    (use (reg:SI DIRFLAG_REG))]
18265   "!TARGET_64BIT"
18266   "{rep\;movsb|rep movsb}"
18267   [(set_attr "type" "str")
18268    (set_attr "prefix_rep" "1")
18269    (set_attr "memory" "both")
18270    (set_attr "mode" "SI")])
18272 (define_insn "*rep_movqi_rex64"
18273   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18274    (set (match_operand:DI 0 "register_operand" "=D") 
18275         (plus:DI (match_operand:DI 3 "register_operand" "0")
18276                  (match_operand:DI 5 "register_operand" "2")))
18277    (set (match_operand:DI 1 "register_operand" "=S") 
18278         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18279    (set (mem:BLK (match_dup 3))
18280         (mem:BLK (match_dup 4)))
18281    (use (match_dup 5))
18282    (use (reg:SI DIRFLAG_REG))]
18283   "TARGET_64BIT"
18284   "{rep\;movsb|rep movsb}"
18285   [(set_attr "type" "str")
18286    (set_attr "prefix_rep" "1")
18287    (set_attr "memory" "both")
18288    (set_attr "mode" "SI")])
18290 (define_expand "setmemsi"
18291    [(use (match_operand:BLK 0 "memory_operand" ""))
18292     (use (match_operand:SI 1 "nonmemory_operand" ""))
18293     (use (match_operand 2 "const_int_operand" ""))
18294     (use (match_operand 3 "const_int_operand" ""))]
18295   ""
18297  /* If value to set is not zero, use the library routine.  */
18298  if (operands[2] != const0_rtx)
18299    FAIL;
18301  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18302    DONE;
18303  else
18304    FAIL;
18307 (define_expand "setmemdi"
18308    [(use (match_operand:BLK 0 "memory_operand" ""))
18309     (use (match_operand:DI 1 "nonmemory_operand" ""))
18310     (use (match_operand 2 "const_int_operand" ""))
18311     (use (match_operand 3 "const_int_operand" ""))]
18312   "TARGET_64BIT"
18314  /* If value to set is not zero, use the library routine.  */
18315  if (operands[2] != const0_rtx)
18316    FAIL;
18318  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18319    DONE;
18320  else
18321    FAIL;
18324 ;; Most CPUs don't like single string operations
18325 ;; Handle this case here to simplify previous expander.
18327 (define_expand "strset"
18328   [(set (match_operand 1 "memory_operand" "")
18329         (match_operand 2 "register_operand" ""))
18330    (parallel [(set (match_operand 0 "register_operand" "")
18331                    (match_dup 3))
18332               (clobber (reg:CC FLAGS_REG))])]
18333   ""
18335   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18336     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18338   /* If .md ever supports :P for Pmode, this can be directly
18339      in the pattern above.  */
18340   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18341                               GEN_INT (GET_MODE_SIZE (GET_MODE
18342                                                       (operands[2]))));
18343   if (TARGET_SINGLE_STRINGOP || optimize_size)
18344     {
18345       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18346                                       operands[3]));
18347       DONE;
18348     }
18351 (define_expand "strset_singleop"
18352   [(parallel [(set (match_operand 1 "memory_operand" "")
18353                    (match_operand 2 "register_operand" ""))
18354               (set (match_operand 0 "register_operand" "")
18355                    (match_operand 3 "" ""))
18356               (use (reg:SI DIRFLAG_REG))])]
18357   "TARGET_SINGLE_STRINGOP || optimize_size"
18358   "")
18360 (define_insn "*strsetdi_rex_1"
18361   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18362         (match_operand:DI 2 "register_operand" "a"))
18363    (set (match_operand:DI 0 "register_operand" "=D")
18364         (plus:DI (match_dup 1)
18365                  (const_int 8)))
18366    (use (reg:SI DIRFLAG_REG))]
18367   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368   "stosq"
18369   [(set_attr "type" "str")
18370    (set_attr "memory" "store")
18371    (set_attr "mode" "DI")])
18373 (define_insn "*strsetsi_1"
18374   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18375         (match_operand:SI 2 "register_operand" "a"))
18376    (set (match_operand:SI 0 "register_operand" "=D")
18377         (plus:SI (match_dup 1)
18378                  (const_int 4)))
18379    (use (reg:SI DIRFLAG_REG))]
18380   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18381   "{stosl|stosd}"
18382   [(set_attr "type" "str")
18383    (set_attr "memory" "store")
18384    (set_attr "mode" "SI")])
18386 (define_insn "*strsetsi_rex_1"
18387   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18388         (match_operand:SI 2 "register_operand" "a"))
18389    (set (match_operand:DI 0 "register_operand" "=D")
18390         (plus:DI (match_dup 1)
18391                  (const_int 4)))
18392    (use (reg:SI DIRFLAG_REG))]
18393   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18394   "{stosl|stosd}"
18395   [(set_attr "type" "str")
18396    (set_attr "memory" "store")
18397    (set_attr "mode" "SI")])
18399 (define_insn "*strsethi_1"
18400   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18401         (match_operand:HI 2 "register_operand" "a"))
18402    (set (match_operand:SI 0 "register_operand" "=D")
18403         (plus:SI (match_dup 1)
18404                  (const_int 2)))
18405    (use (reg:SI DIRFLAG_REG))]
18406   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18407   "stosw"
18408   [(set_attr "type" "str")
18409    (set_attr "memory" "store")
18410    (set_attr "mode" "HI")])
18412 (define_insn "*strsethi_rex_1"
18413   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18414         (match_operand:HI 2 "register_operand" "a"))
18415    (set (match_operand:DI 0 "register_operand" "=D")
18416         (plus:DI (match_dup 1)
18417                  (const_int 2)))
18418    (use (reg:SI DIRFLAG_REG))]
18419   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18420   "stosw"
18421   [(set_attr "type" "str")
18422    (set_attr "memory" "store")
18423    (set_attr "mode" "HI")])
18425 (define_insn "*strsetqi_1"
18426   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18427         (match_operand:QI 2 "register_operand" "a"))
18428    (set (match_operand:SI 0 "register_operand" "=D")
18429         (plus:SI (match_dup 1)
18430                  (const_int 1)))
18431    (use (reg:SI DIRFLAG_REG))]
18432   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18433   "stosb"
18434   [(set_attr "type" "str")
18435    (set_attr "memory" "store")
18436    (set_attr "mode" "QI")])
18438 (define_insn "*strsetqi_rex_1"
18439   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18440         (match_operand:QI 2 "register_operand" "a"))
18441    (set (match_operand:DI 0 "register_operand" "=D")
18442         (plus:DI (match_dup 1)
18443                  (const_int 1)))
18444    (use (reg:SI DIRFLAG_REG))]
18445   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18446   "stosb"
18447   [(set_attr "type" "str")
18448    (set_attr "memory" "store")
18449    (set_attr "mode" "QI")])
18451 (define_expand "rep_stos"
18452   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18453               (set (match_operand 0 "register_operand" "")
18454                    (match_operand 4 "" ""))
18455               (set (match_operand 2 "memory_operand" "") (const_int 0))
18456               (use (match_operand 3 "register_operand" ""))
18457               (use (match_dup 1))
18458               (use (reg:SI DIRFLAG_REG))])]
18459   ""
18460   "")
18462 (define_insn "*rep_stosdi_rex64"
18463   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18464    (set (match_operand:DI 0 "register_operand" "=D") 
18465         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18466                             (const_int 3))
18467                  (match_operand:DI 3 "register_operand" "0")))
18468    (set (mem:BLK (match_dup 3))
18469         (const_int 0))
18470    (use (match_operand:DI 2 "register_operand" "a"))
18471    (use (match_dup 4))
18472    (use (reg:SI DIRFLAG_REG))]
18473   "TARGET_64BIT"
18474   "{rep\;stosq|rep stosq}"
18475   [(set_attr "type" "str")
18476    (set_attr "prefix_rep" "1")
18477    (set_attr "memory" "store")
18478    (set_attr "mode" "DI")])
18480 (define_insn "*rep_stossi"
18481   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18482    (set (match_operand:SI 0 "register_operand" "=D") 
18483         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18484                             (const_int 2))
18485                  (match_operand:SI 3 "register_operand" "0")))
18486    (set (mem:BLK (match_dup 3))
18487         (const_int 0))
18488    (use (match_operand:SI 2 "register_operand" "a"))
18489    (use (match_dup 4))
18490    (use (reg:SI DIRFLAG_REG))]
18491   "!TARGET_64BIT"
18492   "{rep\;stosl|rep stosd}"
18493   [(set_attr "type" "str")
18494    (set_attr "prefix_rep" "1")
18495    (set_attr "memory" "store")
18496    (set_attr "mode" "SI")])
18498 (define_insn "*rep_stossi_rex64"
18499   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18500    (set (match_operand:DI 0 "register_operand" "=D") 
18501         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18502                             (const_int 2))
18503                  (match_operand:DI 3 "register_operand" "0")))
18504    (set (mem:BLK (match_dup 3))
18505         (const_int 0))
18506    (use (match_operand:SI 2 "register_operand" "a"))
18507    (use (match_dup 4))
18508    (use (reg:SI DIRFLAG_REG))]
18509   "TARGET_64BIT"
18510   "{rep\;stosl|rep stosd}"
18511   [(set_attr "type" "str")
18512    (set_attr "prefix_rep" "1")
18513    (set_attr "memory" "store")
18514    (set_attr "mode" "SI")])
18516 (define_insn "*rep_stosqi"
18517   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18518    (set (match_operand:SI 0 "register_operand" "=D") 
18519         (plus:SI (match_operand:SI 3 "register_operand" "0")
18520                  (match_operand:SI 4 "register_operand" "1")))
18521    (set (mem:BLK (match_dup 3))
18522         (const_int 0))
18523    (use (match_operand:QI 2 "register_operand" "a"))
18524    (use (match_dup 4))
18525    (use (reg:SI DIRFLAG_REG))]
18526   "!TARGET_64BIT"
18527   "{rep\;stosb|rep stosb}"
18528   [(set_attr "type" "str")
18529    (set_attr "prefix_rep" "1")
18530    (set_attr "memory" "store")
18531    (set_attr "mode" "QI")])
18533 (define_insn "*rep_stosqi_rex64"
18534   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18535    (set (match_operand:DI 0 "register_operand" "=D") 
18536         (plus:DI (match_operand:DI 3 "register_operand" "0")
18537                  (match_operand:DI 4 "register_operand" "1")))
18538    (set (mem:BLK (match_dup 3))
18539         (const_int 0))
18540    (use (match_operand:QI 2 "register_operand" "a"))
18541    (use (match_dup 4))
18542    (use (reg:SI DIRFLAG_REG))]
18543   "TARGET_64BIT"
18544   "{rep\;stosb|rep stosb}"
18545   [(set_attr "type" "str")
18546    (set_attr "prefix_rep" "1")
18547    (set_attr "memory" "store")
18548    (set_attr "mode" "QI")])
18550 (define_expand "cmpstrnsi"
18551   [(set (match_operand:SI 0 "register_operand" "")
18552         (compare:SI (match_operand:BLK 1 "general_operand" "")
18553                     (match_operand:BLK 2 "general_operand" "")))
18554    (use (match_operand 3 "general_operand" ""))
18555    (use (match_operand 4 "immediate_operand" ""))]
18556   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18558   rtx addr1, addr2, out, outlow, count, countreg, align;
18560   /* Can't use this if the user has appropriated esi or edi.  */
18561   if (global_regs[4] || global_regs[5])
18562     FAIL;
18564   out = operands[0];
18565   if (GET_CODE (out) != REG)
18566     out = gen_reg_rtx (SImode);
18568   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18569   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18570   if (addr1 != XEXP (operands[1], 0))
18571     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18572   if (addr2 != XEXP (operands[2], 0))
18573     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18575   count = operands[3];
18576   countreg = ix86_zero_extend_to_Pmode (count);
18578   /* %%% Iff we are testing strict equality, we can use known alignment
18579      to good advantage.  This may be possible with combine, particularly
18580      once cc0 is dead.  */
18581   align = operands[4];
18583   emit_insn (gen_cld ());
18584   if (GET_CODE (count) == CONST_INT)
18585     {
18586       if (INTVAL (count) == 0)
18587         {
18588           emit_move_insn (operands[0], const0_rtx);
18589           DONE;
18590         }
18591       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18592                                      operands[1], operands[2]));
18593     }
18594   else
18595     {
18596       if (TARGET_64BIT)
18597         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18598       else
18599         emit_insn (gen_cmpsi_1 (countreg, countreg));
18600       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18601                                   operands[1], operands[2]));
18602     }
18604   outlow = gen_lowpart (QImode, out);
18605   emit_insn (gen_cmpintqi (outlow));
18606   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18608   if (operands[0] != out)
18609     emit_move_insn (operands[0], out);
18611   DONE;
18614 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18616 (define_expand "cmpintqi"
18617   [(set (match_dup 1)
18618         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18619    (set (match_dup 2)
18620         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18621    (parallel [(set (match_operand:QI 0 "register_operand" "")
18622                    (minus:QI (match_dup 1)
18623                              (match_dup 2)))
18624               (clobber (reg:CC FLAGS_REG))])]
18625   ""
18626   "operands[1] = gen_reg_rtx (QImode);
18627    operands[2] = gen_reg_rtx (QImode);")
18629 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18630 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18632 (define_expand "cmpstrnqi_nz_1"
18633   [(parallel [(set (reg:CC FLAGS_REG)
18634                    (compare:CC (match_operand 4 "memory_operand" "")
18635                                (match_operand 5 "memory_operand" "")))
18636               (use (match_operand 2 "register_operand" ""))
18637               (use (match_operand:SI 3 "immediate_operand" ""))
18638               (use (reg:SI DIRFLAG_REG))
18639               (clobber (match_operand 0 "register_operand" ""))
18640               (clobber (match_operand 1 "register_operand" ""))
18641               (clobber (match_dup 2))])]
18642   ""
18643   "")
18645 (define_insn "*cmpstrnqi_nz_1"
18646   [(set (reg:CC FLAGS_REG)
18647         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18648                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18649    (use (match_operand:SI 6 "register_operand" "2"))
18650    (use (match_operand:SI 3 "immediate_operand" "i"))
18651    (use (reg:SI DIRFLAG_REG))
18652    (clobber (match_operand:SI 0 "register_operand" "=S"))
18653    (clobber (match_operand:SI 1 "register_operand" "=D"))
18654    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18655   "!TARGET_64BIT"
18656   "repz{\;| }cmpsb"
18657   [(set_attr "type" "str")
18658    (set_attr "mode" "QI")
18659    (set_attr "prefix_rep" "1")])
18661 (define_insn "*cmpstrnqi_nz_rex_1"
18662   [(set (reg:CC FLAGS_REG)
18663         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18664                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18665    (use (match_operand:DI 6 "register_operand" "2"))
18666    (use (match_operand:SI 3 "immediate_operand" "i"))
18667    (use (reg:SI DIRFLAG_REG))
18668    (clobber (match_operand:DI 0 "register_operand" "=S"))
18669    (clobber (match_operand:DI 1 "register_operand" "=D"))
18670    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18671   "TARGET_64BIT"
18672   "repz{\;| }cmpsb"
18673   [(set_attr "type" "str")
18674    (set_attr "mode" "QI")
18675    (set_attr "prefix_rep" "1")])
18677 ;; The same, but the count is not known to not be zero.
18679 (define_expand "cmpstrnqi_1"
18680   [(parallel [(set (reg:CC FLAGS_REG)
18681                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18682                                      (const_int 0))
18683                   (compare:CC (match_operand 4 "memory_operand" "")
18684                               (match_operand 5 "memory_operand" ""))
18685                   (const_int 0)))
18686               (use (match_operand:SI 3 "immediate_operand" ""))
18687               (use (reg:CC FLAGS_REG))
18688               (use (reg:SI DIRFLAG_REG))
18689               (clobber (match_operand 0 "register_operand" ""))
18690               (clobber (match_operand 1 "register_operand" ""))
18691               (clobber (match_dup 2))])]
18692   ""
18693   "")
18695 (define_insn "*cmpstrnqi_1"
18696   [(set (reg:CC FLAGS_REG)
18697         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18698                              (const_int 0))
18699           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18700                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18701           (const_int 0)))
18702    (use (match_operand:SI 3 "immediate_operand" "i"))
18703    (use (reg:CC FLAGS_REG))
18704    (use (reg:SI DIRFLAG_REG))
18705    (clobber (match_operand:SI 0 "register_operand" "=S"))
18706    (clobber (match_operand:SI 1 "register_operand" "=D"))
18707    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18708   "!TARGET_64BIT"
18709   "repz{\;| }cmpsb"
18710   [(set_attr "type" "str")
18711    (set_attr "mode" "QI")
18712    (set_attr "prefix_rep" "1")])
18714 (define_insn "*cmpstrnqi_rex_1"
18715   [(set (reg:CC FLAGS_REG)
18716         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18717                              (const_int 0))
18718           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18719                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18720           (const_int 0)))
18721    (use (match_operand:SI 3 "immediate_operand" "i"))
18722    (use (reg:CC FLAGS_REG))
18723    (use (reg:SI DIRFLAG_REG))
18724    (clobber (match_operand:DI 0 "register_operand" "=S"))
18725    (clobber (match_operand:DI 1 "register_operand" "=D"))
18726    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18727   "TARGET_64BIT"
18728   "repz{\;| }cmpsb"
18729   [(set_attr "type" "str")
18730    (set_attr "mode" "QI")
18731    (set_attr "prefix_rep" "1")])
18733 (define_expand "strlensi"
18734   [(set (match_operand:SI 0 "register_operand" "")
18735         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18736                     (match_operand:QI 2 "immediate_operand" "")
18737                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18738   ""
18740  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18741    DONE;
18742  else
18743    FAIL;
18746 (define_expand "strlendi"
18747   [(set (match_operand:DI 0 "register_operand" "")
18748         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18749                     (match_operand:QI 2 "immediate_operand" "")
18750                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18751   ""
18753  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18754    DONE;
18755  else
18756    FAIL;
18759 (define_expand "strlenqi_1"
18760   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18761               (use (reg:SI DIRFLAG_REG))
18762               (clobber (match_operand 1 "register_operand" ""))
18763               (clobber (reg:CC FLAGS_REG))])]
18764   ""
18765   "")
18767 (define_insn "*strlenqi_1"
18768   [(set (match_operand:SI 0 "register_operand" "=&c")
18769         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18770                     (match_operand:QI 2 "register_operand" "a")
18771                     (match_operand:SI 3 "immediate_operand" "i")
18772                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18773    (use (reg:SI DIRFLAG_REG))
18774    (clobber (match_operand:SI 1 "register_operand" "=D"))
18775    (clobber (reg:CC FLAGS_REG))]
18776   "!TARGET_64BIT"
18777   "repnz{\;| }scasb"
18778   [(set_attr "type" "str")
18779    (set_attr "mode" "QI")
18780    (set_attr "prefix_rep" "1")])
18782 (define_insn "*strlenqi_rex_1"
18783   [(set (match_operand:DI 0 "register_operand" "=&c")
18784         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18785                     (match_operand:QI 2 "register_operand" "a")
18786                     (match_operand:DI 3 "immediate_operand" "i")
18787                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18788    (use (reg:SI DIRFLAG_REG))
18789    (clobber (match_operand:DI 1 "register_operand" "=D"))
18790    (clobber (reg:CC FLAGS_REG))]
18791   "TARGET_64BIT"
18792   "repnz{\;| }scasb"
18793   [(set_attr "type" "str")
18794    (set_attr "mode" "QI")
18795    (set_attr "prefix_rep" "1")])
18797 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18798 ;; handled in combine, but it is not currently up to the task.
18799 ;; When used for their truth value, the cmpstrn* expanders generate
18800 ;; code like this:
18802 ;;   repz cmpsb
18803 ;;   seta       %al
18804 ;;   setb       %dl
18805 ;;   cmpb       %al, %dl
18806 ;;   jcc        label
18808 ;; The intermediate three instructions are unnecessary.
18810 ;; This one handles cmpstrn*_nz_1...
18811 (define_peephole2
18812   [(parallel[
18813      (set (reg:CC FLAGS_REG)
18814           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18815                       (mem:BLK (match_operand 5 "register_operand" ""))))
18816      (use (match_operand 6 "register_operand" ""))
18817      (use (match_operand:SI 3 "immediate_operand" ""))
18818      (use (reg:SI DIRFLAG_REG))
18819      (clobber (match_operand 0 "register_operand" ""))
18820      (clobber (match_operand 1 "register_operand" ""))
18821      (clobber (match_operand 2 "register_operand" ""))])
18822    (set (match_operand:QI 7 "register_operand" "")
18823         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824    (set (match_operand:QI 8 "register_operand" "")
18825         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18826    (set (reg FLAGS_REG)
18827         (compare (match_dup 7) (match_dup 8)))
18828   ]
18829   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18830   [(parallel[
18831      (set (reg:CC FLAGS_REG)
18832           (compare:CC (mem:BLK (match_dup 4))
18833                       (mem:BLK (match_dup 5))))
18834      (use (match_dup 6))
18835      (use (match_dup 3))
18836      (use (reg:SI DIRFLAG_REG))
18837      (clobber (match_dup 0))
18838      (clobber (match_dup 1))
18839      (clobber (match_dup 2))])]
18840   "")
18842 ;; ...and this one handles cmpstrn*_1.
18843 (define_peephole2
18844   [(parallel[
18845      (set (reg:CC FLAGS_REG)
18846           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18847                                (const_int 0))
18848             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18849                         (mem:BLK (match_operand 5 "register_operand" "")))
18850             (const_int 0)))
18851      (use (match_operand:SI 3 "immediate_operand" ""))
18852      (use (reg:CC FLAGS_REG))
18853      (use (reg:SI DIRFLAG_REG))
18854      (clobber (match_operand 0 "register_operand" ""))
18855      (clobber (match_operand 1 "register_operand" ""))
18856      (clobber (match_operand 2 "register_operand" ""))])
18857    (set (match_operand:QI 7 "register_operand" "")
18858         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18859    (set (match_operand:QI 8 "register_operand" "")
18860         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18861    (set (reg FLAGS_REG)
18862         (compare (match_dup 7) (match_dup 8)))
18863   ]
18864   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18865   [(parallel[
18866      (set (reg:CC FLAGS_REG)
18867           (if_then_else:CC (ne (match_dup 6)
18868                                (const_int 0))
18869             (compare:CC (mem:BLK (match_dup 4))
18870                         (mem:BLK (match_dup 5)))
18871             (const_int 0)))
18872      (use (match_dup 3))
18873      (use (reg:CC FLAGS_REG))
18874      (use (reg:SI DIRFLAG_REG))
18875      (clobber (match_dup 0))
18876      (clobber (match_dup 1))
18877      (clobber (match_dup 2))])]
18878   "")
18882 ;; Conditional move instructions.
18884 (define_expand "movdicc"
18885   [(set (match_operand:DI 0 "register_operand" "")
18886         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18887                          (match_operand:DI 2 "general_operand" "")
18888                          (match_operand:DI 3 "general_operand" "")))]
18889   "TARGET_64BIT"
18890   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18892 (define_insn "x86_movdicc_0_m1_rex64"
18893   [(set (match_operand:DI 0 "register_operand" "=r")
18894         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18895           (const_int -1)
18896           (const_int 0)))
18897    (clobber (reg:CC FLAGS_REG))]
18898   "TARGET_64BIT"
18899   "sbb{q}\t%0, %0"
18900   ; Since we don't have the proper number of operands for an alu insn,
18901   ; fill in all the blanks.
18902   [(set_attr "type" "alu")
18903    (set_attr "pent_pair" "pu")
18904    (set_attr "memory" "none")
18905    (set_attr "imm_disp" "false")
18906    (set_attr "mode" "DI")
18907    (set_attr "length_immediate" "0")])
18909 (define_insn "*movdicc_c_rex64"
18910   [(set (match_operand:DI 0 "register_operand" "=r,r")
18911         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18912                                 [(reg FLAGS_REG) (const_int 0)])
18913                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18914                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18915   "TARGET_64BIT && TARGET_CMOVE
18916    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18917   "@
18918    cmov%O2%C1\t{%2, %0|%0, %2}
18919    cmov%O2%c1\t{%3, %0|%0, %3}"
18920   [(set_attr "type" "icmov")
18921    (set_attr "mode" "DI")])
18923 (define_expand "movsicc"
18924   [(set (match_operand:SI 0 "register_operand" "")
18925         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18926                          (match_operand:SI 2 "general_operand" "")
18927                          (match_operand:SI 3 "general_operand" "")))]
18928   ""
18929   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18931 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18932 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18933 ;; So just document what we're doing explicitly.
18935 (define_insn "x86_movsicc_0_m1"
18936   [(set (match_operand:SI 0 "register_operand" "=r")
18937         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18938           (const_int -1)
18939           (const_int 0)))
18940    (clobber (reg:CC FLAGS_REG))]
18941   ""
18942   "sbb{l}\t%0, %0"
18943   ; Since we don't have the proper number of operands for an alu insn,
18944   ; fill in all the blanks.
18945   [(set_attr "type" "alu")
18946    (set_attr "pent_pair" "pu")
18947    (set_attr "memory" "none")
18948    (set_attr "imm_disp" "false")
18949    (set_attr "mode" "SI")
18950    (set_attr "length_immediate" "0")])
18952 (define_insn "*movsicc_noc"
18953   [(set (match_operand:SI 0 "register_operand" "=r,r")
18954         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18955                                 [(reg FLAGS_REG) (const_int 0)])
18956                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18957                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18958   "TARGET_CMOVE
18959    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18960   "@
18961    cmov%O2%C1\t{%2, %0|%0, %2}
18962    cmov%O2%c1\t{%3, %0|%0, %3}"
18963   [(set_attr "type" "icmov")
18964    (set_attr "mode" "SI")])
18966 (define_expand "movhicc"
18967   [(set (match_operand:HI 0 "register_operand" "")
18968         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18969                          (match_operand:HI 2 "general_operand" "")
18970                          (match_operand:HI 3 "general_operand" "")))]
18971   "TARGET_HIMODE_MATH"
18972   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18974 (define_insn "*movhicc_noc"
18975   [(set (match_operand:HI 0 "register_operand" "=r,r")
18976         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18977                                 [(reg FLAGS_REG) (const_int 0)])
18978                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18979                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18980   "TARGET_CMOVE
18981    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18982   "@
18983    cmov%O2%C1\t{%2, %0|%0, %2}
18984    cmov%O2%c1\t{%3, %0|%0, %3}"
18985   [(set_attr "type" "icmov")
18986    (set_attr "mode" "HI")])
18988 (define_expand "movqicc"
18989   [(set (match_operand:QI 0 "register_operand" "")
18990         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18991                          (match_operand:QI 2 "general_operand" "")
18992                          (match_operand:QI 3 "general_operand" "")))]
18993   "TARGET_QIMODE_MATH"
18994   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18996 (define_insn_and_split "*movqicc_noc"
18997   [(set (match_operand:QI 0 "register_operand" "=r,r")
18998         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18999                                 [(match_operand 4 "flags_reg_operand" "")
19000                                  (const_int 0)])
19001                       (match_operand:QI 2 "register_operand" "r,0")
19002                       (match_operand:QI 3 "register_operand" "0,r")))]
19003   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19004   "#"
19005   "&& reload_completed"
19006   [(set (match_dup 0)
19007         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19008                       (match_dup 2)
19009                       (match_dup 3)))]
19010   "operands[0] = gen_lowpart (SImode, operands[0]);
19011    operands[2] = gen_lowpart (SImode, operands[2]);
19012    operands[3] = gen_lowpart (SImode, operands[3]);"
19013   [(set_attr "type" "icmov")
19014    (set_attr "mode" "SI")])
19016 (define_expand "movsfcc"
19017   [(set (match_operand:SF 0 "register_operand" "")
19018         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19019                          (match_operand:SF 2 "register_operand" "")
19020                          (match_operand:SF 3 "register_operand" "")))]
19021   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19022   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19024 (define_insn "*movsfcc_1_387"
19025   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19026         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19027                                 [(reg FLAGS_REG) (const_int 0)])
19028                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19029                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19030   "TARGET_80387 && TARGET_CMOVE
19031    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19032   "@
19033    fcmov%F1\t{%2, %0|%0, %2}
19034    fcmov%f1\t{%3, %0|%0, %3}
19035    cmov%O2%C1\t{%2, %0|%0, %2}
19036    cmov%O2%c1\t{%3, %0|%0, %3}"
19037   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19038    (set_attr "mode" "SF,SF,SI,SI")])
19040 (define_expand "movdfcc"
19041   [(set (match_operand:DF 0 "register_operand" "")
19042         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19043                          (match_operand:DF 2 "register_operand" "")
19044                          (match_operand:DF 3 "register_operand" "")))]
19045   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19046   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19048 (define_insn "*movdfcc_1"
19049   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19050         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19051                                 [(reg FLAGS_REG) (const_int 0)])
19052                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19053                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19054   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19055    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19056   "@
19057    fcmov%F1\t{%2, %0|%0, %2}
19058    fcmov%f1\t{%3, %0|%0, %3}
19059    #
19060    #"
19061   [(set_attr "type" "fcmov,fcmov,multi,multi")
19062    (set_attr "mode" "DF")])
19064 (define_insn "*movdfcc_1_rex64"
19065   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19066         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19067                                 [(reg FLAGS_REG) (const_int 0)])
19068                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19069                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19070   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19071    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19072   "@
19073    fcmov%F1\t{%2, %0|%0, %2}
19074    fcmov%f1\t{%3, %0|%0, %3}
19075    cmov%O2%C1\t{%2, %0|%0, %2}
19076    cmov%O2%c1\t{%3, %0|%0, %3}"
19077   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19078    (set_attr "mode" "DF")])
19080 (define_split
19081   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19082         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19083                                 [(match_operand 4 "flags_reg_operand" "")
19084                                  (const_int 0)])
19085                       (match_operand:DF 2 "nonimmediate_operand" "")
19086                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19087   "!TARGET_64BIT && reload_completed"
19088   [(set (match_dup 2)
19089         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19090                       (match_dup 5)
19091                       (match_dup 7)))
19092    (set (match_dup 3)
19093         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19094                       (match_dup 6)
19095                       (match_dup 8)))]
19096   "split_di (operands+2, 1, operands+5, operands+6);
19097    split_di (operands+3, 1, operands+7, operands+8);
19098    split_di (operands, 1, operands+2, operands+3);")
19100 (define_expand "movxfcc"
19101   [(set (match_operand:XF 0 "register_operand" "")
19102         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19103                          (match_operand:XF 2 "register_operand" "")
19104                          (match_operand:XF 3 "register_operand" "")))]
19105   "TARGET_80387 && TARGET_CMOVE"
19106   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19108 (define_insn "*movxfcc_1"
19109   [(set (match_operand:XF 0 "register_operand" "=f,f")
19110         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19111                                 [(reg FLAGS_REG) (const_int 0)])
19112                       (match_operand:XF 2 "register_operand" "f,0")
19113                       (match_operand:XF 3 "register_operand" "0,f")))]
19114   "TARGET_80387 && TARGET_CMOVE"
19115   "@
19116    fcmov%F1\t{%2, %0|%0, %2}
19117    fcmov%f1\t{%3, %0|%0, %3}"
19118   [(set_attr "type" "fcmov")
19119    (set_attr "mode" "XF")])
19121 ;; These versions of the min/max patterns are intentionally ignorant of
19122 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19123 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19124 ;; are undefined in this condition, we're certain this is correct.
19126 (define_insn "sminsf3"
19127   [(set (match_operand:SF 0 "register_operand" "=x")
19128         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19129                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19130   "TARGET_SSE_MATH"
19131   "minss\t{%2, %0|%0, %2}"
19132   [(set_attr "type" "sseadd")
19133    (set_attr "mode" "SF")])
19135 (define_insn "smaxsf3"
19136   [(set (match_operand:SF 0 "register_operand" "=x")
19137         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19138                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19139   "TARGET_SSE_MATH"
19140   "maxss\t{%2, %0|%0, %2}"
19141   [(set_attr "type" "sseadd")
19142    (set_attr "mode" "SF")])
19144 (define_insn "smindf3"
19145   [(set (match_operand:DF 0 "register_operand" "=x")
19146         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19147                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19148   "TARGET_SSE2 && TARGET_SSE_MATH"
19149   "minsd\t{%2, %0|%0, %2}"
19150   [(set_attr "type" "sseadd")
19151    (set_attr "mode" "DF")])
19153 (define_insn "smaxdf3"
19154   [(set (match_operand:DF 0 "register_operand" "=x")
19155         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19156                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19157   "TARGET_SSE2 && TARGET_SSE_MATH"
19158   "maxsd\t{%2, %0|%0, %2}"
19159   [(set_attr "type" "sseadd")
19160    (set_attr "mode" "DF")])
19162 ;; These versions of the min/max patterns implement exactly the operations
19163 ;;   min = (op1 < op2 ? op1 : op2)
19164 ;;   max = (!(op1 < op2) ? op1 : op2)
19165 ;; Their operands are not commutative, and thus they may be used in the
19166 ;; presence of -0.0 and NaN.
19168 (define_insn "*ieee_sminsf3"
19169   [(set (match_operand:SF 0 "register_operand" "=x")
19170         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19171                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19172                    UNSPEC_IEEE_MIN))]
19173   "TARGET_SSE_MATH"
19174   "minss\t{%2, %0|%0, %2}"
19175   [(set_attr "type" "sseadd")
19176    (set_attr "mode" "SF")])
19178 (define_insn "*ieee_smaxsf3"
19179   [(set (match_operand:SF 0 "register_operand" "=x")
19180         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19181                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19182                    UNSPEC_IEEE_MAX))]
19183   "TARGET_SSE_MATH"
19184   "maxss\t{%2, %0|%0, %2}"
19185   [(set_attr "type" "sseadd")
19186    (set_attr "mode" "SF")])
19188 (define_insn "*ieee_smindf3"
19189   [(set (match_operand:DF 0 "register_operand" "=x")
19190         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19191                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19192                    UNSPEC_IEEE_MIN))]
19193   "TARGET_SSE2 && TARGET_SSE_MATH"
19194   "minsd\t{%2, %0|%0, %2}"
19195   [(set_attr "type" "sseadd")
19196    (set_attr "mode" "DF")])
19198 (define_insn "*ieee_smaxdf3"
19199   [(set (match_operand:DF 0 "register_operand" "=x")
19200         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19201                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19202                    UNSPEC_IEEE_MAX))]
19203   "TARGET_SSE2 && TARGET_SSE_MATH"
19204   "maxsd\t{%2, %0|%0, %2}"
19205   [(set_attr "type" "sseadd")
19206    (set_attr "mode" "DF")])
19208 ;; Make two stack loads independent:
19209 ;;   fld aa              fld aa
19210 ;;   fld %st(0)     ->   fld bb
19211 ;;   fmul bb             fmul %st(1), %st
19213 ;; Actually we only match the last two instructions for simplicity.
19214 (define_peephole2
19215   [(set (match_operand 0 "fp_register_operand" "")
19216         (match_operand 1 "fp_register_operand" ""))
19217    (set (match_dup 0)
19218         (match_operator 2 "binary_fp_operator"
19219            [(match_dup 0)
19220             (match_operand 3 "memory_operand" "")]))]
19221   "REGNO (operands[0]) != REGNO (operands[1])"
19222   [(set (match_dup 0) (match_dup 3))
19223    (set (match_dup 0) (match_dup 4))]
19225   ;; The % modifier is not operational anymore in peephole2's, so we have to
19226   ;; swap the operands manually in the case of addition and multiplication.
19227   "if (COMMUTATIVE_ARITH_P (operands[2]))
19228      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19229                                  operands[0], operands[1]);
19230    else
19231      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19232                                  operands[1], operands[0]);")
19234 ;; Conditional addition patterns
19235 (define_expand "addqicc"
19236   [(match_operand:QI 0 "register_operand" "")
19237    (match_operand 1 "comparison_operator" "")
19238    (match_operand:QI 2 "register_operand" "")
19239    (match_operand:QI 3 "const_int_operand" "")]
19240   ""
19241   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19243 (define_expand "addhicc"
19244   [(match_operand:HI 0 "register_operand" "")
19245    (match_operand 1 "comparison_operator" "")
19246    (match_operand:HI 2 "register_operand" "")
19247    (match_operand:HI 3 "const_int_operand" "")]
19248   ""
19249   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19251 (define_expand "addsicc"
19252   [(match_operand:SI 0 "register_operand" "")
19253    (match_operand 1 "comparison_operator" "")
19254    (match_operand:SI 2 "register_operand" "")
19255    (match_operand:SI 3 "const_int_operand" "")]
19256   ""
19257   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19259 (define_expand "adddicc"
19260   [(match_operand:DI 0 "register_operand" "")
19261    (match_operand 1 "comparison_operator" "")
19262    (match_operand:DI 2 "register_operand" "")
19263    (match_operand:DI 3 "const_int_operand" "")]
19264   "TARGET_64BIT"
19265   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19268 ;; Misc patterns (?)
19270 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19271 ;; Otherwise there will be nothing to keep
19272 ;; 
19273 ;; [(set (reg ebp) (reg esp))]
19274 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19275 ;;  (clobber (eflags)]
19276 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19278 ;; in proper program order.
19279 (define_insn "pro_epilogue_adjust_stack_1"
19280   [(set (match_operand:SI 0 "register_operand" "=r,r")
19281         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19282                  (match_operand:SI 2 "immediate_operand" "i,i")))
19283    (clobber (reg:CC FLAGS_REG))
19284    (clobber (mem:BLK (scratch)))]
19285   "!TARGET_64BIT"
19287   switch (get_attr_type (insn))
19288     {
19289     case TYPE_IMOV:
19290       return "mov{l}\t{%1, %0|%0, %1}";
19292     case TYPE_ALU:
19293       if (GET_CODE (operands[2]) == CONST_INT
19294           && (INTVAL (operands[2]) == 128
19295               || (INTVAL (operands[2]) < 0
19296                   && INTVAL (operands[2]) != -128)))
19297         {
19298           operands[2] = GEN_INT (-INTVAL (operands[2]));
19299           return "sub{l}\t{%2, %0|%0, %2}";
19300         }
19301       return "add{l}\t{%2, %0|%0, %2}";
19303     case TYPE_LEA:
19304       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19305       return "lea{l}\t{%a2, %0|%0, %a2}";
19307     default:
19308       gcc_unreachable ();
19309     }
19311   [(set (attr "type")
19312         (cond [(eq_attr "alternative" "0")
19313                  (const_string "alu")
19314                (match_operand:SI 2 "const0_operand" "")
19315                  (const_string "imov")
19316               ]
19317               (const_string "lea")))
19318    (set_attr "mode" "SI")])
19320 (define_insn "pro_epilogue_adjust_stack_rex64"
19321   [(set (match_operand:DI 0 "register_operand" "=r,r")
19322         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19323                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19324    (clobber (reg:CC FLAGS_REG))
19325    (clobber (mem:BLK (scratch)))]
19326   "TARGET_64BIT"
19328   switch (get_attr_type (insn))
19329     {
19330     case TYPE_IMOV:
19331       return "mov{q}\t{%1, %0|%0, %1}";
19333     case TYPE_ALU:
19334       if (GET_CODE (operands[2]) == CONST_INT
19335           /* Avoid overflows.  */
19336           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19337           && (INTVAL (operands[2]) == 128
19338               || (INTVAL (operands[2]) < 0
19339                   && INTVAL (operands[2]) != -128)))
19340         {
19341           operands[2] = GEN_INT (-INTVAL (operands[2]));
19342           return "sub{q}\t{%2, %0|%0, %2}";
19343         }
19344       return "add{q}\t{%2, %0|%0, %2}";
19346     case TYPE_LEA:
19347       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19348       return "lea{q}\t{%a2, %0|%0, %a2}";
19350     default:
19351       gcc_unreachable ();
19352     }
19354   [(set (attr "type")
19355         (cond [(eq_attr "alternative" "0")
19356                  (const_string "alu")
19357                (match_operand:DI 2 "const0_operand" "")
19358                  (const_string "imov")
19359               ]
19360               (const_string "lea")))
19361    (set_attr "mode" "DI")])
19363 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19364   [(set (match_operand:DI 0 "register_operand" "=r,r")
19365         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19366                  (match_operand:DI 3 "immediate_operand" "i,i")))
19367    (use (match_operand:DI 2 "register_operand" "r,r"))
19368    (clobber (reg:CC FLAGS_REG))
19369    (clobber (mem:BLK (scratch)))]
19370   "TARGET_64BIT"
19372   switch (get_attr_type (insn))
19373     {
19374     case TYPE_ALU:
19375       return "add{q}\t{%2, %0|%0, %2}";
19377     case TYPE_LEA:
19378       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19379       return "lea{q}\t{%a2, %0|%0, %a2}";
19381     default:
19382       gcc_unreachable ();
19383     }
19385   [(set_attr "type" "alu,lea")
19386    (set_attr "mode" "DI")])
19388 (define_expand "allocate_stack_worker"
19389   [(match_operand:SI 0 "register_operand" "")]
19390   "TARGET_STACK_PROBE"
19392   if (reload_completed)
19393     {
19394       if (TARGET_64BIT)
19395         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19396       else
19397         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19398     }
19399   else
19400     {
19401       if (TARGET_64BIT)
19402         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19403       else
19404         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19405     }
19406   DONE;
19409 (define_insn "allocate_stack_worker_1"
19410   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19411     UNSPECV_STACK_PROBE)
19412    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19413    (clobber (match_scratch:SI 1 "=0"))
19414    (clobber (reg:CC FLAGS_REG))]
19415   "!TARGET_64BIT && TARGET_STACK_PROBE"
19416   "call\t__alloca"
19417   [(set_attr "type" "multi")
19418    (set_attr "length" "5")])
19420 (define_expand "allocate_stack_worker_postreload"
19421   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19422                                     UNSPECV_STACK_PROBE)
19423               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19424               (clobber (match_dup 0))
19425               (clobber (reg:CC FLAGS_REG))])]
19426   ""
19427   "")
19429 (define_insn "allocate_stack_worker_rex64"
19430   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19431     UNSPECV_STACK_PROBE)
19432    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19433    (clobber (match_scratch:DI 1 "=0"))
19434    (clobber (reg:CC FLAGS_REG))]
19435   "TARGET_64BIT && TARGET_STACK_PROBE"
19436   "call\t__alloca"
19437   [(set_attr "type" "multi")
19438    (set_attr "length" "5")])
19440 (define_expand "allocate_stack_worker_rex64_postreload"
19441   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19442                                     UNSPECV_STACK_PROBE)
19443               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19444               (clobber (match_dup 0))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   ""
19447   "")
19449 (define_expand "allocate_stack"
19450   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19451                    (minus:SI (reg:SI SP_REG)
19452                              (match_operand:SI 1 "general_operand" "")))
19453               (clobber (reg:CC FLAGS_REG))])
19454    (parallel [(set (reg:SI SP_REG)
19455                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19456               (clobber (reg:CC FLAGS_REG))])]
19457   "TARGET_STACK_PROBE"
19459 #ifdef CHECK_STACK_LIMIT
19460   if (GET_CODE (operands[1]) == CONST_INT
19461       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19462     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19463                            operands[1]));
19464   else 
19465 #endif
19466     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19467                                                             operands[1])));
19469   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19470   DONE;
19473 (define_expand "builtin_setjmp_receiver"
19474   [(label_ref (match_operand 0 "" ""))]
19475   "!TARGET_64BIT && flag_pic"
19477   if (TARGET_MACHO)
19478     {
19479       rtx xops[3];
19480       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19481       rtx label_rtx = gen_label_rtx ();
19482       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19483       xops[0] = xops[1] = picreg;
19484       xops[2] = gen_rtx_CONST (SImode,
19485                   gen_rtx_MINUS (SImode,
19486                     gen_rtx_LABEL_REF (SImode, label_rtx),
19487                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19488       ix86_expand_binary_operator (MINUS, SImode, xops);
19489     }
19490   else
19491     emit_insn (gen_set_got (pic_offset_table_rtx));
19492   DONE;
19495 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19497 (define_split
19498   [(set (match_operand 0 "register_operand" "")
19499         (match_operator 3 "promotable_binary_operator"
19500            [(match_operand 1 "register_operand" "")
19501             (match_operand 2 "aligned_operand" "")]))
19502    (clobber (reg:CC FLAGS_REG))]
19503   "! TARGET_PARTIAL_REG_STALL && reload_completed
19504    && ((GET_MODE (operands[0]) == HImode 
19505         && ((!optimize_size && !TARGET_FAST_PREFIX)
19506             /* ??? next two lines just !satisfies_constraint_K (...) */
19507             || GET_CODE (operands[2]) != CONST_INT
19508             || satisfies_constraint_K (operands[2])))
19509        || (GET_MODE (operands[0]) == QImode 
19510            && (TARGET_PROMOTE_QImode || optimize_size)))"
19511   [(parallel [(set (match_dup 0)
19512                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19513               (clobber (reg:CC FLAGS_REG))])]
19514   "operands[0] = gen_lowpart (SImode, operands[0]);
19515    operands[1] = gen_lowpart (SImode, operands[1]);
19516    if (GET_CODE (operands[3]) != ASHIFT)
19517      operands[2] = gen_lowpart (SImode, operands[2]);
19518    PUT_MODE (operands[3], SImode);")
19520 ; Promote the QImode tests, as i386 has encoding of the AND
19521 ; instruction with 32-bit sign-extended immediate and thus the
19522 ; instruction size is unchanged, except in the %eax case for
19523 ; which it is increased by one byte, hence the ! optimize_size.
19524 (define_split
19525   [(set (match_operand 0 "flags_reg_operand" "")
19526         (match_operator 2 "compare_operator"
19527           [(and (match_operand 3 "aligned_operand" "")
19528                 (match_operand 4 "const_int_operand" ""))
19529            (const_int 0)]))
19530    (set (match_operand 1 "register_operand" "")
19531         (and (match_dup 3) (match_dup 4)))]
19532   "! TARGET_PARTIAL_REG_STALL && reload_completed
19533    /* Ensure that the operand will remain sign-extended immediate.  */
19534    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19535    && ! optimize_size
19536    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19537        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19538   [(parallel [(set (match_dup 0)
19539                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19540                                     (const_int 0)]))
19541               (set (match_dup 1)
19542                    (and:SI (match_dup 3) (match_dup 4)))])]
19544   operands[4]
19545     = gen_int_mode (INTVAL (operands[4])
19546                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19547   operands[1] = gen_lowpart (SImode, operands[1]);
19548   operands[3] = gen_lowpart (SImode, operands[3]);
19551 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19552 ; the TEST instruction with 32-bit sign-extended immediate and thus
19553 ; the instruction size would at least double, which is not what we
19554 ; want even with ! optimize_size.
19555 (define_split
19556   [(set (match_operand 0 "flags_reg_operand" "")
19557         (match_operator 1 "compare_operator"
19558           [(and (match_operand:HI 2 "aligned_operand" "")
19559                 (match_operand:HI 3 "const_int_operand" ""))
19560            (const_int 0)]))]
19561   "! TARGET_PARTIAL_REG_STALL && reload_completed
19562    /* Ensure that the operand will remain sign-extended immediate.  */
19563    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19564    && ! TARGET_FAST_PREFIX
19565    && ! optimize_size"
19566   [(set (match_dup 0)
19567         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19568                          (const_int 0)]))]
19570   operands[3]
19571     = gen_int_mode (INTVAL (operands[3])
19572                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19573   operands[2] = gen_lowpart (SImode, operands[2]);
19576 (define_split
19577   [(set (match_operand 0 "register_operand" "")
19578         (neg (match_operand 1 "register_operand" "")))
19579    (clobber (reg:CC FLAGS_REG))]
19580   "! TARGET_PARTIAL_REG_STALL && reload_completed
19581    && (GET_MODE (operands[0]) == HImode
19582        || (GET_MODE (operands[0]) == QImode 
19583            && (TARGET_PROMOTE_QImode || optimize_size)))"
19584   [(parallel [(set (match_dup 0)
19585                    (neg:SI (match_dup 1)))
19586               (clobber (reg:CC FLAGS_REG))])]
19587   "operands[0] = gen_lowpart (SImode, operands[0]);
19588    operands[1] = gen_lowpart (SImode, operands[1]);")
19590 (define_split
19591   [(set (match_operand 0 "register_operand" "")
19592         (not (match_operand 1 "register_operand" "")))]
19593   "! TARGET_PARTIAL_REG_STALL && reload_completed
19594    && (GET_MODE (operands[0]) == HImode
19595        || (GET_MODE (operands[0]) == QImode 
19596            && (TARGET_PROMOTE_QImode || optimize_size)))"
19597   [(set (match_dup 0)
19598         (not:SI (match_dup 1)))]
19599   "operands[0] = gen_lowpart (SImode, operands[0]);
19600    operands[1] = gen_lowpart (SImode, operands[1]);")
19602 (define_split 
19603   [(set (match_operand 0 "register_operand" "")
19604         (if_then_else (match_operator 1 "comparison_operator" 
19605                                 [(reg FLAGS_REG) (const_int 0)])
19606                       (match_operand 2 "register_operand" "")
19607                       (match_operand 3 "register_operand" "")))]
19608   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19609    && (GET_MODE (operands[0]) == HImode
19610        || (GET_MODE (operands[0]) == QImode 
19611            && (TARGET_PROMOTE_QImode || optimize_size)))"
19612   [(set (match_dup 0)
19613         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19614   "operands[0] = gen_lowpart (SImode, operands[0]);
19615    operands[2] = gen_lowpart (SImode, operands[2]);
19616    operands[3] = gen_lowpart (SImode, operands[3]);")
19617                         
19619 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19620 ;; transform a complex memory operation into two memory to register operations.
19622 ;; Don't push memory operands
19623 (define_peephole2
19624   [(set (match_operand:SI 0 "push_operand" "")
19625         (match_operand:SI 1 "memory_operand" ""))
19626    (match_scratch:SI 2 "r")]
19627   "!optimize_size && !TARGET_PUSH_MEMORY
19628    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19629   [(set (match_dup 2) (match_dup 1))
19630    (set (match_dup 0) (match_dup 2))]
19631   "")
19633 (define_peephole2
19634   [(set (match_operand:DI 0 "push_operand" "")
19635         (match_operand:DI 1 "memory_operand" ""))
19636    (match_scratch:DI 2 "r")]
19637   "!optimize_size && !TARGET_PUSH_MEMORY
19638    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19639   [(set (match_dup 2) (match_dup 1))
19640    (set (match_dup 0) (match_dup 2))]
19641   "")
19643 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19644 ;; SImode pushes.
19645 (define_peephole2
19646   [(set (match_operand:SF 0 "push_operand" "")
19647         (match_operand:SF 1 "memory_operand" ""))
19648    (match_scratch:SF 2 "r")]
19649   "!optimize_size && !TARGET_PUSH_MEMORY
19650    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19651   [(set (match_dup 2) (match_dup 1))
19652    (set (match_dup 0) (match_dup 2))]
19653   "")
19655 (define_peephole2
19656   [(set (match_operand:HI 0 "push_operand" "")
19657         (match_operand:HI 1 "memory_operand" ""))
19658    (match_scratch:HI 2 "r")]
19659   "!optimize_size && !TARGET_PUSH_MEMORY
19660    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19661   [(set (match_dup 2) (match_dup 1))
19662    (set (match_dup 0) (match_dup 2))]
19663   "")
19665 (define_peephole2
19666   [(set (match_operand:QI 0 "push_operand" "")
19667         (match_operand:QI 1 "memory_operand" ""))
19668    (match_scratch:QI 2 "q")]
19669   "!optimize_size && !TARGET_PUSH_MEMORY
19670    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19671   [(set (match_dup 2) (match_dup 1))
19672    (set (match_dup 0) (match_dup 2))]
19673   "")
19675 ;; Don't move an immediate directly to memory when the instruction
19676 ;; gets too big.
19677 (define_peephole2
19678   [(match_scratch:SI 1 "r")
19679    (set (match_operand:SI 0 "memory_operand" "")
19680         (const_int 0))]
19681   "! optimize_size
19682    && ! TARGET_USE_MOV0
19683    && TARGET_SPLIT_LONG_MOVES
19684    && get_attr_length (insn) >= ix86_cost->large_insn
19685    && peep2_regno_dead_p (0, FLAGS_REG)"
19686   [(parallel [(set (match_dup 1) (const_int 0))
19687               (clobber (reg:CC FLAGS_REG))])
19688    (set (match_dup 0) (match_dup 1))]
19689   "")
19691 (define_peephole2
19692   [(match_scratch:HI 1 "r")
19693    (set (match_operand:HI 0 "memory_operand" "")
19694         (const_int 0))]
19695   "! optimize_size
19696    && ! TARGET_USE_MOV0
19697    && TARGET_SPLIT_LONG_MOVES
19698    && get_attr_length (insn) >= ix86_cost->large_insn
19699    && peep2_regno_dead_p (0, FLAGS_REG)"
19700   [(parallel [(set (match_dup 2) (const_int 0))
19701               (clobber (reg:CC FLAGS_REG))])
19702    (set (match_dup 0) (match_dup 1))]
19703   "operands[2] = gen_lowpart (SImode, operands[1]);")
19705 (define_peephole2
19706   [(match_scratch:QI 1 "q")
19707    (set (match_operand:QI 0 "memory_operand" "")
19708         (const_int 0))]
19709   "! optimize_size
19710    && ! TARGET_USE_MOV0
19711    && TARGET_SPLIT_LONG_MOVES
19712    && get_attr_length (insn) >= ix86_cost->large_insn
19713    && peep2_regno_dead_p (0, FLAGS_REG)"
19714   [(parallel [(set (match_dup 2) (const_int 0))
19715               (clobber (reg:CC FLAGS_REG))])
19716    (set (match_dup 0) (match_dup 1))]
19717   "operands[2] = gen_lowpart (SImode, operands[1]);")
19719 (define_peephole2
19720   [(match_scratch:SI 2 "r")
19721    (set (match_operand:SI 0 "memory_operand" "")
19722         (match_operand:SI 1 "immediate_operand" ""))]
19723   "! optimize_size
19724    && get_attr_length (insn) >= ix86_cost->large_insn
19725    && TARGET_SPLIT_LONG_MOVES"
19726   [(set (match_dup 2) (match_dup 1))
19727    (set (match_dup 0) (match_dup 2))]
19728   "")
19730 (define_peephole2
19731   [(match_scratch:HI 2 "r")
19732    (set (match_operand:HI 0 "memory_operand" "")
19733         (match_operand:HI 1 "immediate_operand" ""))]
19734   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19735   && TARGET_SPLIT_LONG_MOVES"
19736   [(set (match_dup 2) (match_dup 1))
19737    (set (match_dup 0) (match_dup 2))]
19738   "")
19740 (define_peephole2
19741   [(match_scratch:QI 2 "q")
19742    (set (match_operand:QI 0 "memory_operand" "")
19743         (match_operand:QI 1 "immediate_operand" ""))]
19744   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19745   && TARGET_SPLIT_LONG_MOVES"
19746   [(set (match_dup 2) (match_dup 1))
19747    (set (match_dup 0) (match_dup 2))]
19748   "")
19750 ;; Don't compare memory with zero, load and use a test instead.
19751 (define_peephole2
19752   [(set (match_operand 0 "flags_reg_operand" "")
19753         (match_operator 1 "compare_operator"
19754           [(match_operand:SI 2 "memory_operand" "")
19755            (const_int 0)]))
19756    (match_scratch:SI 3 "r")]
19757   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19758   [(set (match_dup 3) (match_dup 2))
19759    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19760   "")
19762 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19763 ;; Don't split NOTs with a displacement operand, because resulting XOR
19764 ;; will not be pairable anyway.
19766 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19767 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19768 ;; so this split helps here as well.
19770 ;; Note: Can't do this as a regular split because we can't get proper
19771 ;; lifetime information then.
19773 (define_peephole2
19774   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19775         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19776   "!optimize_size
19777    && peep2_regno_dead_p (0, FLAGS_REG)
19778    && ((TARGET_PENTIUM 
19779         && (GET_CODE (operands[0]) != MEM
19780             || !memory_displacement_operand (operands[0], SImode)))
19781        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19782   [(parallel [(set (match_dup 0)
19783                    (xor:SI (match_dup 1) (const_int -1)))
19784               (clobber (reg:CC FLAGS_REG))])]
19785   "")
19787 (define_peephole2
19788   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19789         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19790   "!optimize_size
19791    && peep2_regno_dead_p (0, FLAGS_REG)
19792    && ((TARGET_PENTIUM 
19793         && (GET_CODE (operands[0]) != MEM
19794             || !memory_displacement_operand (operands[0], HImode)))
19795        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19796   [(parallel [(set (match_dup 0)
19797                    (xor:HI (match_dup 1) (const_int -1)))
19798               (clobber (reg:CC FLAGS_REG))])]
19799   "")
19801 (define_peephole2
19802   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19803         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19804   "!optimize_size
19805    && peep2_regno_dead_p (0, FLAGS_REG)
19806    && ((TARGET_PENTIUM 
19807         && (GET_CODE (operands[0]) != MEM
19808             || !memory_displacement_operand (operands[0], QImode)))
19809        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19810   [(parallel [(set (match_dup 0)
19811                    (xor:QI (match_dup 1) (const_int -1)))
19812               (clobber (reg:CC FLAGS_REG))])]
19813   "")
19815 ;; Non pairable "test imm, reg" instructions can be translated to
19816 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19817 ;; byte opcode instead of two, have a short form for byte operands),
19818 ;; so do it for other CPUs as well.  Given that the value was dead,
19819 ;; this should not create any new dependencies.  Pass on the sub-word
19820 ;; versions if we're concerned about partial register stalls.
19822 (define_peephole2
19823   [(set (match_operand 0 "flags_reg_operand" "")
19824         (match_operator 1 "compare_operator"
19825           [(and:SI (match_operand:SI 2 "register_operand" "")
19826                    (match_operand:SI 3 "immediate_operand" ""))
19827            (const_int 0)]))]
19828   "ix86_match_ccmode (insn, CCNOmode)
19829    && (true_regnum (operands[2]) != 0
19830        || satisfies_constraint_K (operands[3]))
19831    && peep2_reg_dead_p (1, operands[2])"
19832   [(parallel
19833      [(set (match_dup 0)
19834            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19835                             (const_int 0)]))
19836       (set (match_dup 2)
19837            (and:SI (match_dup 2) (match_dup 3)))])]
19838   "")
19840 ;; We don't need to handle HImode case, because it will be promoted to SImode
19841 ;; on ! TARGET_PARTIAL_REG_STALL
19843 (define_peephole2
19844   [(set (match_operand 0 "flags_reg_operand" "")
19845         (match_operator 1 "compare_operator"
19846           [(and:QI (match_operand:QI 2 "register_operand" "")
19847                    (match_operand:QI 3 "immediate_operand" ""))
19848            (const_int 0)]))]
19849   "! TARGET_PARTIAL_REG_STALL
19850    && ix86_match_ccmode (insn, CCNOmode)
19851    && true_regnum (operands[2]) != 0
19852    && peep2_reg_dead_p (1, operands[2])"
19853   [(parallel
19854      [(set (match_dup 0)
19855            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19856                             (const_int 0)]))
19857       (set (match_dup 2)
19858            (and:QI (match_dup 2) (match_dup 3)))])]
19859   "")
19861 (define_peephole2
19862   [(set (match_operand 0 "flags_reg_operand" "")
19863         (match_operator 1 "compare_operator"
19864           [(and:SI
19865              (zero_extract:SI
19866                (match_operand 2 "ext_register_operand" "")
19867                (const_int 8)
19868                (const_int 8))
19869              (match_operand 3 "const_int_operand" ""))
19870            (const_int 0)]))]
19871   "! TARGET_PARTIAL_REG_STALL
19872    && ix86_match_ccmode (insn, CCNOmode)
19873    && true_regnum (operands[2]) != 0
19874    && peep2_reg_dead_p (1, operands[2])"
19875   [(parallel [(set (match_dup 0)
19876                    (match_op_dup 1
19877                      [(and:SI
19878                         (zero_extract:SI
19879                           (match_dup 2)
19880                           (const_int 8)
19881                           (const_int 8))
19882                         (match_dup 3))
19883                       (const_int 0)]))
19884               (set (zero_extract:SI (match_dup 2)
19885                                     (const_int 8)
19886                                     (const_int 8))
19887                    (and:SI 
19888                      (zero_extract:SI
19889                        (match_dup 2)
19890                        (const_int 8)
19891                        (const_int 8))
19892                      (match_dup 3)))])]
19893   "")
19895 ;; Don't do logical operations with memory inputs.
19896 (define_peephole2
19897   [(match_scratch:SI 2 "r")
19898    (parallel [(set (match_operand:SI 0 "register_operand" "")
19899                    (match_operator:SI 3 "arith_or_logical_operator"
19900                      [(match_dup 0)
19901                       (match_operand:SI 1 "memory_operand" "")]))
19902               (clobber (reg:CC FLAGS_REG))])]
19903   "! optimize_size && ! TARGET_READ_MODIFY"
19904   [(set (match_dup 2) (match_dup 1))
19905    (parallel [(set (match_dup 0)
19906                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19907               (clobber (reg:CC FLAGS_REG))])]
19908   "")
19910 (define_peephole2
19911   [(match_scratch:SI 2 "r")
19912    (parallel [(set (match_operand:SI 0 "register_operand" "")
19913                    (match_operator:SI 3 "arith_or_logical_operator"
19914                      [(match_operand:SI 1 "memory_operand" "")
19915                       (match_dup 0)]))
19916               (clobber (reg:CC FLAGS_REG))])]
19917   "! optimize_size && ! TARGET_READ_MODIFY"
19918   [(set (match_dup 2) (match_dup 1))
19919    (parallel [(set (match_dup 0)
19920                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19921               (clobber (reg:CC FLAGS_REG))])]
19922   "")
19924 ; Don't do logical operations with memory outputs
19926 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19927 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19928 ; the same decoder scheduling characteristics as the original.
19930 (define_peephole2
19931   [(match_scratch:SI 2 "r")
19932    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19933                    (match_operator:SI 3 "arith_or_logical_operator"
19934                      [(match_dup 0)
19935                       (match_operand:SI 1 "nonmemory_operand" "")]))
19936               (clobber (reg:CC FLAGS_REG))])]
19937   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19938   [(set (match_dup 2) (match_dup 0))
19939    (parallel [(set (match_dup 2)
19940                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19941               (clobber (reg:CC FLAGS_REG))])
19942    (set (match_dup 0) (match_dup 2))]
19943   "")
19945 (define_peephole2
19946   [(match_scratch:SI 2 "r")
19947    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19948                    (match_operator:SI 3 "arith_or_logical_operator"
19949                      [(match_operand:SI 1 "nonmemory_operand" "")
19950                       (match_dup 0)]))
19951               (clobber (reg:CC FLAGS_REG))])]
19952   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19953   [(set (match_dup 2) (match_dup 0))
19954    (parallel [(set (match_dup 2)
19955                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19956               (clobber (reg:CC FLAGS_REG))])
19957    (set (match_dup 0) (match_dup 2))]
19958   "")
19960 ;; Attempt to always use XOR for zeroing registers.
19961 (define_peephole2
19962   [(set (match_operand 0 "register_operand" "")
19963         (match_operand 1 "const0_operand" ""))]
19964   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19965    && (! TARGET_USE_MOV0 || optimize_size)
19966    && GENERAL_REG_P (operands[0])
19967    && peep2_regno_dead_p (0, FLAGS_REG)"
19968   [(parallel [(set (match_dup 0) (const_int 0))
19969               (clobber (reg:CC FLAGS_REG))])]
19971   operands[0] = gen_lowpart (word_mode, operands[0]);
19974 (define_peephole2
19975   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19976         (const_int 0))]
19977   "(GET_MODE (operands[0]) == QImode
19978     || GET_MODE (operands[0]) == HImode)
19979    && (! TARGET_USE_MOV0 || optimize_size)
19980    && peep2_regno_dead_p (0, FLAGS_REG)"
19981   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19982               (clobber (reg:CC FLAGS_REG))])])
19984 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19985 (define_peephole2
19986   [(set (match_operand 0 "register_operand" "")
19987         (const_int -1))]
19988   "(GET_MODE (operands[0]) == HImode
19989     || GET_MODE (operands[0]) == SImode 
19990     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19991    && (optimize_size || TARGET_PENTIUM)
19992    && peep2_regno_dead_p (0, FLAGS_REG)"
19993   [(parallel [(set (match_dup 0) (const_int -1))
19994               (clobber (reg:CC FLAGS_REG))])]
19995   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19996                               operands[0]);")
19998 ;; Attempt to convert simple leas to adds. These can be created by
19999 ;; move expanders.
20000 (define_peephole2
20001   [(set (match_operand:SI 0 "register_operand" "")
20002         (plus:SI (match_dup 0)
20003                  (match_operand:SI 1 "nonmemory_operand" "")))]
20004   "peep2_regno_dead_p (0, FLAGS_REG)"
20005   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20006               (clobber (reg:CC FLAGS_REG))])]
20007   "")
20009 (define_peephole2
20010   [(set (match_operand:SI 0 "register_operand" "")
20011         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20012                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20013   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20014   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20015               (clobber (reg:CC FLAGS_REG))])]
20016   "operands[2] = gen_lowpart (SImode, operands[2]);")
20018 (define_peephole2
20019   [(set (match_operand:DI 0 "register_operand" "")
20020         (plus:DI (match_dup 0)
20021                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20022   "peep2_regno_dead_p (0, FLAGS_REG)"
20023   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20024               (clobber (reg:CC FLAGS_REG))])]
20025   "")
20027 (define_peephole2
20028   [(set (match_operand:SI 0 "register_operand" "")
20029         (mult:SI (match_dup 0)
20030                  (match_operand:SI 1 "const_int_operand" "")))]
20031   "exact_log2 (INTVAL (operands[1])) >= 0
20032    && peep2_regno_dead_p (0, FLAGS_REG)"
20033   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20034               (clobber (reg:CC FLAGS_REG))])]
20035   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20037 (define_peephole2
20038   [(set (match_operand:DI 0 "register_operand" "")
20039         (mult:DI (match_dup 0)
20040                  (match_operand:DI 1 "const_int_operand" "")))]
20041   "exact_log2 (INTVAL (operands[1])) >= 0
20042    && peep2_regno_dead_p (0, FLAGS_REG)"
20043   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20044               (clobber (reg:CC FLAGS_REG))])]
20045   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20047 (define_peephole2
20048   [(set (match_operand:SI 0 "register_operand" "")
20049         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20050                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20051   "exact_log2 (INTVAL (operands[2])) >= 0
20052    && REGNO (operands[0]) == REGNO (operands[1])
20053    && peep2_regno_dead_p (0, FLAGS_REG)"
20054   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20055               (clobber (reg:CC FLAGS_REG))])]
20056   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20058 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20059 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20060 ;; many CPUs it is also faster, since special hardware to avoid esp
20061 ;; dependencies is present.
20063 ;; While some of these conversions may be done using splitters, we use peepholes
20064 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20066 ;; Convert prologue esp subtractions to push.
20067 ;; We need register to push.  In order to keep verify_flow_info happy we have
20068 ;; two choices
20069 ;; - use scratch and clobber it in order to avoid dependencies
20070 ;; - use already live register
20071 ;; We can't use the second way right now, since there is no reliable way how to
20072 ;; verify that given register is live.  First choice will also most likely in
20073 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20074 ;; call clobbered registers are dead.  We may want to use base pointer as an
20075 ;; alternative when no register is available later.
20077 (define_peephole2
20078   [(match_scratch:SI 0 "r")
20079    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20080               (clobber (reg:CC FLAGS_REG))
20081               (clobber (mem:BLK (scratch)))])]
20082   "optimize_size || !TARGET_SUB_ESP_4"
20083   [(clobber (match_dup 0))
20084    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20085               (clobber (mem:BLK (scratch)))])])
20087 (define_peephole2
20088   [(match_scratch:SI 0 "r")
20089    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20090               (clobber (reg:CC FLAGS_REG))
20091               (clobber (mem:BLK (scratch)))])]
20092   "optimize_size || !TARGET_SUB_ESP_8"
20093   [(clobber (match_dup 0))
20094    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20096               (clobber (mem:BLK (scratch)))])])
20098 ;; Convert esp subtractions to push.
20099 (define_peephole2
20100   [(match_scratch:SI 0 "r")
20101    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20102               (clobber (reg:CC FLAGS_REG))])]
20103   "optimize_size || !TARGET_SUB_ESP_4"
20104   [(clobber (match_dup 0))
20105    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20107 (define_peephole2
20108   [(match_scratch:SI 0 "r")
20109    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20110               (clobber (reg:CC FLAGS_REG))])]
20111   "optimize_size || !TARGET_SUB_ESP_8"
20112   [(clobber (match_dup 0))
20113    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20114    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20116 ;; Convert epilogue deallocator to pop.
20117 (define_peephole2
20118   [(match_scratch:SI 0 "r")
20119    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20120               (clobber (reg:CC FLAGS_REG))
20121               (clobber (mem:BLK (scratch)))])]
20122   "optimize_size || !TARGET_ADD_ESP_4"
20123   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20124               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20125               (clobber (mem:BLK (scratch)))])]
20126   "")
20128 ;; Two pops case is tricky, since pop causes dependency on destination register.
20129 ;; We use two registers if available.
20130 (define_peephole2
20131   [(match_scratch:SI 0 "r")
20132    (match_scratch:SI 1 "r")
20133    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20134               (clobber (reg:CC FLAGS_REG))
20135               (clobber (mem:BLK (scratch)))])]
20136   "optimize_size || !TARGET_ADD_ESP_8"
20137   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20138               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20139               (clobber (mem:BLK (scratch)))])
20140    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20141               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20142   "")
20144 (define_peephole2
20145   [(match_scratch:SI 0 "r")
20146    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20147               (clobber (reg:CC FLAGS_REG))
20148               (clobber (mem:BLK (scratch)))])]
20149   "optimize_size"
20150   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20151               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20152               (clobber (mem:BLK (scratch)))])
20153    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20154               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20155   "")
20157 ;; Convert esp additions to pop.
20158 (define_peephole2
20159   [(match_scratch:SI 0 "r")
20160    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   ""
20163   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20164               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20165   "")
20167 ;; Two pops case is tricky, since pop causes dependency on destination register.
20168 ;; We use two registers if available.
20169 (define_peephole2
20170   [(match_scratch:SI 0 "r")
20171    (match_scratch:SI 1 "r")
20172    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20173               (clobber (reg:CC FLAGS_REG))])]
20174   ""
20175   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20176               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20177    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20178               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20179   "")
20181 (define_peephole2
20182   [(match_scratch:SI 0 "r")
20183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20184               (clobber (reg:CC FLAGS_REG))])]
20185   "optimize_size"
20186   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20187               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20188    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20189               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20190   "")
20192 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20193 ;; required and register dies.  Similarly for 128 to plus -128.
20194 (define_peephole2
20195   [(set (match_operand 0 "flags_reg_operand" "")
20196         (match_operator 1 "compare_operator"
20197           [(match_operand 2 "register_operand" "")
20198            (match_operand 3 "const_int_operand" "")]))]
20199   "(INTVAL (operands[3]) == -1
20200     || INTVAL (operands[3]) == 1
20201     || INTVAL (operands[3]) == 128)
20202    && ix86_match_ccmode (insn, CCGCmode)
20203    && peep2_reg_dead_p (1, operands[2])"
20204   [(parallel [(set (match_dup 0)
20205                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20206               (clobber (match_dup 2))])]
20207   "")
20209 (define_peephole2
20210   [(match_scratch:DI 0 "r")
20211    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20212               (clobber (reg:CC FLAGS_REG))
20213               (clobber (mem:BLK (scratch)))])]
20214   "optimize_size || !TARGET_SUB_ESP_4"
20215   [(clobber (match_dup 0))
20216    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20217               (clobber (mem:BLK (scratch)))])])
20219 (define_peephole2
20220   [(match_scratch:DI 0 "r")
20221    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20222               (clobber (reg:CC FLAGS_REG))
20223               (clobber (mem:BLK (scratch)))])]
20224   "optimize_size || !TARGET_SUB_ESP_8"
20225   [(clobber (match_dup 0))
20226    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20228               (clobber (mem:BLK (scratch)))])])
20230 ;; Convert esp subtractions to push.
20231 (define_peephole2
20232   [(match_scratch:DI 0 "r")
20233    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20234               (clobber (reg:CC FLAGS_REG))])]
20235   "optimize_size || !TARGET_SUB_ESP_4"
20236   [(clobber (match_dup 0))
20237    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20239 (define_peephole2
20240   [(match_scratch:DI 0 "r")
20241    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20242               (clobber (reg:CC FLAGS_REG))])]
20243   "optimize_size || !TARGET_SUB_ESP_8"
20244   [(clobber (match_dup 0))
20245    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20246    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20248 ;; Convert epilogue deallocator to pop.
20249 (define_peephole2
20250   [(match_scratch:DI 0 "r")
20251    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20252               (clobber (reg:CC FLAGS_REG))
20253               (clobber (mem:BLK (scratch)))])]
20254   "optimize_size || !TARGET_ADD_ESP_4"
20255   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20256               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20257               (clobber (mem:BLK (scratch)))])]
20258   "")
20260 ;; Two pops case is tricky, since pop causes dependency on destination register.
20261 ;; We use two registers if available.
20262 (define_peephole2
20263   [(match_scratch:DI 0 "r")
20264    (match_scratch:DI 1 "r")
20265    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20266               (clobber (reg:CC FLAGS_REG))
20267               (clobber (mem:BLK (scratch)))])]
20268   "optimize_size || !TARGET_ADD_ESP_8"
20269   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20270               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20271               (clobber (mem:BLK (scratch)))])
20272    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20273               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20274   "")
20276 (define_peephole2
20277   [(match_scratch:DI 0 "r")
20278    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20279               (clobber (reg:CC FLAGS_REG))
20280               (clobber (mem:BLK (scratch)))])]
20281   "optimize_size"
20282   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20283               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20284               (clobber (mem:BLK (scratch)))])
20285    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20286               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20287   "")
20289 ;; Convert esp additions to pop.
20290 (define_peephole2
20291   [(match_scratch:DI 0 "r")
20292    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20293               (clobber (reg:CC FLAGS_REG))])]
20294   ""
20295   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20296               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20297   "")
20299 ;; Two pops case is tricky, since pop causes dependency on destination register.
20300 ;; We use two registers if available.
20301 (define_peephole2
20302   [(match_scratch:DI 0 "r")
20303    (match_scratch:DI 1 "r")
20304    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20305               (clobber (reg:CC FLAGS_REG))])]
20306   ""
20307   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20308               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20309    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20310               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20311   "")
20313 (define_peephole2
20314   [(match_scratch:DI 0 "r")
20315    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20316               (clobber (reg:CC FLAGS_REG))])]
20317   "optimize_size"
20318   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20319               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20320    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20321               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20322   "")
20324 ;; Convert imul by three, five and nine into lea
20325 (define_peephole2
20326   [(parallel
20327     [(set (match_operand:SI 0 "register_operand" "")
20328           (mult:SI (match_operand:SI 1 "register_operand" "")
20329                    (match_operand:SI 2 "const_int_operand" "")))
20330      (clobber (reg:CC FLAGS_REG))])]
20331   "INTVAL (operands[2]) == 3
20332    || INTVAL (operands[2]) == 5
20333    || INTVAL (operands[2]) == 9"
20334   [(set (match_dup 0)
20335         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20336                  (match_dup 1)))]
20337   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20339 (define_peephole2
20340   [(parallel
20341     [(set (match_operand:SI 0 "register_operand" "")
20342           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20343                    (match_operand:SI 2 "const_int_operand" "")))
20344      (clobber (reg:CC FLAGS_REG))])]
20345   "!optimize_size 
20346    && (INTVAL (operands[2]) == 3
20347        || INTVAL (operands[2]) == 5
20348        || INTVAL (operands[2]) == 9)"
20349   [(set (match_dup 0) (match_dup 1))
20350    (set (match_dup 0)
20351         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20352                  (match_dup 0)))]
20353   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20355 (define_peephole2
20356   [(parallel
20357     [(set (match_operand:DI 0 "register_operand" "")
20358           (mult:DI (match_operand:DI 1 "register_operand" "")
20359                    (match_operand:DI 2 "const_int_operand" "")))
20360      (clobber (reg:CC FLAGS_REG))])]
20361   "TARGET_64BIT
20362    && (INTVAL (operands[2]) == 3
20363        || INTVAL (operands[2]) == 5
20364        || INTVAL (operands[2]) == 9)"
20365   [(set (match_dup 0)
20366         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20367                  (match_dup 1)))]
20368   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20370 (define_peephole2
20371   [(parallel
20372     [(set (match_operand:DI 0 "register_operand" "")
20373           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20374                    (match_operand:DI 2 "const_int_operand" "")))
20375      (clobber (reg:CC FLAGS_REG))])]
20376   "TARGET_64BIT
20377    && !optimize_size 
20378    && (INTVAL (operands[2]) == 3
20379        || INTVAL (operands[2]) == 5
20380        || INTVAL (operands[2]) == 9)"
20381   [(set (match_dup 0) (match_dup 1))
20382    (set (match_dup 0)
20383         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20384                  (match_dup 0)))]
20385   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20387 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20388 ;; imul $32bit_imm, reg, reg is direct decoded.
20389 (define_peephole2
20390   [(match_scratch:DI 3 "r")
20391    (parallel [(set (match_operand:DI 0 "register_operand" "")
20392                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20393                             (match_operand:DI 2 "immediate_operand" "")))
20394               (clobber (reg:CC FLAGS_REG))])]
20395   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20396    && !satisfies_constraint_K (operands[2])"
20397   [(set (match_dup 3) (match_dup 1))
20398    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20399               (clobber (reg:CC FLAGS_REG))])]
20402 (define_peephole2
20403   [(match_scratch:SI 3 "r")
20404    (parallel [(set (match_operand:SI 0 "register_operand" "")
20405                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20406                             (match_operand:SI 2 "immediate_operand" "")))
20407               (clobber (reg:CC FLAGS_REG))])]
20408   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20409    && !satisfies_constraint_K (operands[2])"
20410   [(set (match_dup 3) (match_dup 1))
20411    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20412               (clobber (reg:CC FLAGS_REG))])]
20415 (define_peephole2
20416   [(match_scratch:SI 3 "r")
20417    (parallel [(set (match_operand:DI 0 "register_operand" "")
20418                    (zero_extend:DI
20419                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20420                               (match_operand:SI 2 "immediate_operand" ""))))
20421               (clobber (reg:CC FLAGS_REG))])]
20422   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20423    && !satisfies_constraint_K (operands[2])"
20424   [(set (match_dup 3) (match_dup 1))
20425    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20426               (clobber (reg:CC FLAGS_REG))])]
20429 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20430 ;; Convert it into imul reg, reg
20431 ;; It would be better to force assembler to encode instruction using long
20432 ;; immediate, but there is apparently no way to do so.
20433 (define_peephole2
20434   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20435                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20436                             (match_operand:DI 2 "const_int_operand" "")))
20437               (clobber (reg:CC FLAGS_REG))])
20438    (match_scratch:DI 3 "r")]
20439   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20440    && satisfies_constraint_K (operands[2])"
20441   [(set (match_dup 3) (match_dup 2))
20442    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20443               (clobber (reg:CC FLAGS_REG))])]
20445   if (!rtx_equal_p (operands[0], operands[1]))
20446     emit_move_insn (operands[0], operands[1]);
20449 (define_peephole2
20450   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20451                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20452                             (match_operand:SI 2 "const_int_operand" "")))
20453               (clobber (reg:CC FLAGS_REG))])
20454    (match_scratch:SI 3 "r")]
20455   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20456    && satisfies_constraint_K (operands[2])"
20457   [(set (match_dup 3) (match_dup 2))
20458    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20459               (clobber (reg:CC FLAGS_REG))])]
20461   if (!rtx_equal_p (operands[0], operands[1]))
20462     emit_move_insn (operands[0], operands[1]);
20465 (define_peephole2
20466   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20467                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20468                             (match_operand:HI 2 "immediate_operand" "")))
20469               (clobber (reg:CC FLAGS_REG))])
20470    (match_scratch:HI 3 "r")]
20471   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20472   [(set (match_dup 3) (match_dup 2))
20473    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20474               (clobber (reg:CC FLAGS_REG))])]
20476   if (!rtx_equal_p (operands[0], operands[1]))
20477     emit_move_insn (operands[0], operands[1]);
20480 ;; After splitting up read-modify operations, array accesses with memory
20481 ;; operands might end up in form:
20482 ;;  sall    $2, %eax
20483 ;;  movl    4(%esp), %edx
20484 ;;  addl    %edx, %eax
20485 ;; instead of pre-splitting:
20486 ;;  sall    $2, %eax
20487 ;;  addl    4(%esp), %eax
20488 ;; Turn it into:
20489 ;;  movl    4(%esp), %edx
20490 ;;  leal    (%edx,%eax,4), %eax
20492 (define_peephole2
20493   [(parallel [(set (match_operand 0 "register_operand" "")
20494                    (ashift (match_operand 1 "register_operand" "")
20495                            (match_operand 2 "const_int_operand" "")))
20496                (clobber (reg:CC FLAGS_REG))])
20497    (set (match_operand 3 "register_operand")
20498         (match_operand 4 "x86_64_general_operand" ""))
20499    (parallel [(set (match_operand 5 "register_operand" "")
20500                    (plus (match_operand 6 "register_operand" "")
20501                          (match_operand 7 "register_operand" "")))
20502                    (clobber (reg:CC FLAGS_REG))])]
20503   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20504    /* Validate MODE for lea.  */
20505    && ((!TARGET_PARTIAL_REG_STALL
20506         && (GET_MODE (operands[0]) == QImode
20507             || GET_MODE (operands[0]) == HImode))
20508        || GET_MODE (operands[0]) == SImode 
20509        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20510    /* We reorder load and the shift.  */
20511    && !rtx_equal_p (operands[1], operands[3])
20512    && !reg_overlap_mentioned_p (operands[0], operands[4])
20513    /* Last PLUS must consist of operand 0 and 3.  */
20514    && !rtx_equal_p (operands[0], operands[3])
20515    && (rtx_equal_p (operands[3], operands[6])
20516        || rtx_equal_p (operands[3], operands[7]))
20517    && (rtx_equal_p (operands[0], operands[6])
20518        || rtx_equal_p (operands[0], operands[7]))
20519    /* The intermediate operand 0 must die or be same as output.  */
20520    && (rtx_equal_p (operands[0], operands[5])
20521        || peep2_reg_dead_p (3, operands[0]))"
20522   [(set (match_dup 3) (match_dup 4))
20523    (set (match_dup 0) (match_dup 1))]
20525   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20526   int scale = 1 << INTVAL (operands[2]);
20527   rtx index = gen_lowpart (Pmode, operands[1]);
20528   rtx base = gen_lowpart (Pmode, operands[3]);
20529   rtx dest = gen_lowpart (mode, operands[5]);
20531   operands[1] = gen_rtx_PLUS (Pmode, base,
20532                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20533   if (mode != Pmode)
20534     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20535   operands[0] = dest;
20538 ;; Call-value patterns last so that the wildcard operand does not
20539 ;; disrupt insn-recog's switch tables.
20541 (define_insn "*call_value_pop_0"
20542   [(set (match_operand 0 "" "")
20543         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20544               (match_operand:SI 2 "" "")))
20545    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20546                             (match_operand:SI 3 "immediate_operand" "")))]
20547   "!TARGET_64BIT"
20549   if (SIBLING_CALL_P (insn))
20550     return "jmp\t%P1";
20551   else
20552     return "call\t%P1";
20554   [(set_attr "type" "callv")])
20556 (define_insn "*call_value_pop_1"
20557   [(set (match_operand 0 "" "")
20558         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20559               (match_operand:SI 2 "" "")))
20560    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20561                             (match_operand:SI 3 "immediate_operand" "i")))]
20562   "!TARGET_64BIT"
20564   if (constant_call_address_operand (operands[1], Pmode))
20565     {
20566       if (SIBLING_CALL_P (insn))
20567         return "jmp\t%P1";
20568       else
20569         return "call\t%P1";
20570     }
20571   if (SIBLING_CALL_P (insn))
20572     return "jmp\t%A1";
20573   else
20574     return "call\t%A1";
20576   [(set_attr "type" "callv")])
20578 (define_insn "*call_value_0"
20579   [(set (match_operand 0 "" "")
20580         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20581               (match_operand:SI 2 "" "")))]
20582   "!TARGET_64BIT"
20584   if (SIBLING_CALL_P (insn))
20585     return "jmp\t%P1";
20586   else
20587     return "call\t%P1";
20589   [(set_attr "type" "callv")])
20591 (define_insn "*call_value_0_rex64"
20592   [(set (match_operand 0 "" "")
20593         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20594               (match_operand:DI 2 "const_int_operand" "")))]
20595   "TARGET_64BIT"
20597   if (SIBLING_CALL_P (insn))
20598     return "jmp\t%P1";
20599   else
20600     return "call\t%P1";
20602   [(set_attr "type" "callv")])
20604 (define_insn "*call_value_1"
20605   [(set (match_operand 0 "" "")
20606         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20607               (match_operand:SI 2 "" "")))]
20608   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20610   if (constant_call_address_operand (operands[1], Pmode))
20611     return "call\t%P1";
20612   return "call\t%A1";
20614   [(set_attr "type" "callv")])
20616 (define_insn "*sibcall_value_1"
20617   [(set (match_operand 0 "" "")
20618         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20619               (match_operand:SI 2 "" "")))]
20620   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20622   if (constant_call_address_operand (operands[1], Pmode))
20623     return "jmp\t%P1";
20624   return "jmp\t%A1";
20626   [(set_attr "type" "callv")])
20628 (define_insn "*call_value_1_rex64"
20629   [(set (match_operand 0 "" "")
20630         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20631               (match_operand:DI 2 "" "")))]
20632   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20634   if (constant_call_address_operand (operands[1], Pmode))
20635     return "call\t%P1";
20636   return "call\t%A1";
20638   [(set_attr "type" "callv")])
20640 (define_insn "*sibcall_value_1_rex64"
20641   [(set (match_operand 0 "" "")
20642         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20643               (match_operand:DI 2 "" "")))]
20644   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20645   "jmp\t%P1"
20646   [(set_attr "type" "callv")])
20648 (define_insn "*sibcall_value_1_rex64_v"
20649   [(set (match_operand 0 "" "")
20650         (call (mem:QI (reg:DI 40))
20651               (match_operand:DI 1 "" "")))]
20652   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20653   "jmp\t*%%r11"
20654   [(set_attr "type" "callv")])
20656 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20657 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20658 ;; caught for use by garbage collectors and the like.  Using an insn that
20659 ;; maps to SIGILL makes it more likely the program will rightfully die.
20660 ;; Keeping with tradition, "6" is in honor of #UD.
20661 (define_insn "trap"
20662   [(trap_if (const_int 1) (const_int 6))]
20663   ""
20664   { return ASM_SHORT "0x0b0f"; }
20665   [(set_attr "length" "2")])
20667 (define_expand "sse_prologue_save"
20668   [(parallel [(set (match_operand:BLK 0 "" "")
20669                    (unspec:BLK [(reg:DI 21)
20670                                 (reg:DI 22)
20671                                 (reg:DI 23)
20672                                 (reg:DI 24)
20673                                 (reg:DI 25)
20674                                 (reg:DI 26)
20675                                 (reg:DI 27)
20676                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20677               (use (match_operand:DI 1 "register_operand" ""))
20678               (use (match_operand:DI 2 "immediate_operand" ""))
20679               (use (label_ref:DI (match_operand 3 "" "")))])]
20680   "TARGET_64BIT"
20681   "")
20683 (define_insn "*sse_prologue_save_insn"
20684   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20685                           (match_operand:DI 4 "const_int_operand" "n")))
20686         (unspec:BLK [(reg:DI 21)
20687                      (reg:DI 22)
20688                      (reg:DI 23)
20689                      (reg:DI 24)
20690                      (reg:DI 25)
20691                      (reg:DI 26)
20692                      (reg:DI 27)
20693                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20694    (use (match_operand:DI 1 "register_operand" "r"))
20695    (use (match_operand:DI 2 "const_int_operand" "i"))
20696    (use (label_ref:DI (match_operand 3 "" "X")))]
20697   "TARGET_64BIT
20698    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20699    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20700   "*
20702   int i;
20703   operands[0] = gen_rtx_MEM (Pmode,
20704                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20705   output_asm_insn (\"jmp\\t%A1\", operands);
20706   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20707     {
20708       operands[4] = adjust_address (operands[0], DImode, i*16);
20709       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20710       PUT_MODE (operands[4], TImode);
20711       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20712         output_asm_insn (\"rex\", operands);
20713       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20714     }
20715   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20716                              CODE_LABEL_NUMBER (operands[3]));
20717   RET;
20719   "
20720   [(set_attr "type" "other")
20721    (set_attr "length_immediate" "0")
20722    (set_attr "length_address" "0")
20723    (set_attr "length" "135")
20724    (set_attr "memory" "store")
20725    (set_attr "modrm" "0")
20726    (set_attr "mode" "DI")])
20728 (define_expand "prefetch"
20729   [(prefetch (match_operand 0 "address_operand" "")
20730              (match_operand:SI 1 "const_int_operand" "")
20731              (match_operand:SI 2 "const_int_operand" ""))]
20732   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20734   int rw = INTVAL (operands[1]);
20735   int locality = INTVAL (operands[2]);
20737   gcc_assert (rw == 0 || rw == 1);
20738   gcc_assert (locality >= 0 && locality <= 3);
20739   gcc_assert (GET_MODE (operands[0]) == Pmode
20740               || GET_MODE (operands[0]) == VOIDmode);
20742   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20743      supported by SSE counterpart or the SSE prefetch is not available
20744      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20745      of locality.  */
20746   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20747     operands[2] = GEN_INT (3);
20748   else
20749     operands[1] = const0_rtx;
20752 (define_insn "*prefetch_sse"
20753   [(prefetch (match_operand:SI 0 "address_operand" "p")
20754              (const_int 0)
20755              (match_operand:SI 1 "const_int_operand" ""))]
20756   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20758   static const char * const patterns[4] = {
20759    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20760   };
20762   int locality = INTVAL (operands[1]);
20763   gcc_assert (locality >= 0 && locality <= 3);
20765   return patterns[locality];  
20767   [(set_attr "type" "sse")
20768    (set_attr "memory" "none")])
20770 (define_insn "*prefetch_sse_rex"
20771   [(prefetch (match_operand:DI 0 "address_operand" "p")
20772              (const_int 0)
20773              (match_operand:SI 1 "const_int_operand" ""))]
20774   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20776   static const char * const patterns[4] = {
20777    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20778   };
20780   int locality = INTVAL (operands[1]);
20781   gcc_assert (locality >= 0 && locality <= 3);
20783   return patterns[locality];  
20785   [(set_attr "type" "sse")
20786    (set_attr "memory" "none")])
20788 (define_insn "*prefetch_3dnow"
20789   [(prefetch (match_operand:SI 0 "address_operand" "p")
20790              (match_operand:SI 1 "const_int_operand" "n")
20791              (const_int 3))]
20792   "TARGET_3DNOW && !TARGET_64BIT"
20794   if (INTVAL (operands[1]) == 0)
20795     return "prefetch\t%a0";
20796   else
20797     return "prefetchw\t%a0";
20799   [(set_attr "type" "mmx")
20800    (set_attr "memory" "none")])
20802 (define_insn "*prefetch_3dnow_rex"
20803   [(prefetch (match_operand:DI 0 "address_operand" "p")
20804              (match_operand:SI 1 "const_int_operand" "n")
20805              (const_int 3))]
20806   "TARGET_3DNOW && TARGET_64BIT"
20808   if (INTVAL (operands[1]) == 0)
20809     return "prefetch\t%a0";
20810   else
20811     return "prefetchw\t%a0";
20813   [(set_attr "type" "mmx")
20814    (set_attr "memory" "none")])
20816 (define_expand "stack_protect_set"
20817   [(match_operand 0 "memory_operand" "")
20818    (match_operand 1 "memory_operand" "")]
20819   ""
20821 #ifdef TARGET_THREAD_SSP_OFFSET
20822   if (TARGET_64BIT)
20823     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20824                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20825   else
20826     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20827                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20828 #else
20829   if (TARGET_64BIT)
20830     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20831   else
20832     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20833 #endif
20834   DONE;
20837 (define_insn "stack_protect_set_si"
20838   [(set (match_operand:SI 0 "memory_operand" "=m")
20839         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20840    (set (match_scratch:SI 2 "=&r") (const_int 0))
20841    (clobber (reg:CC FLAGS_REG))]
20842   ""
20843   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20844   [(set_attr "type" "multi")])
20846 (define_insn "stack_protect_set_di"
20847   [(set (match_operand:DI 0 "memory_operand" "=m")
20848         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20849    (set (match_scratch:DI 2 "=&r") (const_int 0))
20850    (clobber (reg:CC FLAGS_REG))]
20851   "TARGET_64BIT"
20852   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20853   [(set_attr "type" "multi")])
20855 (define_insn "stack_tls_protect_set_si"
20856   [(set (match_operand:SI 0 "memory_operand" "=m")
20857         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20858    (set (match_scratch:SI 2 "=&r") (const_int 0))
20859    (clobber (reg:CC FLAGS_REG))]
20860   ""
20861   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20862   [(set_attr "type" "multi")])
20864 (define_insn "stack_tls_protect_set_di"
20865   [(set (match_operand:DI 0 "memory_operand" "=m")
20866         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20867    (set (match_scratch:DI 2 "=&r") (const_int 0))
20868    (clobber (reg:CC FLAGS_REG))]
20869   "TARGET_64BIT"
20870   {
20871      /* The kernel uses a different segment register for performance reasons; a
20872         system call would not have to trash the userspace segment register,
20873         which would be expensive */
20874      if (ix86_cmodel != CM_KERNEL)
20875         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20876      else
20877         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20878   }
20879   [(set_attr "type" "multi")])
20881 (define_expand "stack_protect_test"
20882   [(match_operand 0 "memory_operand" "")
20883    (match_operand 1 "memory_operand" "")
20884    (match_operand 2 "" "")]
20885   ""
20887   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20888   ix86_compare_op0 = operands[0];
20889   ix86_compare_op1 = operands[1];
20890   ix86_compare_emitted = flags;
20892 #ifdef TARGET_THREAD_SSP_OFFSET
20893   if (TARGET_64BIT)
20894     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20895                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20896   else
20897     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20898                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20899 #else
20900   if (TARGET_64BIT)
20901     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20902   else
20903     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20904 #endif
20905   emit_jump_insn (gen_beq (operands[2]));
20906   DONE;
20909 (define_insn "stack_protect_test_si"
20910   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20911         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20912                      (match_operand:SI 2 "memory_operand" "m")]
20913                     UNSPEC_SP_TEST))
20914    (clobber (match_scratch:SI 3 "=&r"))]
20915   ""
20916   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20917   [(set_attr "type" "multi")])
20919 (define_insn "stack_protect_test_di"
20920   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20921         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20922                      (match_operand:DI 2 "memory_operand" "m")]
20923                     UNSPEC_SP_TEST))
20924    (clobber (match_scratch:DI 3 "=&r"))]
20925   "TARGET_64BIT"
20926   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20927   [(set_attr "type" "multi")])
20929 (define_insn "stack_tls_protect_test_si"
20930   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20931         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20932                      (match_operand:SI 2 "const_int_operand" "i")]
20933                     UNSPEC_SP_TLS_TEST))
20934    (clobber (match_scratch:SI 3 "=r"))]
20935   ""
20936   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20937   [(set_attr "type" "multi")])
20939 (define_insn "stack_tls_protect_test_di"
20940   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20941         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20942                      (match_operand:DI 2 "const_int_operand" "i")]
20943                     UNSPEC_SP_TLS_TEST))
20944    (clobber (match_scratch:DI 3 "=r"))]
20945   "TARGET_64BIT"
20946   {
20947      /* The kernel uses a different segment register for performance reasons; a
20948         system call would not have to trash the userspace segment register,
20949         which would be expensive */
20950      if (ix86_cmodel != CM_KERNEL)
20951         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20952      else
20953         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20954   }
20955   [(set_attr "type" "multi")])
20957 (include "sse.md")
20958 (include "mmx.md")
20959 (include "sync.md")