* config/fp-bit.h (LSHIFT): Take shift count parameter.
[official-gcc.git] / gcc / config / i386 / i386.md
blob1475e7fd36d2a55371cfb7bcd830c7ab3c9005b7
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
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)
77    ; Other random patterns
78    (UNSPEC_SCAS                 20)
79    (UNSPEC_FNSTSW               21)
80    (UNSPEC_SAHF                 22)
81    (UNSPEC_FSTCW                23)
82    (UNSPEC_ADD_CARRY            24)
83    (UNSPEC_FLDCW                25)
84    (UNSPEC_REP                  26)
85    (UNSPEC_EH_RETURN            27)
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDQQU                47)
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
122    ; x87 Rounding
123    (UNSPEC_FRNDINT_FLOOR        70)
124    (UNSPEC_FRNDINT_CEIL         71)
125    (UNSPEC_FRNDINT_TRUNC        72)
126    (UNSPEC_FRNDINT_MASK_PM      73)
127    (UNSPEC_FIST_FLOOR           74)
128    (UNSPEC_FIST_CEIL            75)
130    ; x87 Double output FP
131    (UNSPEC_SINCOS_COS           80)
132    (UNSPEC_SINCOS_SIN           81)
133    (UNSPEC_TAN_ONE              82)
134    (UNSPEC_TAN_TAN              83)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149   ])
151 (define_constants
152   [(UNSPECV_BLOCKAGE            0)
153    (UNSPECV_STACK_PROBE         1)
154    (UNSPECV_EMMS                2)
155    (UNSPECV_LDMXCSR             3)
156    (UNSPECV_STMXCSR             4)
157    (UNSPECV_FEMMS               5)
158    (UNSPECV_CLFLUSH             6)
159    (UNSPECV_ALIGN               7)
160    (UNSPECV_MONITOR             8)
161    (UNSPECV_MWAIT               9)
162    (UNSPECV_CMPXCHG_1           10)
163    (UNSPECV_CMPXCHG_2           11)
164    (UNSPECV_XCHG                12)
165    (UNSPECV_LOCK                13)
166   ])
168 ;; Registers by name.
169 (define_constants
170   [(BP_REG                       6)
171    (SP_REG                       7)
172    (FLAGS_REG                   17)
173    (FPSR_REG                    18)
174    (DIRFLAG_REG                 19)
175   ])
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; from i386.c.
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first.  This allows for better optimization.  For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
186 ;; Processor type.  This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189   (const (symbol_ref "ix86_tune")))
191 ;; A basic instruction type.  Refinements due to arguments to be
192 ;; provided in other attributes.
193 (define_attr "type"
194   "other,multi,
195    alu,alu1,negnot,imov,imovx,lea,
196    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197    icmp,test,ibr,setcc,icmov,
198    push,pop,call,callv,leave,
199    str,cld,
200    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201    sselog,sselog1,sseiadd,sseishft,sseimul,
202    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204   (const_string "other"))
206 ;; Main data type used by the insn
207 (define_attr "mode"
208   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209   (const_string "unknown"))
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214            (const_string "i387")
215          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
217            (const_string "sse")
218          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
219            (const_string "mmx")
220          (eq_attr "type" "other")
221            (const_string "unknown")]
222          (const_string "integer")))
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
227            (const_int 0)
228          (eq_attr "unit" "i387,sse,mmx")
229            (const_int 0)
230          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
231                           imul,icmp,push,pop")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233          (eq_attr "type" "imov,test")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235          (eq_attr "type" "call")
236            (if_then_else (match_operand 0 "constant_call_address_operand" "")
237              (const_int 4)
238              (const_int 0))
239          (eq_attr "type" "callv")
240            (if_then_else (match_operand 1 "constant_call_address_operand" "")
241              (const_int 4)
242              (const_int 0))
243          ;; We don't know the size before shorten_branches.  Expect
244          ;; the instruction to fit for better scheduling.
245          (eq_attr "type" "ibr")
246            (const_int 1)
247          ]
248          (symbol_ref "/* Update immediate_length and other attributes! */
249                       gcc_unreachable (),1")))
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
254            (const_int 0)
255          (and (eq_attr "type" "call")
256               (match_operand 0 "constant_call_address_operand" ""))
257              (const_int 0)
258          (and (eq_attr "type" "callv")
259               (match_operand 1 "constant_call_address_operand" ""))
260              (const_int 0)
261          ]
262          (symbol_ref "ix86_attr_length_address_default (insn)")))
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266   (if_then_else (ior (eq_attr "mode" "HI")
267                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
268     (const_int 1)
269     (const_int 0)))
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" "" 
273   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
274     (const_int 1)
275     (const_int 0)))
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
279   (if_then_else 
280     (ior (eq_attr "type" "imovx,setcc,icmov")
281          (eq_attr "unit" "sse,mmx"))
282     (const_int 1)
283     (const_int 0)))
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287   (cond [(and (eq_attr "mode" "DI")
288               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
289            (const_int 1)
290          (and (eq_attr "mode" "QI")
291               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292                   (const_int 0)))
293            (const_int 1)
294          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
295              (const_int 0))
296            (const_int 1)
297         ]
298         (const_int 0)))
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302   (cond [(eq_attr "type" "str,cld,leave")
303            (const_int 0)
304          (eq_attr "unit" "i387")
305            (const_int 0)
306          (and (eq_attr "type" "incdec")
307               (ior (match_operand:SI 1 "register_operand" "")
308                    (match_operand:HI 1 "register_operand" "")))
309            (const_int 0)
310          (and (eq_attr "type" "push")
311               (not (match_operand 1 "memory_operand" "")))
312            (const_int 0)
313          (and (eq_attr "type" "pop")
314               (not (match_operand 0 "memory_operand" "")))
315            (const_int 0)
316          (and (eq_attr "type" "imov")
317               (ior (and (match_operand 0 "register_operand" "")
318                         (match_operand 1 "immediate_operand" ""))
319                    (ior (and (match_operand 0 "ax_reg_operand" "")
320                              (match_operand 1 "memory_displacement_only_operand" ""))
321                         (and (match_operand 0 "memory_displacement_only_operand" "")
322                              (match_operand 1 "ax_reg_operand" "")))))
323            (const_int 0)
324          (and (eq_attr "type" "call")
325               (match_operand 0 "constant_call_address_operand" ""))
326              (const_int 0)
327          (and (eq_attr "type" "callv")
328               (match_operand 1 "constant_call_address_operand" ""))
329              (const_int 0)
330          ]
331          (const_int 1)))
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
336 ;; other insns.
337 (define_attr "length" ""
338   (cond [(eq_attr "type" "other,multi,fistp,frndint")
339            (const_int 16)
340          (eq_attr "type" "fcmp")
341            (const_int 4)
342          (eq_attr "unit" "i387")
343            (plus (const_int 2)
344                  (plus (attr "prefix_data16")
345                        (attr "length_address")))]
346          (plus (plus (attr "modrm")
347                      (plus (attr "prefix_0f")
348                            (plus (attr "prefix_rex")
349                                  (const_int 1))))
350                (plus (attr "prefix_rep")
351                      (plus (attr "prefix_data16")
352                            (plus (attr "length_immediate")
353                                  (attr "length_address")))))))
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
359 (define_attr "memory" "none,load,store,both,unknown"
360   (cond [(eq_attr "type" "other,multi,str")
361            (const_string "unknown")
362          (eq_attr "type" "lea,fcmov,fpspc,cld")
363            (const_string "none")
364          (eq_attr "type" "fistp,leave")
365            (const_string "both")
366          (eq_attr "type" "frndint")
367            (const_string "load")
368          (eq_attr "type" "push")
369            (if_then_else (match_operand 1 "memory_operand" "")
370              (const_string "both")
371              (const_string "store"))
372          (eq_attr "type" "pop")
373            (if_then_else (match_operand 0 "memory_operand" "")
374              (const_string "both")
375              (const_string "load"))
376          (eq_attr "type" "setcc")
377            (if_then_else (match_operand 0 "memory_operand" "")
378              (const_string "store")
379              (const_string "none"))
380          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381            (if_then_else (ior (match_operand 0 "memory_operand" "")
382                               (match_operand 1 "memory_operand" ""))
383              (const_string "load")
384              (const_string "none"))
385          (eq_attr "type" "ibr")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "load")
388              (const_string "none"))
389          (eq_attr "type" "call")
390            (if_then_else (match_operand 0 "constant_call_address_operand" "")
391              (const_string "none")
392              (const_string "load"))
393          (eq_attr "type" "callv")
394            (if_then_else (match_operand 1 "constant_call_address_operand" "")
395              (const_string "none")
396              (const_string "load"))
397          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398               (match_operand 1 "memory_operand" ""))
399            (const_string "both")
400          (and (match_operand 0 "memory_operand" "")
401               (match_operand 1 "memory_operand" ""))
402            (const_string "both")
403          (match_operand 0 "memory_operand" "")
404            (const_string "store")
405          (match_operand 1 "memory_operand" "")
406            (const_string "load")
407          (and (eq_attr "type"
408                  "!alu1,negnot,ishift1,
409                    imov,imovx,icmp,test,
410                    fmov,fcmp,fsgn,
411                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412                    mmx,mmxmov,mmxcmp,mmxcvt")
413               (match_operand 2 "memory_operand" ""))
414            (const_string "load")
415          (and (eq_attr "type" "icmov")
416               (match_operand 3 "memory_operand" ""))
417            (const_string "load")
418         ]
419         (const_string "none")))
421 ;; Indicates if an instruction has both an immediate and a displacement.
423 (define_attr "imm_disp" "false,true,unknown"
424   (cond [(eq_attr "type" "other,multi")
425            (const_string "unknown")
426          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427               (and (match_operand 0 "memory_displacement_operand" "")
428                    (match_operand 1 "immediate_operand" "")))
429            (const_string "true")
430          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431               (and (match_operand 0 "memory_displacement_operand" "")
432                    (match_operand 2 "immediate_operand" "")))
433            (const_string "true")
434         ]
435         (const_string "false")))
437 ;; Indicates if an FP operation has an integer source.
439 (define_attr "fp_int_src" "false,true"
440   (const_string "false"))
442 ;; Defines rounding mode of an FP operation.
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445   (const_string "any"))
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449   [(set_attr "length" "128")
450    (set_attr "type" "multi")])
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
468 ;; Scheduling descriptions
470 (include "pentium.md")
471 (include "ppro.md")
472 (include "k6.md")
473 (include "athlon.md")
476 ;; Operand and operator predicates
478 (include "predicates.md")
481 ;; Compare instructions.
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
487 (define_expand "cmpti"
488   [(set (reg:CC FLAGS_REG)
489         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490                     (match_operand:TI 1 "x86_64_general_operand" "")))]
491   "TARGET_64BIT"
493   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494     operands[0] = force_reg (TImode, operands[0]);
495   ix86_compare_op0 = operands[0];
496   ix86_compare_op1 = operands[1];
497   DONE;
500 (define_expand "cmpdi"
501   [(set (reg:CC FLAGS_REG)
502         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503                     (match_operand:DI 1 "x86_64_general_operand" "")))]
504   ""
506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507     operands[0] = force_reg (DImode, operands[0]);
508   ix86_compare_op0 = operands[0];
509   ix86_compare_op1 = operands[1];
510   DONE;
513 (define_expand "cmpsi"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516                     (match_operand:SI 1 "general_operand" "")))]
517   ""
519   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520     operands[0] = force_reg (SImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
526 (define_expand "cmphi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529                     (match_operand:HI 1 "general_operand" "")))]
530   ""
532   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533     operands[0] = force_reg (HImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
539 (define_expand "cmpqi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542                     (match_operand:QI 1 "general_operand" "")))]
543   "TARGET_QIMODE_MATH"
545   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546     operands[0] = force_reg (QImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
552 (define_insn "cmpdi_ccno_1_rex64"
553   [(set (reg FLAGS_REG)
554         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555                  (match_operand:DI 1 "const0_operand" "n,n")))]
556   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
557   "@
558    test{q}\t{%0, %0|%0, %0}
559    cmp{q}\t{%1, %0|%0, %1}"
560   [(set_attr "type" "test,icmp")
561    (set_attr "length_immediate" "0,1")
562    (set_attr "mode" "DI")])
564 (define_insn "*cmpdi_minus_1_rex64"
565   [(set (reg FLAGS_REG)
566         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
568                  (const_int 0)))]
569   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570   "cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "icmp")
572    (set_attr "mode" "DI")])
574 (define_expand "cmpdi_1_rex64"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577                     (match_operand:DI 1 "general_operand" "")))]
578   "TARGET_64BIT"
579   "")
581 (define_insn "cmpdi_1_insn_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586   "cmp{q}\t{%1, %0|%0, %1}"
587   [(set_attr "type" "icmp")
588    (set_attr "mode" "DI")])
591 (define_insn "*cmpsi_ccno_1"
592   [(set (reg FLAGS_REG)
593         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594                  (match_operand:SI 1 "const0_operand" "n,n")))]
595   "ix86_match_ccmode (insn, CCNOmode)"
596   "@
597    test{l}\t{%0, %0|%0, %0}
598    cmp{l}\t{%1, %0|%0, %1}"
599   [(set_attr "type" "test,icmp")
600    (set_attr "length_immediate" "0,1")
601    (set_attr "mode" "SI")])
603 (define_insn "*cmpsi_minus_1"
604   [(set (reg FLAGS_REG)
605         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606                            (match_operand:SI 1 "general_operand" "ri,mr"))
607                  (const_int 0)))]
608   "ix86_match_ccmode (insn, CCGOCmode)"
609   "cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "icmp")
611    (set_attr "mode" "SI")])
613 (define_expand "cmpsi_1"
614   [(set (reg:CC FLAGS_REG)
615         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616                     (match_operand:SI 1 "general_operand" "ri,mr")))]
617   ""
618   "")
620 (define_insn "*cmpsi_1_insn"
621   [(set (reg FLAGS_REG)
622         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                  (match_operand:SI 1 "general_operand" "ri,mr")))]
624   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625     && ix86_match_ccmode (insn, CCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
630 (define_insn "*cmphi_ccno_1"
631   [(set (reg FLAGS_REG)
632         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633                  (match_operand:HI 1 "const0_operand" "n,n")))]
634   "ix86_match_ccmode (insn, CCNOmode)"
635   "@
636    test{w}\t{%0, %0|%0, %0}
637    cmp{w}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "test,icmp")
639    (set_attr "length_immediate" "0,1")
640    (set_attr "mode" "HI")])
642 (define_insn "*cmphi_minus_1"
643   [(set (reg FLAGS_REG)
644         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645                            (match_operand:HI 1 "general_operand" "ri,mr"))
646                  (const_int 0)))]
647   "ix86_match_ccmode (insn, CCGOCmode)"
648   "cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "icmp")
650    (set_attr "mode" "HI")])
652 (define_insn "*cmphi_1"
653   [(set (reg FLAGS_REG)
654         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655                  (match_operand:HI 1 "general_operand" "ri,mr")))]
656   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657    && ix86_match_ccmode (insn, CCmode)"
658   "cmp{w}\t{%1, %0|%0, %1}"
659   [(set_attr "type" "icmp")
660    (set_attr "mode" "HI")])
662 (define_insn "*cmpqi_ccno_1"
663   [(set (reg FLAGS_REG)
664         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665                  (match_operand:QI 1 "const0_operand" "n,n")))]
666   "ix86_match_ccmode (insn, CCNOmode)"
667   "@
668    test{b}\t{%0, %0|%0, %0}
669    cmp{b}\t{$0, %0|%0, 0}"
670   [(set_attr "type" "test,icmp")
671    (set_attr "length_immediate" "0,1")
672    (set_attr "mode" "QI")])
674 (define_insn "*cmpqi_1"
675   [(set (reg FLAGS_REG)
676         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677                  (match_operand:QI 1 "general_operand" "qi,mq")))]
678   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679     && ix86_match_ccmode (insn, CCmode)"
680   "cmp{b}\t{%1, %0|%0, %1}"
681   [(set_attr "type" "icmp")
682    (set_attr "mode" "QI")])
684 (define_insn "*cmpqi_minus_1"
685   [(set (reg FLAGS_REG)
686         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687                            (match_operand:QI 1 "general_operand" "qi,mq"))
688                  (const_int 0)))]
689   "ix86_match_ccmode (insn, CCGOCmode)"
690   "cmp{b}\t{%1, %0|%0, %1}"
691   [(set_attr "type" "icmp")
692    (set_attr "mode" "QI")])
694 (define_insn "*cmpqi_ext_1"
695   [(set (reg FLAGS_REG)
696         (compare
697           (match_operand:QI 0 "general_operand" "Qm")
698           (subreg:QI
699             (zero_extract:SI
700               (match_operand 1 "ext_register_operand" "Q")
701               (const_int 8)
702               (const_int 8)) 0)))]
703   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704   "cmp{b}\t{%h1, %0|%0, %h1}"
705   [(set_attr "type" "icmp")
706    (set_attr "mode" "QI")])
708 (define_insn "*cmpqi_ext_1_rex64"
709   [(set (reg FLAGS_REG)
710         (compare
711           (match_operand:QI 0 "register_operand" "Q")
712           (subreg:QI
713             (zero_extract:SI
714               (match_operand 1 "ext_register_operand" "Q")
715               (const_int 8)
716               (const_int 8)) 0)))]
717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718   "cmp{b}\t{%h1, %0|%0, %h1}"
719   [(set_attr "type" "icmp")
720    (set_attr "mode" "QI")])
722 (define_insn "*cmpqi_ext_2"
723   [(set (reg FLAGS_REG)
724         (compare
725           (subreg:QI
726             (zero_extract:SI
727               (match_operand 0 "ext_register_operand" "Q")
728               (const_int 8)
729               (const_int 8)) 0)
730           (match_operand:QI 1 "const0_operand" "n")))]
731   "ix86_match_ccmode (insn, CCNOmode)"
732   "test{b}\t%h0, %h0"
733   [(set_attr "type" "test")
734    (set_attr "length_immediate" "0")
735    (set_attr "mode" "QI")])
737 (define_expand "cmpqi_ext_3"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC
740           (subreg:QI
741             (zero_extract:SI
742               (match_operand 0 "ext_register_operand" "")
743               (const_int 8)
744               (const_int 8)) 0)
745           (match_operand:QI 1 "general_operand" "")))]
746   ""
747   "")
749 (define_insn "cmpqi_ext_3_insn"
750   [(set (reg FLAGS_REG)
751         (compare
752           (subreg:QI
753             (zero_extract:SI
754               (match_operand 0 "ext_register_operand" "Q")
755               (const_int 8)
756               (const_int 8)) 0)
757           (match_operand:QI 1 "general_operand" "Qmn")))]
758   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759   "cmp{b}\t{%1, %h0|%h0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "QI")])
763 (define_insn "cmpqi_ext_3_insn_rex64"
764   [(set (reg FLAGS_REG)
765         (compare
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773   "cmp{b}\t{%1, %h0|%h0, %1}"
774   [(set_attr "type" "icmp")
775    (set_attr "mode" "QI")])
777 (define_insn "*cmpqi_ext_4"
778   [(set (reg FLAGS_REG)
779         (compare
780           (subreg:QI
781             (zero_extract:SI
782               (match_operand 0 "ext_register_operand" "Q")
783               (const_int 8)
784               (const_int 8)) 0)
785           (subreg:QI
786             (zero_extract:SI
787               (match_operand 1 "ext_register_operand" "Q")
788               (const_int 8)
789               (const_int 8)) 0)))]
790   "ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%h1, %h0|%h0, %h1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares.  Which is what
798 ;; the old patterns did, but with many more of them.
800 (define_expand "cmpxf"
801   [(set (reg:CC FLAGS_REG)
802         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803                     (match_operand:XF 1 "nonmemory_operand" "")))]
804   "TARGET_80387"
806   ix86_compare_op0 = operands[0];
807   ix86_compare_op1 = operands[1];
808   DONE;
811 (define_expand "cmpdf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
822 (define_expand "cmpsf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || TARGET_SSE_MATH"
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
836 ;; CCFPmode     compare with exceptions
837 ;; CCFPUmode    compare with no exceptions
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
842 (define_insn "*cmpfp_0"
843   [(set (match_operand:HI 0 "register_operand" "=a")
844         (unspec:HI
845           [(compare:CCFP
846              (match_operand 1 "register_operand" "f")
847              (match_operand 2 "const0_operand" "X"))]
848         UNSPEC_FNSTSW))]
849   "TARGET_80387
850    && FLOAT_MODE_P (GET_MODE (operands[1]))
851    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
855    (set (attr "mode")
856      (cond [(match_operand:SF 1 "" "")
857               (const_string "SF")
858             (match_operand:DF 1 "" "")
859               (const_string "DF")
860            ]
861            (const_string "XF")))])
863 (define_insn "*cmpfp_sf"
864   [(set (match_operand:HI 0 "register_operand" "=a")
865         (unspec:HI
866           [(compare:CCFP
867              (match_operand:SF 1 "register_operand" "f")
868              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
869           UNSPEC_FNSTSW))]
870   "TARGET_80387"
871   "* return output_fp_compare (insn, operands, 0, 0);"
872   [(set_attr "type" "multi")
873    (set_attr "unit" "i387")
874    (set_attr "mode" "SF")])
876 (define_insn "*cmpfp_df"
877   [(set (match_operand:HI 0 "register_operand" "=a")
878         (unspec:HI
879           [(compare:CCFP
880              (match_operand:DF 1 "register_operand" "f")
881              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
882           UNSPEC_FNSTSW))]
883   "TARGET_80387"
884   "* return output_fp_compare (insn, operands, 0, 0);"
885   [(set_attr "type" "multi")
886    (set_attr "unit" "i387")
887    (set_attr "mode" "DF")])
889 (define_insn "*cmpfp_xf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:XF 1 "register_operand" "f")
894              (match_operand:XF 2 "register_operand" "f"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "XF")])
902 (define_insn "*cmpfp_u"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFPU
906              (match_operand 1 "register_operand" "f")
907              (match_operand 2 "register_operand" "f"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387
910    && FLOAT_MODE_P (GET_MODE (operands[1]))
911    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912   "* return output_fp_compare (insn, operands, 0, 1);"
913   [(set_attr "type" "multi")
914    (set_attr "unit" "i387")
915    (set (attr "mode")
916      (cond [(match_operand:SF 1 "" "")
917               (const_string "SF")
918             (match_operand:DF 1 "" "")
919               (const_string "DF")
920            ]
921            (const_string "XF")))])
923 (define_insn "*cmpfp_<mode>"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFP
927              (match_operand 1 "register_operand" "f")
928              (match_operator 3 "float_operator"
929                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
930           UNSPEC_FNSTSW))]
931   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932    && FLOAT_MODE_P (GET_MODE (operands[1]))
933    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934   "* return output_fp_compare (insn, operands, 0, 0);"
935   [(set_attr "type" "multi")
936    (set_attr "unit" "i387")
937    (set_attr "fp_int_src" "true")
938    (set_attr "mode" "<MODE>")])
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
943 (define_insn "x86_fnstsw_1"
944   [(set (match_operand:HI 0 "register_operand" "=a")
945         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
946   "TARGET_80387"
947   "fnstsw\t%0"
948   [(set_attr "length" "2")
949    (set_attr "mode" "SI")
950    (set_attr "unit" "i387")])
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
955 (define_insn "x86_sahf_1"
956   [(set (reg:CC FLAGS_REG)
957         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
958   "!TARGET_64BIT"
959   "sahf"
960   [(set_attr "length" "1")
961    (set_attr "athlon_decode" "vector")
962    (set_attr "mode" "SI")])
964 ;; Pentium Pro can do steps 1 through 3 in one go.
966 (define_insn "*cmpfp_i_mixed"
967   [(set (reg:CCFP FLAGS_REG)
968         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
970   "TARGET_MIX_SSE_I387
971    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973   "* return output_fp_compare (insn, operands, 1, 0);"
974   [(set_attr "type" "fcmp,ssecomi")
975    (set (attr "mode")
976      (if_then_else (match_operand:SF 1 "" "")
977         (const_string "SF")
978         (const_string "DF")))
979    (set_attr "athlon_decode" "vector")])
981 (define_insn "*cmpfp_i_sse"
982   [(set (reg:CCFP FLAGS_REG)
983         (compare:CCFP (match_operand 0 "register_operand" "x")
984                       (match_operand 1 "nonimmediate_operand" "xm")))]
985   "TARGET_SSE_MATH
986    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988   "* return output_fp_compare (insn, operands, 1, 0);"
989   [(set_attr "type" "ssecomi")
990    (set (attr "mode")
991      (if_then_else (match_operand:SF 1 "" "")
992         (const_string "SF")
993         (const_string "DF")))
994    (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_i_i387"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP (match_operand 0 "register_operand" "f")
999                       (match_operand 1 "register_operand" "f")))]
1000   "TARGET_80387 && TARGET_CMOVE
1001    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002    && FLOAT_MODE_P (GET_MODE (operands[0]))
1003    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004   "* return output_fp_compare (insn, operands, 1, 0);"
1005   [(set_attr "type" "fcmp")
1006    (set (attr "mode")
1007      (cond [(match_operand:SF 1 "" "")
1008               (const_string "SF")
1009             (match_operand:DF 1 "" "")
1010               (const_string "DF")
1011            ]
1012            (const_string "XF")))
1013    (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_iu_mixed"
1016   [(set (reg:CCFPU FLAGS_REG)
1017         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019   "TARGET_MIX_SSE_I387
1020    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 1);"
1023   [(set_attr "type" "fcmp,ssecomi")
1024    (set (attr "mode")
1025      (if_then_else (match_operand:SF 1 "" "")
1026         (const_string "SF")
1027         (const_string "DF")))
1028    (set_attr "athlon_decode" "vector")])
1030 (define_insn "*cmpfp_iu_sse"
1031   [(set (reg:CCFPU FLAGS_REG)
1032         (compare:CCFPU (match_operand 0 "register_operand" "x")
1033                        (match_operand 1 "nonimmediate_operand" "xm")))]
1034   "TARGET_SSE_MATH
1035    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037   "* return output_fp_compare (insn, operands, 1, 1);"
1038   [(set_attr "type" "ssecomi")
1039    (set (attr "mode")
1040      (if_then_else (match_operand:SF 1 "" "")
1041         (const_string "SF")
1042         (const_string "DF")))
1043    (set_attr "athlon_decode" "vector")])
1045 (define_insn "*cmpfp_iu_387"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f")
1048                        (match_operand 1 "register_operand" "f")))]
1049   "TARGET_80387 && TARGET_CMOVE
1050    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051    && FLOAT_MODE_P (GET_MODE (operands[0]))
1052    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053   "* return output_fp_compare (insn, operands, 1, 1);"
1054   [(set_attr "type" "fcmp")
1055    (set (attr "mode")
1056      (cond [(match_operand:SF 1 "" "")
1057               (const_string "SF")
1058             (match_operand:DF 1 "" "")
1059               (const_string "DF")
1060            ]
1061            (const_string "XF")))
1062    (set_attr "athlon_decode" "vector")])
1064 ;; Move instructions.
1066 ;; General case of fullword move.
1068 (define_expand "movsi"
1069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070         (match_operand:SI 1 "general_operand" ""))]
1071   ""
1072   "ix86_expand_move (SImode, operands); DONE;")
1074 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1075 ;; general_operand.
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1083 (define_insn "*pushsi2"
1084   [(set (match_operand:SI 0 "push_operand" "=<")
1085         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1086   "!TARGET_64BIT"
1087   "push{l}\t%1"
1088   [(set_attr "type" "push")
1089    (set_attr "mode" "SI")])
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093   [(set (match_operand:SI 0 "push_operand" "=X")
1094         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1095   "TARGET_64BIT"
1096   "push{q}\t%q1"
1097   [(set_attr "type" "push")
1098    (set_attr "mode" "SI")])
1100 (define_insn "*pushsi2_prologue"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103    (clobber (mem:BLK (scratch)))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1109 (define_insn "*popsi1_epilogue"
1110   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111         (mem:SI (reg:SI SP_REG)))
1112    (set (reg:SI SP_REG)
1113         (plus:SI (reg:SI SP_REG) (const_int 4)))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "pop{l}\t%0"
1117   [(set_attr "type" "pop")
1118    (set_attr "mode" "SI")])
1120 (define_insn "popsi1"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1125   "!TARGET_64BIT"
1126   "pop{l}\t%0"
1127   [(set_attr "type" "pop")
1128    (set_attr "mode" "SI")])
1130 (define_insn "*movsi_xor"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (match_operand:SI 1 "const0_operand" "i"))
1133    (clobber (reg:CC FLAGS_REG))]
1134   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135   "xor{l}\t{%0, %0|%0, %0}"
1136   [(set_attr "type" "alu1")
1137    (set_attr "mode" "SI")
1138    (set_attr "length_immediate" "0")])
1140 (define_insn "*movsi_or"
1141   [(set (match_operand:SI 0 "register_operand" "=r")
1142         (match_operand:SI 1 "immediate_operand" "i"))
1143    (clobber (reg:CC FLAGS_REG))]
1144   "reload_completed
1145    && operands[1] == constm1_rtx
1146    && (TARGET_PENTIUM || optimize_size)"
1148   operands[1] = constm1_rtx;
1149   return "or{l}\t{%1, %0|%0, %1}";
1151   [(set_attr "type" "alu1")
1152    (set_attr "mode" "SI")
1153    (set_attr "length_immediate" "1")])
1155 (define_insn "*movsi_1"
1156   [(set (match_operand:SI 0 "nonimmediate_operand"
1157                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158         (match_operand:SI 1 "general_operand"
1159                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1160   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162   switch (get_attr_type (insn))
1163     {
1164     case TYPE_SSELOG1:
1165       if (get_attr_mode (insn) == MODE_TI)
1166         return "pxor\t%0, %0";
1167       return "xorps\t%0, %0";
1169     case TYPE_SSEMOV:
1170       switch (get_attr_mode (insn))
1171         {
1172         case MODE_TI:
1173           return "movdqa\t{%1, %0|%0, %1}";
1174         case MODE_V4SF:
1175           return "movaps\t{%1, %0|%0, %1}";
1176         case MODE_SI:
1177           return "movd\t{%1, %0|%0, %1}";
1178         case MODE_SF:
1179           return "movss\t{%1, %0|%0, %1}";
1180         default:
1181           gcc_unreachable ();
1182         }
1184     case TYPE_MMXADD:
1185       return "pxor\t%0, %0";
1187     case TYPE_MMXMOV:
1188       if (get_attr_mode (insn) == MODE_DI)
1189         return "movq\t{%1, %0|%0, %1}";
1190       return "movd\t{%1, %0|%0, %1}";
1192     case TYPE_LEA:
1193       return "lea{l}\t{%1, %0|%0, %1}";
1195     default:
1196       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197       return "mov{l}\t{%1, %0|%0, %1}";
1198     }
1200   [(set (attr "type")
1201      (cond [(eq_attr "alternative" "2")
1202               (const_string "mmxadd")
1203             (eq_attr "alternative" "3,4,5")
1204               (const_string "mmxmov")
1205             (eq_attr "alternative" "6")
1206               (const_string "sselog1")
1207             (eq_attr "alternative" "7,8,9,10,11")
1208               (const_string "ssemov")
1209             (match_operand:DI 1 "pic_32bit_operand" "")
1210               (const_string "lea")
1211            ]
1212            (const_string "imov")))
1213    (set (attr "mode")
1214      (cond [(eq_attr "alternative" "2,3")
1215               (const_string "DI")
1216             (eq_attr "alternative" "6,7")
1217               (if_then_else
1218                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219                 (const_string "V4SF")
1220                 (const_string "TI"))
1221             (and (eq_attr "alternative" "8,9,10,11")
1222                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1223               (const_string "SF")
1224            ]
1225            (const_string "SI")))])
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1234   "@
1235    movabs{l}\t{%1, %P0|%P0, %1}
1236    mov{l}\t{%1, %a0|%a0, %1}"
1237   [(set_attr "type" "imov")
1238    (set_attr "modrm" "0,*")
1239    (set_attr "length_address" "8,0")
1240    (set_attr "length_immediate" "0,*")
1241    (set_attr "memory" "store")
1242    (set_attr "mode" "SI")])
1244 (define_insn "*movabssi_2_rex64"
1245   [(set (match_operand:SI 0 "register_operand" "=a,r")
1246         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1248   "@
1249    movabs{l}\t{%P1, %0|%0, %P1}
1250    mov{l}\t{%a1, %0|%0, %a1}"
1251   [(set_attr "type" "imov")
1252    (set_attr "modrm" "0,*")
1253    (set_attr "length_address" "8,0")
1254    (set_attr "length_immediate" "0")
1255    (set_attr "memory" "load")
1256    (set_attr "mode" "SI")])
1258 (define_insn "*swapsi"
1259   [(set (match_operand:SI 0 "register_operand" "+r")
1260         (match_operand:SI 1 "register_operand" "+r"))
1261    (set (match_dup 1)
1262         (match_dup 0))]
1263   ""
1264   "xchg{l}\t%1, %0"
1265   [(set_attr "type" "imov")
1266    (set_attr "mode" "SI")
1267    (set_attr "pent_pair" "np")
1268    (set_attr "athlon_decode" "vector")])
1270 (define_expand "movhi"
1271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272         (match_operand:HI 1 "general_operand" ""))]
1273   ""
1274   "ix86_expand_move (HImode, operands); DONE;")
1276 (define_insn "*pushhi2"
1277   [(set (match_operand:HI 0 "push_operand" "=<,<")
1278         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279   "!TARGET_64BIT"
1280   "@
1281    push{w}\t{|WORD PTR }%1
1282    push{w}\t%1"
1283   [(set_attr "type" "push")
1284    (set_attr "mode" "HI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290   "TARGET_64BIT"
1291   "push{q}\t%q1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "QI")])
1295 (define_insn "*movhi_1"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300   switch (get_attr_type (insn))
1301     {
1302     case TYPE_IMOVX:
1303       /* movzwl is faster than movw on p2 due to partial word stalls,
1304          though not as fast as an aligned movl.  */
1305       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306     default:
1307       if (get_attr_mode (insn) == MODE_SI)
1308         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309       else
1310         return "mov{w}\t{%1, %0|%0, %1}";
1311     }
1313   [(set (attr "type")
1314      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "0")
1317                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318                           (const_int 0))
1319                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1320                           (const_int 0))))
1321               (const_string "imov")
1322             (and (eq_attr "alternative" "1,2")
1323                  (match_operand:HI 1 "aligned_operand" ""))
1324               (const_string "imov")
1325             (and (ne (symbol_ref "TARGET_MOVX")
1326                      (const_int 0))
1327                  (eq_attr "alternative" "0,2"))
1328               (const_string "imovx")
1329            ]
1330            (const_string "imov")))
1331     (set (attr "mode")
1332       (cond [(eq_attr "type" "imovx")
1333                (const_string "SI")
1334              (and (eq_attr "alternative" "1,2")
1335                   (match_operand:HI 1 "aligned_operand" ""))
1336                (const_string "SI")
1337              (and (eq_attr "alternative" "0")
1338                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339                            (const_int 0))
1340                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1341                            (const_int 0))))
1342                (const_string "SI")
1343             ]
1344             (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353   "@
1354    movabs{w}\t{%1, %P0|%P0, %1}
1355    mov{w}\t{%1, %a0|%a0, %1}"
1356   [(set_attr "type" "imov")
1357    (set_attr "modrm" "0,*")
1358    (set_attr "length_address" "8,0")
1359    (set_attr "length_immediate" "0,*")
1360    (set_attr "memory" "store")
1361    (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364   [(set (match_operand:HI 0 "register_operand" "=a,r")
1365         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367   "@
1368    movabs{w}\t{%P1, %0|%0, %P1}
1369    mov{w}\t{%a1, %0|%0, %a1}"
1370   [(set_attr "type" "imov")
1371    (set_attr "modrm" "0,*")
1372    (set_attr "length_address" "8,0")
1373    (set_attr "length_immediate" "0")
1374    (set_attr "memory" "load")
1375    (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378   [(set (match_operand:HI 0 "register_operand" "+r")
1379         (match_operand:HI 1 "register_operand" "+r"))
1380    (set (match_dup 1)
1381         (match_dup 0))]
1382   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1383   "xchg{l}\t%k1, %k0"
1384   [(set_attr "type" "imov")
1385    (set_attr "mode" "SI")
1386    (set_attr "pent_pair" "np")
1387    (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390   [(set (match_operand:HI 0 "register_operand" "+r")
1391         (match_operand:HI 1 "register_operand" "+r"))
1392    (set (match_dup 1)
1393         (match_dup 0))]
1394   "TARGET_PARTIAL_REG_STALL"
1395   "xchg{w}\t%1, %0"
1396   [(set_attr "type" "imov")
1397    (set_attr "mode" "HI")
1398    (set_attr "pent_pair" "np")
1399    (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403         (match_operand:HI 1 "general_operand" ""))]
1404   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406   /* Don't generate memory->memory moves, go through a register */
1407   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408     operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413         (match_operand:HI 1 "general_operand" "rn,m"))]
1414   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416   "mov{w}\t{%1, %0|%0, %1}"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422         (match_operand:HI 1 "const0_operand" "i"))
1423    (clobber (reg:CC FLAGS_REG))]
1424   "reload_completed
1425    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426   "xor{w}\t{%0, %0|%0, %0}"
1427   [(set_attr "type" "alu1")
1428    (set_attr "mode" "HI")
1429    (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433         (match_operand:QI 1 "general_operand" ""))]
1434   ""
1435   "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte".  But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1441 (define_insn "*pushqi2"
1442   [(set (match_operand:QI 0 "push_operand" "=X,X")
1443         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444   "!TARGET_64BIT"
1445   "@
1446    push{w}\t{|word ptr }%1
1447    push{w}\t%w1"
1448   [(set_attr "type" "push")
1449    (set_attr "mode" "HI")])
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453   [(set (match_operand:QI 0 "push_operand" "=X")
1454         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455   "TARGET_64BIT"
1456   "push{q}\t%q1"
1457   [(set_attr "type" "push")
1458    (set_attr "mode" "QI")])
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there.  Then we use movzx.
1470 (define_insn "*movqi_1"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1473   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1475   switch (get_attr_type (insn))
1476     {
1477     case TYPE_IMOVX:
1478       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480     default:
1481       if (get_attr_mode (insn) == MODE_SI)
1482         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483       else
1484         return "mov{b}\t{%1, %0|%0, %1}";
1485     }
1487   [(set (attr "type")
1488      (cond [(eq_attr "alternative" "5")
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")
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                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                            (const_int 0))))
1517                (const_string "SI")
1518              ;; Avoid partial register stalls when not using QImode arithmetic
1519              (and (eq_attr "type" "imov")
1520                   (and (eq_attr "alternative" "0,1")
1521                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522                                 (const_int 0))
1523                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1524                                 (const_int 0)))))
1525                (const_string "SI")
1526            ]
1527            (const_string "QI")))])
1529 (define_expand "reload_outqi"
1530   [(parallel [(match_operand:QI 0 "" "=m")
1531               (match_operand:QI 1 "register_operand" "r")
1532               (match_operand:QI 2 "register_operand" "=&q")])]
1533   ""
1535   rtx op0, op1, op2;
1536   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1538   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1539   if (! q_regs_operand (op1, QImode))
1540     {
1541       emit_insn (gen_movqi (op2, op1));
1542       op1 = op2;
1543     }
1544   emit_insn (gen_movqi (op0, op1));
1545   DONE;
1548 (define_insn "*swapqi_1"
1549   [(set (match_operand:QI 0 "register_operand" "+r")
1550         (match_operand:QI 1 "register_operand" "+r"))
1551    (set (match_dup 1)
1552         (match_dup 0))]
1553   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1554   "xchg{l}\t%k1, %k0"
1555   [(set_attr "type" "imov")
1556    (set_attr "mode" "SI")
1557    (set_attr "pent_pair" "np")
1558    (set_attr "athlon_decode" "vector")])
1560 (define_insn "*swapqi_2"
1561   [(set (match_operand:QI 0 "register_operand" "+q")
1562         (match_operand:QI 1 "register_operand" "+q"))
1563    (set (match_dup 1)
1564         (match_dup 0))]
1565   "TARGET_PARTIAL_REG_STALL"
1566   "xchg{b}\t%1, %0"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "QI")
1569    (set_attr "pent_pair" "np")
1570    (set_attr "athlon_decode" "vector")])
1572 (define_expand "movstrictqi"
1573   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1574         (match_operand:QI 1 "general_operand" ""))]
1575   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1577   /* Don't generate memory->memory moves, go through a register.  */
1578   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1579     operands[1] = force_reg (QImode, operands[1]);
1582 (define_insn "*movstrictqi_1"
1583   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1584         (match_operand:QI 1 "general_operand" "*qn,m"))]
1585   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1586    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1587   "mov{b}\t{%1, %0|%0, %1}"
1588   [(set_attr "type" "imov")
1589    (set_attr "mode" "QI")])
1591 (define_insn "*movstrictqi_xor"
1592   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1593         (match_operand:QI 1 "const0_operand" "i"))
1594    (clobber (reg:CC FLAGS_REG))]
1595   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1596   "xor{b}\t{%0, %0|%0, %0}"
1597   [(set_attr "type" "alu1")
1598    (set_attr "mode" "QI")
1599    (set_attr "length_immediate" "0")])
1601 (define_insn "*movsi_extv_1"
1602   [(set (match_operand:SI 0 "register_operand" "=R")
1603         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1604                          (const_int 8)
1605                          (const_int 8)))]
1606   ""
1607   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1608   [(set_attr "type" "imovx")
1609    (set_attr "mode" "SI")])
1611 (define_insn "*movhi_extv_1"
1612   [(set (match_operand:HI 0 "register_operand" "=R")
1613         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1614                          (const_int 8)
1615                          (const_int 8)))]
1616   ""
1617   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1618   [(set_attr "type" "imovx")
1619    (set_attr "mode" "SI")])
1621 (define_insn "*movqi_extv_1"
1622   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1623         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1624                          (const_int 8)
1625                          (const_int 8)))]
1626   "!TARGET_64BIT"
1628   switch (get_attr_type (insn))
1629     {
1630     case TYPE_IMOVX:
1631       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1632     default:
1633       return "mov{b}\t{%h1, %0|%0, %h1}";
1634     }
1636   [(set (attr "type")
1637      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1638                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1639                              (ne (symbol_ref "TARGET_MOVX")
1640                                  (const_int 0))))
1641         (const_string "imovx")
1642         (const_string "imov")))
1643    (set (attr "mode")
1644      (if_then_else (eq_attr "type" "imovx")
1645         (const_string "SI")
1646         (const_string "QI")))])
1648 (define_insn "*movqi_extv_1_rex64"
1649   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1650         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1651                          (const_int 8)
1652                          (const_int 8)))]
1653   "TARGET_64BIT"
1655   switch (get_attr_type (insn))
1656     {
1657     case TYPE_IMOVX:
1658       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1659     default:
1660       return "mov{b}\t{%h1, %0|%0, %h1}";
1661     }
1663   [(set (attr "type")
1664      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1665                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1666                              (ne (symbol_ref "TARGET_MOVX")
1667                                  (const_int 0))))
1668         (const_string "imovx")
1669         (const_string "imov")))
1670    (set (attr "mode")
1671      (if_then_else (eq_attr "type" "imovx")
1672         (const_string "SI")
1673         (const_string "QI")))])
1675 ;; Stores and loads of ax to arbitrary constant address.
1676 ;; We fake an second form of instruction to force reload to load address
1677 ;; into register when rax is not available
1678 (define_insn "*movabsqi_1_rex64"
1679   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1680         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1681   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1682   "@
1683    movabs{b}\t{%1, %P0|%P0, %1}
1684    mov{b}\t{%1, %a0|%a0, %1}"
1685   [(set_attr "type" "imov")
1686    (set_attr "modrm" "0,*")
1687    (set_attr "length_address" "8,0")
1688    (set_attr "length_immediate" "0,*")
1689    (set_attr "memory" "store")
1690    (set_attr "mode" "QI")])
1692 (define_insn "*movabsqi_2_rex64"
1693   [(set (match_operand:QI 0 "register_operand" "=a,r")
1694         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1695   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1696   "@
1697    movabs{b}\t{%P1, %0|%0, %P1}
1698    mov{b}\t{%a1, %0|%0, %a1}"
1699   [(set_attr "type" "imov")
1700    (set_attr "modrm" "0,*")
1701    (set_attr "length_address" "8,0")
1702    (set_attr "length_immediate" "0")
1703    (set_attr "memory" "load")
1704    (set_attr "mode" "QI")])
1706 (define_insn "*movdi_extzv_1"
1707   [(set (match_operand:DI 0 "register_operand" "=R")
1708         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1709                          (const_int 8)
1710                          (const_int 8)))]
1711   "TARGET_64BIT"
1712   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1713   [(set_attr "type" "imovx")
1714    (set_attr "mode" "DI")])
1716 (define_insn "*movsi_extzv_1"
1717   [(set (match_operand:SI 0 "register_operand" "=R")
1718         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1719                          (const_int 8)
1720                          (const_int 8)))]
1721   ""
1722   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1723   [(set_attr "type" "imovx")
1724    (set_attr "mode" "SI")])
1726 (define_insn "*movqi_extzv_2"
1727   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1728         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1729                                     (const_int 8)
1730                                     (const_int 8)) 0))]
1731   "!TARGET_64BIT"
1733   switch (get_attr_type (insn))
1734     {
1735     case TYPE_IMOVX:
1736       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737     default:
1738       return "mov{b}\t{%h1, %0|%0, %h1}";
1739     }
1741   [(set (attr "type")
1742      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1743                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1744                              (ne (symbol_ref "TARGET_MOVX")
1745                                  (const_int 0))))
1746         (const_string "imovx")
1747         (const_string "imov")))
1748    (set (attr "mode")
1749      (if_then_else (eq_attr "type" "imovx")
1750         (const_string "SI")
1751         (const_string "QI")))])
1753 (define_insn "*movqi_extzv_2_rex64"
1754   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1755         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1756                                     (const_int 8)
1757                                     (const_int 8)) 0))]
1758   "TARGET_64BIT"
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764     default:
1765       return "mov{b}\t{%h1, %0|%0, %h1}";
1766     }
1768   [(set (attr "type")
1769      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1770                         (ne (symbol_ref "TARGET_MOVX")
1771                             (const_int 0)))
1772         (const_string "imovx")
1773         (const_string "imov")))
1774    (set (attr "mode")
1775      (if_then_else (eq_attr "type" "imovx")
1776         (const_string "SI")
1777         (const_string "QI")))])
1779 (define_insn "movsi_insv_1"
1780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1781                          (const_int 8)
1782                          (const_int 8))
1783         (match_operand:SI 1 "general_operand" "Qmn"))]
1784   "!TARGET_64BIT"
1785   "mov{b}\t{%b1, %h0|%h0, %b1}"
1786   [(set_attr "type" "imov")
1787    (set_attr "mode" "QI")])
1789 (define_insn "movdi_insv_1_rex64"
1790   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1791                          (const_int 8)
1792                          (const_int 8))
1793         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1794   "TARGET_64BIT"
1795   "mov{b}\t{%b1, %h0|%h0, %b1}"
1796   [(set_attr "type" "imov")
1797    (set_attr "mode" "QI")])
1799 (define_insn "*movqi_insv_2"
1800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801                          (const_int 8)
1802                          (const_int 8))
1803         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1804                      (const_int 8)))]
1805   ""
1806   "mov{b}\t{%h1, %h0|%h0, %h1}"
1807   [(set_attr "type" "imov")
1808    (set_attr "mode" "QI")])
1810 (define_expand "movdi"
1811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1812         (match_operand:DI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (DImode, operands); DONE;")
1816 (define_insn "*pushdi"
1817   [(set (match_operand:DI 0 "push_operand" "=<")
1818         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1819   "!TARGET_64BIT"
1820   "#")
1822 (define_insn "*pushdi2_rex64"
1823   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1824         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1825   "TARGET_64BIT"
1826   "@
1827    push{q}\t%1
1828    #"
1829   [(set_attr "type" "push,multi")
1830    (set_attr "mode" "DI")])
1832 ;; Convert impossible pushes of immediate to existing instructions.
1833 ;; First try to get scratch register and go through it.  In case this
1834 ;; fails, push sign extended lower part first and then overwrite
1835 ;; upper part by 32bit move.
1836 (define_peephole2
1837   [(match_scratch:DI 2 "r")
1838    (set (match_operand:DI 0 "push_operand" "")
1839         (match_operand:DI 1 "immediate_operand" ""))]
1840   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841    && !x86_64_immediate_operand (operands[1], DImode)"
1842   [(set (match_dup 2) (match_dup 1))
1843    (set (match_dup 0) (match_dup 2))]
1844   "")
1846 ;; We need to define this as both peepholer and splitter for case
1847 ;; peephole2 pass is not run.
1848 ;; "&& 1" is needed to keep it from matching the previous pattern.
1849 (define_peephole2
1850   [(set (match_operand:DI 0 "push_operand" "")
1851         (match_operand:DI 1 "immediate_operand" ""))]
1852   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1854   [(set (match_dup 0) (match_dup 1))
1855    (set (match_dup 2) (match_dup 3))]
1856   "split_di (operands + 1, 1, operands + 2, operands + 3);
1857    operands[1] = gen_lowpart (DImode, operands[2]);
1858    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1859                                                     GEN_INT (4)));
1860   ")
1862 (define_split
1863   [(set (match_operand:DI 0 "push_operand" "")
1864         (match_operand:DI 1 "immediate_operand" ""))]
1865   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1866                     ? flow2_completed : reload_completed)
1867    && !symbolic_operand (operands[1], DImode)
1868    && !x86_64_immediate_operand (operands[1], DImode)"
1869   [(set (match_dup 0) (match_dup 1))
1870    (set (match_dup 2) (match_dup 3))]
1871   "split_di (operands + 1, 1, operands + 2, operands + 3);
1872    operands[1] = gen_lowpart (DImode, operands[2]);
1873    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1874                                                     GEN_INT (4)));
1875   ")
1877 (define_insn "*pushdi2_prologue_rex64"
1878   [(set (match_operand:DI 0 "push_operand" "=<")
1879         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1880    (clobber (mem:BLK (scratch)))]
1881   "TARGET_64BIT"
1882   "push{q}\t%1"
1883   [(set_attr "type" "push")
1884    (set_attr "mode" "DI")])
1886 (define_insn "*popdi1_epilogue_rex64"
1887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1888         (mem:DI (reg:DI SP_REG)))
1889    (set (reg:DI SP_REG)
1890         (plus:DI (reg:DI SP_REG) (const_int 8)))
1891    (clobber (mem:BLK (scratch)))]
1892   "TARGET_64BIT"
1893   "pop{q}\t%0"
1894   [(set_attr "type" "pop")
1895    (set_attr "mode" "DI")])
1897 (define_insn "popdi1"
1898   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1899         (mem:DI (reg:DI SP_REG)))
1900    (set (reg:DI SP_REG)
1901         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1902   "TARGET_64BIT"
1903   "pop{q}\t%0"
1904   [(set_attr "type" "pop")
1905    (set_attr "mode" "DI")])
1907 (define_insn "*movdi_xor_rex64"
1908   [(set (match_operand:DI 0 "register_operand" "=r")
1909         (match_operand:DI 1 "const0_operand" "i"))
1910    (clobber (reg:CC FLAGS_REG))]
1911   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1912    && reload_completed"
1913   "xor{l}\t{%k0, %k0|%k0, %k0}"
1914   [(set_attr "type" "alu1")
1915    (set_attr "mode" "SI")
1916    (set_attr "length_immediate" "0")])
1918 (define_insn "*movdi_or_rex64"
1919   [(set (match_operand:DI 0 "register_operand" "=r")
1920         (match_operand:DI 1 "const_int_operand" "i"))
1921    (clobber (reg:CC FLAGS_REG))]
1922   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1923    && reload_completed
1924    && operands[1] == constm1_rtx"
1926   operands[1] = constm1_rtx;
1927   return "or{q}\t{%1, %0|%0, %1}";
1929   [(set_attr "type" "alu1")
1930    (set_attr "mode" "DI")
1931    (set_attr "length_immediate" "1")])
1933 (define_insn "*movdi_2"
1934   [(set (match_operand:DI 0 "nonimmediate_operand"
1935                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1936         (match_operand:DI 1 "general_operand"
1937                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1938   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1939   "@
1940    #
1941    #
1942    pxor\t%0, %0
1943    movq\t{%1, %0|%0, %1}
1944    movq\t{%1, %0|%0, %1}
1945    pxor\t%0, %0
1946    movq\t{%1, %0|%0, %1}
1947    movdqa\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    xorps\t%0, %0
1950    movlps\t{%1, %0|%0, %1}
1951    movaps\t{%1, %0|%0, %1}
1952    movlps\t{%1, %0|%0, %1}"
1953   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1954    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1956 (define_split
1957   [(set (match_operand:DI 0 "push_operand" "")
1958         (match_operand:DI 1 "general_operand" ""))]
1959   "!TARGET_64BIT && reload_completed
1960    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1961   [(const_int 0)]
1962   "ix86_split_long_move (operands); DONE;")
1964 ;; %%% This multiword shite has got to go.
1965 (define_split
1966   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1967         (match_operand:DI 1 "general_operand" ""))]
1968   "!TARGET_64BIT && reload_completed
1969    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1970    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971   [(const_int 0)]
1972   "ix86_split_long_move (operands); DONE;")
1974 (define_insn "*movdi_1_rex64"
1975   [(set (match_operand:DI 0 "nonimmediate_operand"
1976                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1977         (match_operand:DI 1 "general_operand"
1978                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1979   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1981   switch (get_attr_type (insn))
1982     {
1983     case TYPE_SSECVT:
1984       if (which_alternative == 13)
1985         return "movq2dq\t{%1, %0|%0, %1}";
1986       else
1987         return "movdq2q\t{%1, %0|%0, %1}";
1988     case TYPE_SSEMOV:
1989       if (get_attr_mode (insn) == MODE_TI)
1990           return "movdqa\t{%1, %0|%0, %1}";
1991       /* FALLTHRU */
1992     case TYPE_MMXMOV:
1993       /* Moves from and into integer register is done using movd opcode with
1994          REX prefix.  */
1995       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996           return "movd\t{%1, %0|%0, %1}";
1997       return "movq\t{%1, %0|%0, %1}";
1998     case TYPE_SSELOG1:
1999     case TYPE_MMXADD:
2000       return "pxor\t%0, %0";
2001     case TYPE_MULTI:
2002       return "#";
2003     case TYPE_LEA:
2004       return "lea{q}\t{%a1, %0|%0, %a1}";
2005     default:
2006       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2007       if (get_attr_mode (insn) == MODE_SI)
2008         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2009       else if (which_alternative == 2)
2010         return "movabs{q}\t{%1, %0|%0, %1}";
2011       else
2012         return "mov{q}\t{%1, %0|%0, %1}";
2013     }
2015   [(set (attr "type")
2016      (cond [(eq_attr "alternative" "5")
2017               (const_string "mmxadd")
2018             (eq_attr "alternative" "6,7,8")
2019               (const_string "mmxmov")
2020             (eq_attr "alternative" "9")
2021               (const_string "sselog1")
2022             (eq_attr "alternative" "10,11,12")
2023               (const_string "ssemov")
2024             (eq_attr "alternative" "13,14")
2025               (const_string "ssecvt")
2026             (eq_attr "alternative" "4")
2027               (const_string "multi")
2028             (match_operand:DI 1 "pic_32bit_operand" "")
2029               (const_string "lea")
2030            ]
2031            (const_string "imov")))
2032    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2033    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2034    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2036 ;; Stores and loads of ax to arbitrary constant address.
2037 ;; We fake an second form of instruction to force reload to load address
2038 ;; into register when rax is not available
2039 (define_insn "*movabsdi_1_rex64"
2040   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2041         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2042   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2043   "@
2044    movabs{q}\t{%1, %P0|%P0, %1}
2045    mov{q}\t{%1, %a0|%a0, %1}"
2046   [(set_attr "type" "imov")
2047    (set_attr "modrm" "0,*")
2048    (set_attr "length_address" "8,0")
2049    (set_attr "length_immediate" "0,*")
2050    (set_attr "memory" "store")
2051    (set_attr "mode" "DI")])
2053 (define_insn "*movabsdi_2_rex64"
2054   [(set (match_operand:DI 0 "register_operand" "=a,r")
2055         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2056   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2057   "@
2058    movabs{q}\t{%P1, %0|%0, %P1}
2059    mov{q}\t{%a1, %0|%0, %a1}"
2060   [(set_attr "type" "imov")
2061    (set_attr "modrm" "0,*")
2062    (set_attr "length_address" "8,0")
2063    (set_attr "length_immediate" "0")
2064    (set_attr "memory" "load")
2065    (set_attr "mode" "DI")])
2067 ;; Convert impossible stores of immediate to existing instructions.
2068 ;; First try to get scratch register and go through it.  In case this
2069 ;; fails, move by 32bit parts.
2070 (define_peephole2
2071   [(match_scratch:DI 2 "r")
2072    (set (match_operand:DI 0 "memory_operand" "")
2073         (match_operand:DI 1 "immediate_operand" ""))]
2074   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075    && !x86_64_immediate_operand (operands[1], DImode)"
2076   [(set (match_dup 2) (match_dup 1))
2077    (set (match_dup 0) (match_dup 2))]
2078   "")
2080 ;; We need to define this as both peepholer and splitter for case
2081 ;; peephole2 pass is not run.
2082 ;; "&& 1" is needed to keep it from matching the previous pattern.
2083 (define_peephole2
2084   [(set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2088   [(set (match_dup 2) (match_dup 3))
2089    (set (match_dup 4) (match_dup 5))]
2090   "split_di (operands, 2, operands + 2, operands + 4);")
2092 (define_split
2093   [(set (match_operand:DI 0 "memory_operand" "")
2094         (match_operand:DI 1 "immediate_operand" ""))]
2095   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096                     ? flow2_completed : reload_completed)
2097    && !symbolic_operand (operands[1], DImode)
2098    && !x86_64_immediate_operand (operands[1], DImode)"
2099   [(set (match_dup 2) (match_dup 3))
2100    (set (match_dup 4) (match_dup 5))]
2101   "split_di (operands, 2, operands + 2, operands + 4);")
2103 (define_insn "*swapdi_rex64"
2104   [(set (match_operand:DI 0 "register_operand" "+r")
2105         (match_operand:DI 1 "register_operand" "+r"))
2106    (set (match_dup 1)
2107         (match_dup 0))]
2108   "TARGET_64BIT"
2109   "xchg{q}\t%1, %0"
2110   [(set_attr "type" "imov")
2111    (set_attr "mode" "DI")
2112    (set_attr "pent_pair" "np")
2113    (set_attr "athlon_decode" "vector")])
2115 (define_expand "movti"
2116   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2117         (match_operand:TI 1 "nonimmediate_operand" ""))]
2118   "TARGET_SSE || TARGET_64BIT"
2120   if (TARGET_64BIT)
2121     ix86_expand_move (TImode, operands);
2122   else
2123     ix86_expand_vector_move (TImode, operands);
2124   DONE;
2127 (define_insn "*movti_internal"
2128   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2129         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2130   "TARGET_SSE && !TARGET_64BIT
2131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2133   switch (which_alternative)
2134     {
2135     case 0:
2136       if (get_attr_mode (insn) == MODE_V4SF)
2137         return "xorps\t%0, %0";
2138       else
2139         return "pxor\t%0, %0";
2140     case 1:
2141     case 2:
2142       if (get_attr_mode (insn) == MODE_V4SF)
2143         return "movaps\t{%1, %0|%0, %1}";
2144       else
2145         return "movdqa\t{%1, %0|%0, %1}";
2146     default:
2147       gcc_unreachable ();
2148     }
2150   [(set_attr "type" "ssemov,ssemov,ssemov")
2151    (set (attr "mode")
2152         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2153                  (const_string "V4SF")
2155                (eq_attr "alternative" "0,1")
2156                  (if_then_else
2157                    (ne (symbol_ref "optimize_size")
2158                        (const_int 0))
2159                    (const_string "V4SF")
2160                    (const_string "TI"))
2161                (eq_attr "alternative" "2")
2162                  (if_then_else
2163                    (ne (symbol_ref "optimize_size")
2164                        (const_int 0))
2165                    (const_string "V4SF")
2166                    (const_string "TI"))]
2167                (const_string "TI")))])
2169 (define_insn "*movti_rex64"
2170   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2171         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2172   "TARGET_64BIT
2173    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175   switch (which_alternative)
2176     {
2177     case 0:
2178     case 1:
2179       return "#";
2180     case 2:
2181       if (get_attr_mode (insn) == MODE_V4SF)
2182         return "xorps\t%0, %0";
2183       else
2184         return "pxor\t%0, %0";
2185     case 3:
2186     case 4:
2187       if (get_attr_mode (insn) == MODE_V4SF)
2188         return "movaps\t{%1, %0|%0, %1}";
2189       else
2190         return "movdqa\t{%1, %0|%0, %1}";
2191     default:
2192       gcc_unreachable ();
2193     }
2195   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2196    (set (attr "mode")
2197         (cond [(eq_attr "alternative" "2,3")
2198                  (if_then_else
2199                    (ne (symbol_ref "optimize_size")
2200                        (const_int 0))
2201                    (const_string "V4SF")
2202                    (const_string "TI"))
2203                (eq_attr "alternative" "4")
2204                  (if_then_else
2205                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2206                             (const_int 0))
2207                         (ne (symbol_ref "optimize_size")
2208                             (const_int 0)))
2209                    (const_string "V4SF")
2210                    (const_string "TI"))]
2211                (const_string "DI")))])
2213 (define_split
2214   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2215         (match_operand:TI 1 "general_operand" ""))]
2216   "reload_completed && !SSE_REG_P (operands[0])
2217    && !SSE_REG_P (operands[1])"
2218   [(const_int 0)]
2219   "ix86_split_long_move (operands); DONE;")
2221 (define_expand "movsf"
2222   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2223         (match_operand:SF 1 "general_operand" ""))]
2224   ""
2225   "ix86_expand_move (SFmode, operands); DONE;")
2227 (define_insn "*pushsf"
2228   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2229         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2230   "!TARGET_64BIT"
2232   /* Anything else should be already split before reg-stack.  */
2233   gcc_assert (which_alternative == 1);
2234   return "push{l}\t%1";
2236   [(set_attr "type" "multi,push,multi")
2237    (set_attr "unit" "i387,*,*")
2238    (set_attr "mode" "SF,SI,SF")])
2240 (define_insn "*pushsf_rex64"
2241   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2242         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2243   "TARGET_64BIT"
2245   /* Anything else should be already split before reg-stack.  */
2246   gcc_assert (which_alternative == 1);
2247   return "push{q}\t%q1";
2249   [(set_attr "type" "multi,push,multi")
2250    (set_attr "unit" "i387,*,*")
2251    (set_attr "mode" "SF,DI,SF")])
2253 (define_split
2254   [(set (match_operand:SF 0 "push_operand" "")
2255         (match_operand:SF 1 "memory_operand" ""))]
2256   "reload_completed
2257    && GET_CODE (operands[1]) == MEM
2258    && constant_pool_reference_p (operands[1])"
2259   [(set (match_dup 0)
2260         (match_dup 1))]
2261   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2264 ;; %%% Kill this when call knows how to work this out.
2265 (define_split
2266   [(set (match_operand:SF 0 "push_operand" "")
2267         (match_operand:SF 1 "any_fp_register_operand" ""))]
2268   "!TARGET_64BIT"
2269   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2270    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2272 (define_split
2273   [(set (match_operand:SF 0 "push_operand" "")
2274         (match_operand:SF 1 "any_fp_register_operand" ""))]
2275   "TARGET_64BIT"
2276   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2277    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279 (define_insn "*movsf_1"
2280   [(set (match_operand:SF 0 "nonimmediate_operand"
2281           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2282         (match_operand:SF 1 "general_operand"
2283           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2284   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2285    && (reload_in_progress || reload_completed
2286        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2287        || GET_CODE (operands[1]) != CONST_DOUBLE
2288        || memory_operand (operands[0], SFmode))" 
2290   switch (which_alternative)
2291     {
2292     case 0:
2293       return output_387_reg_move (insn, operands);
2295     case 1:
2296       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297         return "fstp%z0\t%y0";
2298       else
2299         return "fst%z0\t%y0";
2301     case 2:
2302       return standard_80387_constant_opcode (operands[1]);
2304     case 3:
2305     case 4:
2306       return "mov{l}\t{%1, %0|%0, %1}";
2307     case 5:
2308       if (get_attr_mode (insn) == MODE_TI)
2309         return "pxor\t%0, %0";
2310       else
2311         return "xorps\t%0, %0";
2312     case 6:
2313       if (get_attr_mode (insn) == MODE_V4SF)
2314         return "movaps\t{%1, %0|%0, %1}";
2315       else
2316         return "movss\t{%1, %0|%0, %1}";
2317     case 7:
2318     case 8:
2319       return "movss\t{%1, %0|%0, %1}";
2321     case 9:
2322     case 10:
2323       return "movd\t{%1, %0|%0, %1}";
2325     case 11:
2326       return "movq\t{%1, %0|%0, %1}";
2328     default:
2329       gcc_unreachable ();
2330     }
2332   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2333    (set (attr "mode")
2334         (cond [(eq_attr "alternative" "3,4,9,10")
2335                  (const_string "SI")
2336                (eq_attr "alternative" "5")
2337                  (if_then_else
2338                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2339                                  (const_int 0))
2340                              (ne (symbol_ref "TARGET_SSE2")
2341                                  (const_int 0)))
2342                         (eq (symbol_ref "optimize_size")
2343                             (const_int 0)))
2344                    (const_string "TI")
2345                    (const_string "V4SF"))
2346                /* For architectures resolving dependencies on
2347                   whole SSE registers use APS move to break dependency
2348                   chains, otherwise use short move to avoid extra work. 
2350                   Do the same for architectures resolving dependencies on
2351                   the parts.  While in DF mode it is better to always handle
2352                   just register parts, the SF mode is different due to lack
2353                   of instructions to load just part of the register.  It is
2354                   better to maintain the whole registers in single format
2355                   to avoid problems on using packed logical operations.  */
2356                (eq_attr "alternative" "6")
2357                  (if_then_else
2358                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2359                             (const_int 0))
2360                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2361                             (const_int 0)))
2362                    (const_string "V4SF")
2363                    (const_string "SF"))
2364                (eq_attr "alternative" "11")
2365                  (const_string "DI")]
2366                (const_string "SF")))])
2368 (define_insn "*swapsf"
2369   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2370         (match_operand:SF 1 "fp_register_operand" "+f"))
2371    (set (match_dup 1)
2372         (match_dup 0))]
2373   "reload_completed || TARGET_80387"
2375   if (STACK_TOP_P (operands[0]))
2376     return "fxch\t%1";
2377   else
2378     return "fxch\t%0";
2380   [(set_attr "type" "fxch")
2381    (set_attr "mode" "SF")])
2383 (define_expand "movdf"
2384   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2385         (match_operand:DF 1 "general_operand" ""))]
2386   ""
2387   "ix86_expand_move (DFmode, operands); DONE;")
2389 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2390 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2391 ;; On the average, pushdf using integers can be still shorter.  Allow this
2392 ;; pattern for optimize_size too.
2394 (define_insn "*pushdf_nointeger"
2395   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2396         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2397   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399   /* This insn should be already split before reg-stack.  */
2400   gcc_unreachable ();
2402   [(set_attr "type" "multi")
2403    (set_attr "unit" "i387,*,*,*")
2404    (set_attr "mode" "DF,SI,SI,DF")])
2406 (define_insn "*pushdf_integer"
2407   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411   /* This insn should be already split before reg-stack.  */
2412   gcc_unreachable ();
2414   [(set_attr "type" "multi")
2415    (set_attr "unit" "i387,*,*")
2416    (set_attr "mode" "DF,SI,DF")])
2418 ;; %%% Kill this when call knows how to work this out.
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "!TARGET_64BIT && reload_completed"
2423   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2425   "")
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "any_fp_register_operand" ""))]
2430   "TARGET_64BIT && reload_completed"
2431   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2432    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2433   "")
2435 (define_split
2436   [(set (match_operand:DF 0 "push_operand" "")
2437         (match_operand:DF 1 "general_operand" ""))]
2438   "reload_completed"
2439   [(const_int 0)]
2440   "ix86_split_long_move (operands); DONE;")
2442 ;; Moving is usually shorter when only FP registers are used. This separate
2443 ;; movdf pattern avoids the use of integer registers for FP operations
2444 ;; when optimizing for size.
2446 (define_insn "*movdf_nointeger"
2447   [(set (match_operand:DF 0 "nonimmediate_operand"
2448                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2449         (match_operand:DF 1 "general_operand"
2450                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2451   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2452    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2453    && (reload_in_progress || reload_completed
2454        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2455        || GET_CODE (operands[1]) != CONST_DOUBLE
2456        || memory_operand (operands[0], DFmode))" 
2458   switch (which_alternative)
2459     {
2460     case 0:
2461       return output_387_reg_move (insn, operands);
2463     case 1:
2464       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2465         return "fstp%z0\t%y0";
2466       else
2467         return "fst%z0\t%y0";
2469     case 2:
2470       return standard_80387_constant_opcode (operands[1]);
2472     case 3:
2473     case 4:
2474       return "#";
2475     case 5:
2476       switch (get_attr_mode (insn))
2477         {
2478         case MODE_V4SF:
2479           return "xorps\t%0, %0";
2480         case MODE_V2DF:
2481           return "xorpd\t%0, %0";
2482         case MODE_TI:
2483           return "pxor\t%0, %0";
2484         default:
2485           gcc_unreachable ();
2486         }
2487     case 6:
2488     case 7:
2489     case 8:
2490       switch (get_attr_mode (insn))
2491         {
2492         case MODE_V4SF:
2493           return "movaps\t{%1, %0|%0, %1}";
2494         case MODE_V2DF:
2495           return "movapd\t{%1, %0|%0, %1}";
2496         case MODE_TI:
2497           return "movdqa\t{%1, %0|%0, %1}";
2498         case MODE_DI:
2499           return "movq\t{%1, %0|%0, %1}";
2500         case MODE_DF:
2501           return "movsd\t{%1, %0|%0, %1}";
2502         case MODE_V1DF:
2503           return "movlpd\t{%1, %0|%0, %1}";
2504         case MODE_V2SF:
2505           return "movlps\t{%1, %0|%0, %1}";
2506         default:
2507           gcc_unreachable ();
2508         }
2510     default:
2511       gcc_unreachable ();
2512     }
2514   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2515    (set (attr "mode")
2516         (cond [(eq_attr "alternative" "0,1,2")
2517                  (const_string "DF")
2518                (eq_attr "alternative" "3,4")
2519                  (const_string "SI")
2521                /* For SSE1, we have many fewer alternatives.  */
2522                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2523                  (cond [(eq_attr "alternative" "5,6")
2524                           (const_string "V4SF")
2525                        ]
2526                    (const_string "V2SF"))
2528                /* xorps is one byte shorter.  */
2529                (eq_attr "alternative" "5")
2530                  (cond [(ne (symbol_ref "optimize_size")
2531                             (const_int 0))
2532                           (const_string "V4SF")
2533                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2534                             (const_int 0))
2535                           (const_string "TI")
2536                        ]
2537                        (const_string "V2DF"))
2539                /* For architectures resolving dependencies on
2540                   whole SSE registers use APD move to break dependency
2541                   chains, otherwise use short move to avoid extra work.
2543                   movaps encodes one byte shorter.  */
2544                (eq_attr "alternative" "6")
2545                  (cond
2546                    [(ne (symbol_ref "optimize_size")
2547                         (const_int 0))
2548                       (const_string "V4SF")
2549                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2550                         (const_int 0))
2551                       (const_string "V2DF")
2552                    ]
2553                    (const_string "DF"))
2554                /* For architectures resolving dependencies on register
2555                   parts we may avoid extra work to zero out upper part
2556                   of register.  */
2557                (eq_attr "alternative" "7")
2558                  (if_then_else
2559                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2560                        (const_int 0))
2561                    (const_string "V1DF")
2562                    (const_string "DF"))
2563               ]
2564               (const_string "DF")))])
2566 (define_insn "*movdf_integer"
2567   [(set (match_operand:DF 0 "nonimmediate_operand"
2568                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2569         (match_operand:DF 1 "general_operand"
2570                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2571   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2572    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2573    && (reload_in_progress || reload_completed
2574        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2575        || GET_CODE (operands[1]) != CONST_DOUBLE
2576        || memory_operand (operands[0], DFmode))" 
2578   switch (which_alternative)
2579     {
2580     case 0:
2581       return output_387_reg_move (insn, operands);
2583     case 1:
2584       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2585         return "fstp%z0\t%y0";
2586       else
2587         return "fst%z0\t%y0";
2589     case 2:
2590       return standard_80387_constant_opcode (operands[1]);
2592     case 3:
2593     case 4:
2594       return "#";
2596     case 5:
2597       switch (get_attr_mode (insn))
2598         {
2599         case MODE_V4SF:
2600           return "xorps\t%0, %0";
2601         case MODE_V2DF:
2602           return "xorpd\t%0, %0";
2603         case MODE_TI:
2604           return "pxor\t%0, %0";
2605         default:
2606           gcc_unreachable ();
2607         }
2608     case 6:
2609     case 7:
2610     case 8:
2611       switch (get_attr_mode (insn))
2612         {
2613         case MODE_V4SF:
2614           return "movaps\t{%1, %0|%0, %1}";
2615         case MODE_V2DF:
2616           return "movapd\t{%1, %0|%0, %1}";
2617         case MODE_TI:
2618           return "movdqa\t{%1, %0|%0, %1}";
2619         case MODE_DI:
2620           return "movq\t{%1, %0|%0, %1}";
2621         case MODE_DF:
2622           return "movsd\t{%1, %0|%0, %1}";
2623         case MODE_V1DF:
2624           return "movlpd\t{%1, %0|%0, %1}";
2625         case MODE_V2SF:
2626           return "movlps\t{%1, %0|%0, %1}";
2627         default:
2628           gcc_unreachable ();
2629         }
2631     default:
2632       gcc_unreachable();
2633     }
2635   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2636    (set (attr "mode")
2637         (cond [(eq_attr "alternative" "0,1,2")
2638                  (const_string "DF")
2639                (eq_attr "alternative" "3,4")
2640                  (const_string "SI")
2642                /* For SSE1, we have many fewer alternatives.  */
2643                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2644                  (cond [(eq_attr "alternative" "5,6")
2645                           (const_string "V4SF")
2646                        ]
2647                    (const_string "V2SF"))
2649                /* xorps is one byte shorter.  */
2650                (eq_attr "alternative" "5")
2651                  (cond [(ne (symbol_ref "optimize_size")
2652                             (const_int 0))
2653                           (const_string "V4SF")
2654                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2655                             (const_int 0))
2656                           (const_string "TI")
2657                        ]
2658                        (const_string "V2DF"))
2660                /* For architectures resolving dependencies on
2661                   whole SSE registers use APD move to break dependency
2662                   chains, otherwise use short move to avoid extra work.
2664                   movaps encodes one byte shorter.  */
2665                (eq_attr "alternative" "6")
2666                  (cond
2667                    [(ne (symbol_ref "optimize_size")
2668                         (const_int 0))
2669                       (const_string "V4SF")
2670                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671                         (const_int 0))
2672                       (const_string "V2DF")
2673                    ]
2674                    (const_string "DF"))
2675                /* For architectures resolving dependencies on register
2676                   parts we may avoid extra work to zero out upper part
2677                   of register.  */
2678                (eq_attr "alternative" "7")
2679                  (if_then_else
2680                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2681                        (const_int 0))
2682                    (const_string "V1DF")
2683                    (const_string "DF"))
2684               ]
2685               (const_string "DF")))])
2687 (define_split
2688   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2689         (match_operand:DF 1 "general_operand" ""))]
2690   "reload_completed
2691    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2692    && ! (ANY_FP_REG_P (operands[0]) || 
2693          (GET_CODE (operands[0]) == SUBREG
2694           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2695    && ! (ANY_FP_REG_P (operands[1]) || 
2696          (GET_CODE (operands[1]) == SUBREG
2697           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2698   [(const_int 0)]
2699   "ix86_split_long_move (operands); DONE;")
2701 (define_insn "*swapdf"
2702   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2703         (match_operand:DF 1 "fp_register_operand" "+f"))
2704    (set (match_dup 1)
2705         (match_dup 0))]
2706   "reload_completed || TARGET_80387"
2708   if (STACK_TOP_P (operands[0]))
2709     return "fxch\t%1";
2710   else
2711     return "fxch\t%0";
2713   [(set_attr "type" "fxch")
2714    (set_attr "mode" "DF")])
2716 (define_expand "movxf"
2717   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2718         (match_operand:XF 1 "general_operand" ""))]
2719   ""
2720   "ix86_expand_move (XFmode, operands); DONE;")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2724 ;; Pushing using integer instructions is longer except for constants
2725 ;; and direct memory references.
2726 ;; (assuming that any given constant is pushed only once, but this ought to be
2727 ;;  handled elsewhere).
2729 (define_insn "*pushxf_nointeger"
2730   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2731         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2732   "optimize_size"
2734   /* This insn should be already split before reg-stack.  */
2735   gcc_unreachable ();
2737   [(set_attr "type" "multi")
2738    (set_attr "unit" "i387,*,*")
2739    (set_attr "mode" "XF,SI,SI")])
2741 (define_insn "*pushxf_integer"
2742   [(set (match_operand:XF 0 "push_operand" "=<,<")
2743         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2744   "!optimize_size"
2746   /* This insn should be already split before reg-stack.  */
2747   gcc_unreachable ();
2749   [(set_attr "type" "multi")
2750    (set_attr "unit" "i387,*")
2751    (set_attr "mode" "XF,SI")])
2753 (define_split
2754   [(set (match_operand 0 "push_operand" "")
2755         (match_operand 1 "general_operand" ""))]
2756   "reload_completed
2757    && (GET_MODE (operands[0]) == XFmode
2758        || GET_MODE (operands[0]) == DFmode)
2759    && !ANY_FP_REG_P (operands[1])"
2760   [(const_int 0)]
2761   "ix86_split_long_move (operands); DONE;")
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "!TARGET_64BIT"
2767   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2768    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771 (define_split
2772   [(set (match_operand:XF 0 "push_operand" "")
2773         (match_operand:XF 1 "any_fp_register_operand" ""))]
2774   "TARGET_64BIT"
2775   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2776    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2777   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779 ;; Do not use integer registers when optimizing for size
2780 (define_insn "*movxf_nointeger"
2781   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2782         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2783   "optimize_size
2784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2785    && (reload_in_progress || reload_completed
2786        || GET_CODE (operands[1]) != CONST_DOUBLE
2787        || memory_operand (operands[0], XFmode))" 
2789   switch (which_alternative)
2790     {
2791     case 0:
2792       return output_387_reg_move (insn, operands);
2794     case 1:
2795       /* There is no non-popping store to memory for XFmode.  So if
2796          we need one, follow the store with a load.  */
2797       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798         return "fstp%z0\t%y0\;fld%z0\t%y0";
2799       else
2800         return "fstp%z0\t%y0";
2802     case 2:
2803       return standard_80387_constant_opcode (operands[1]);
2805     case 3: case 4:
2806       return "#";
2807     default:
2808       gcc_unreachable ();
2809     }
2811   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2812    (set_attr "mode" "XF,XF,XF,SI,SI")])
2814 (define_insn "*movxf_integer"
2815   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2816         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2817   "!optimize_size
2818    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2819    && (reload_in_progress || reload_completed
2820        || GET_CODE (operands[1]) != CONST_DOUBLE
2821        || memory_operand (operands[0], XFmode))" 
2823   switch (which_alternative)
2824     {
2825     case 0:
2826       return output_387_reg_move (insn, operands);
2828     case 1:
2829       /* There is no non-popping store to memory for XFmode.  So if
2830          we need one, follow the store with a load.  */
2831       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2832         return "fstp%z0\t%y0\;fld%z0\t%y0";
2833       else
2834         return "fstp%z0\t%y0";
2836     case 2:
2837       return standard_80387_constant_opcode (operands[1]);
2839     case 3: case 4:
2840       return "#";
2842     default:
2843       gcc_unreachable ();
2844     }
2846   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2847    (set_attr "mode" "XF,XF,XF,SI,SI")])
2849 (define_split
2850   [(set (match_operand 0 "nonimmediate_operand" "")
2851         (match_operand 1 "general_operand" ""))]
2852   "reload_completed
2853    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854    && GET_MODE (operands[0]) == XFmode
2855    && ! (ANY_FP_REG_P (operands[0]) || 
2856          (GET_CODE (operands[0]) == SUBREG
2857           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2858    && ! (ANY_FP_REG_P (operands[1]) || 
2859          (GET_CODE (operands[1]) == SUBREG
2860           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2861   [(const_int 0)]
2862   "ix86_split_long_move (operands); DONE;")
2864 (define_split
2865   [(set (match_operand 0 "register_operand" "")
2866         (match_operand 1 "memory_operand" ""))]
2867   "reload_completed
2868    && GET_CODE (operands[1]) == MEM
2869    && (GET_MODE (operands[0]) == XFmode
2870        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2871    && constant_pool_reference_p (operands[1])"
2872   [(set (match_dup 0) (match_dup 1))]
2874   rtx c = avoid_constant_pool_reference (operands[1]);
2875   rtx r = operands[0];
2877   if (GET_CODE (r) == SUBREG)
2878     r = SUBREG_REG (r);
2880   if (SSE_REG_P (r))
2881     {
2882       if (!standard_sse_constant_p (c))
2883         FAIL;
2884     }
2885   else if (FP_REG_P (r))
2886     {
2887       if (!standard_80387_constant_p (c))
2888         FAIL;
2889     }
2890   else if (MMX_REG_P (r))
2891     FAIL;
2893   operands[1] = c;
2896 (define_insn "swapxf"
2897   [(set (match_operand:XF 0 "register_operand" "+f")
2898         (match_operand:XF 1 "register_operand" "+f"))
2899    (set (match_dup 1)
2900         (match_dup 0))]
2901   "TARGET_80387"
2903   if (STACK_TOP_P (operands[0]))
2904     return "fxch\t%1";
2905   else
2906     return "fxch\t%0";
2908   [(set_attr "type" "fxch")
2909    (set_attr "mode" "XF")])
2911 (define_expand "movtf"
2912   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2913         (match_operand:TF 1 "nonimmediate_operand" ""))]
2914   "TARGET_64BIT"
2916   ix86_expand_move (TFmode, operands);
2917   DONE;
2920 (define_insn "*movtf_internal"
2921   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2922         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2923   "TARGET_64BIT
2924    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926   switch (which_alternative)
2927     {
2928     case 0:
2929     case 1:
2930       return "#";
2931     case 2:
2932       if (get_attr_mode (insn) == MODE_V4SF)
2933         return "xorps\t%0, %0";
2934       else
2935         return "pxor\t%0, %0";
2936     case 3:
2937     case 4:
2938       if (get_attr_mode (insn) == MODE_V4SF)
2939         return "movaps\t{%1, %0|%0, %1}";
2940       else
2941         return "movdqa\t{%1, %0|%0, %1}";
2942     default:
2943       gcc_unreachable ();
2944     }
2946   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2947    (set (attr "mode")
2948         (cond [(eq_attr "alternative" "2,3")
2949                  (if_then_else
2950                    (ne (symbol_ref "optimize_size")
2951                        (const_int 0))
2952                    (const_string "V4SF")
2953                    (const_string "TI"))
2954                (eq_attr "alternative" "4")
2955                  (if_then_else
2956                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2957                             (const_int 0))
2958                         (ne (symbol_ref "optimize_size")
2959                             (const_int 0)))
2960                    (const_string "V4SF")
2961                    (const_string "TI"))]
2962                (const_string "DI")))])
2964 (define_split
2965   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2966         (match_operand:TF 1 "general_operand" ""))]
2967   "reload_completed && !SSE_REG_P (operands[0])
2968    && !SSE_REG_P (operands[1])"
2969   [(const_int 0)]
2970   "ix86_split_long_move (operands); DONE;")
2972 ;; Zero extension instructions
2974 (define_expand "zero_extendhisi2"
2975   [(set (match_operand:SI 0 "register_operand" "")
2976      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2977   ""
2979   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2980     {
2981       operands[1] = force_reg (HImode, operands[1]);
2982       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983       DONE;
2984     }
2987 (define_insn "zero_extendhisi2_and"
2988   [(set (match_operand:SI 0 "register_operand" "=r")
2989      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2990    (clobber (reg:CC FLAGS_REG))]
2991   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992   "#"
2993   [(set_attr "type" "alu1")
2994    (set_attr "mode" "SI")])
2996 (define_split
2997   [(set (match_operand:SI 0 "register_operand" "")
2998         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2999    (clobber (reg:CC FLAGS_REG))]
3000   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3001   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3002               (clobber (reg:CC FLAGS_REG))])]
3003   "")
3005 (define_insn "*zero_extendhisi2_movzwl"
3006   [(set (match_operand:SI 0 "register_operand" "=r")
3007      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3008   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3009   "movz{wl|x}\t{%1, %0|%0, %1}"
3010   [(set_attr "type" "imovx")
3011    (set_attr "mode" "SI")])
3013 (define_expand "zero_extendqihi2"
3014   [(parallel
3015     [(set (match_operand:HI 0 "register_operand" "")
3016        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3017      (clobber (reg:CC FLAGS_REG))])]
3018   ""
3019   "")
3021 (define_insn "*zero_extendqihi2_and"
3022   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3023      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3024    (clobber (reg:CC FLAGS_REG))]
3025   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3026   "#"
3027   [(set_attr "type" "alu1")
3028    (set_attr "mode" "HI")])
3030 (define_insn "*zero_extendqihi2_movzbw_and"
3031   [(set (match_operand:HI 0 "register_operand" "=r,r")
3032      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3033    (clobber (reg:CC FLAGS_REG))]
3034   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035   "#"
3036   [(set_attr "type" "imovx,alu1")
3037    (set_attr "mode" "HI")])
3039 ; zero extend to SImode here to avoid partial register stalls
3040 (define_insn "*zero_extendqihi2_movzbl"
3041   [(set (match_operand:HI 0 "register_operand" "=r")
3042      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3043   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3044   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3045   [(set_attr "type" "imovx")
3046    (set_attr "mode" "SI")])
3048 ;; For the movzbw case strip only the clobber
3049 (define_split
3050   [(set (match_operand:HI 0 "register_operand" "")
3051         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3052    (clobber (reg:CC FLAGS_REG))]
3053   "reload_completed 
3054    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3055    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3056   [(set (match_operand:HI 0 "register_operand" "")
3057         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3059 ;; When source and destination does not overlap, clear destination
3060 ;; first and then do the movb
3061 (define_split
3062   [(set (match_operand:HI 0 "register_operand" "")
3063         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3064    (clobber (reg:CC FLAGS_REG))]
3065   "reload_completed
3066    && ANY_QI_REG_P (operands[0])
3067    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3068    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3069   [(set (match_dup 0) (const_int 0))
3070    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3071   "operands[2] = gen_lowpart (QImode, operands[0]);")
3073 ;; Rest is handled by single and.
3074 (define_split
3075   [(set (match_operand:HI 0 "register_operand" "")
3076         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3077    (clobber (reg:CC FLAGS_REG))]
3078   "reload_completed
3079    && true_regnum (operands[0]) == true_regnum (operands[1])"
3080   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3081               (clobber (reg:CC FLAGS_REG))])]
3082   "")
3084 (define_expand "zero_extendqisi2"
3085   [(parallel
3086     [(set (match_operand:SI 0 "register_operand" "")
3087        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3088      (clobber (reg:CC FLAGS_REG))])]
3089   ""
3090   "")
3092 (define_insn "*zero_extendqisi2_and"
3093   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3097   "#"
3098   [(set_attr "type" "alu1")
3099    (set_attr "mode" "SI")])
3101 (define_insn "*zero_extendqisi2_movzbw_and"
3102   [(set (match_operand:SI 0 "register_operand" "=r,r")
3103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3104    (clobber (reg:CC FLAGS_REG))]
3105   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3106   "#"
3107   [(set_attr "type" "imovx,alu1")
3108    (set_attr "mode" "SI")])
3110 (define_insn "*zero_extendqisi2_movzbw"
3111   [(set (match_operand:SI 0 "register_operand" "=r")
3112      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3113   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3114   "movz{bl|x}\t{%1, %0|%0, %1}"
3115   [(set_attr "type" "imovx")
3116    (set_attr "mode" "SI")])
3118 ;; For the movzbl case strip only the clobber
3119 (define_split
3120   [(set (match_operand:SI 0 "register_operand" "")
3121         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3122    (clobber (reg:CC FLAGS_REG))]
3123   "reload_completed 
3124    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3125    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3126   [(set (match_dup 0)
3127         (zero_extend:SI (match_dup 1)))])
3129 ;; When source and destination does not overlap, clear destination
3130 ;; first and then do the movb
3131 (define_split
3132   [(set (match_operand:SI 0 "register_operand" "")
3133         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3134    (clobber (reg:CC FLAGS_REG))]
3135   "reload_completed
3136    && ANY_QI_REG_P (operands[0])
3137    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3138    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3139    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3140   [(set (match_dup 0) (const_int 0))
3141    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3142   "operands[2] = gen_lowpart (QImode, operands[0]);")
3144 ;; Rest is handled by single and.
3145 (define_split
3146   [(set (match_operand:SI 0 "register_operand" "")
3147         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3148    (clobber (reg:CC FLAGS_REG))]
3149   "reload_completed
3150    && true_regnum (operands[0]) == true_regnum (operands[1])"
3151   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3152               (clobber (reg:CC FLAGS_REG))])]
3153   "")
3155 ;; %%% Kill me once multi-word ops are sane.
3156 (define_expand "zero_extendsidi2"
3157   [(set (match_operand:DI 0 "register_operand" "=r")
3158      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3159   ""
3160   "if (!TARGET_64BIT)
3161      {
3162        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3163        DONE;
3164      }
3165   ")
3167 (define_insn "zero_extendsidi2_32"
3168   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3169         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3170    (clobber (reg:CC FLAGS_REG))]
3171   "!TARGET_64BIT"
3172   "@
3173    #
3174    #
3175    #
3176    movd\t{%1, %0|%0, %1}
3177    movd\t{%1, %0|%0, %1}"
3178   [(set_attr "mode" "SI,SI,SI,DI,TI")
3179    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3181 (define_insn "zero_extendsidi2_rex64"
3182   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3183      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3184   "TARGET_64BIT"
3185   "@
3186    mov\t{%k1, %k0|%k0, %k1}
3187    #
3188    movd\t{%1, %0|%0, %1}
3189    movd\t{%1, %0|%0, %1}"
3190   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3191    (set_attr "mode" "SI,DI,SI,SI")])
3193 (define_split
3194   [(set (match_operand:DI 0 "memory_operand" "")
3195      (zero_extend:DI (match_dup 0)))]
3196   "TARGET_64BIT"
3197   [(set (match_dup 4) (const_int 0))]
3198   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200 (define_split 
3201   [(set (match_operand:DI 0 "register_operand" "")
3202         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT && reload_completed
3205    && true_regnum (operands[0]) == true_regnum (operands[1])"
3206   [(set (match_dup 4) (const_int 0))]
3207   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209 (define_split 
3210   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3211         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3212    (clobber (reg:CC FLAGS_REG))]
3213   "!TARGET_64BIT && reload_completed
3214    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3215   [(set (match_dup 3) (match_dup 1))
3216    (set (match_dup 4) (const_int 0))]
3217   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3219 (define_insn "zero_extendhidi2"
3220   [(set (match_operand:DI 0 "register_operand" "=r")
3221      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3222   "TARGET_64BIT"
3223   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "DI")])
3227 (define_insn "zero_extendqidi2"
3228   [(set (match_operand:DI 0 "register_operand" "=r")
3229      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3230   "TARGET_64BIT"
3231   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3232   [(set_attr "type" "imovx")
3233    (set_attr "mode" "DI")])
3235 ;; Sign extension instructions
3237 (define_expand "extendsidi2"
3238   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3239                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3240               (clobber (reg:CC FLAGS_REG))
3241               (clobber (match_scratch:SI 2 ""))])]
3242   ""
3244   if (TARGET_64BIT)
3245     {
3246       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3247       DONE;
3248     }
3251 (define_insn "*extendsidi2_1"
3252   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3253         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3254    (clobber (reg:CC FLAGS_REG))
3255    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3256   "!TARGET_64BIT"
3257   "#")
3259 (define_insn "extendsidi2_rex64"
3260   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3261         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3262   "TARGET_64BIT"
3263   "@
3264    {cltq|cdqe}
3265    movs{lq|x}\t{%1,%0|%0, %1}"
3266   [(set_attr "type" "imovx")
3267    (set_attr "mode" "DI")
3268    (set_attr "prefix_0f" "0")
3269    (set_attr "modrm" "0,1")])
3271 (define_insn "extendhidi2"
3272   [(set (match_operand:DI 0 "register_operand" "=r")
3273         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3274   "TARGET_64BIT"
3275   "movs{wq|x}\t{%1,%0|%0, %1}"
3276   [(set_attr "type" "imovx")
3277    (set_attr "mode" "DI")])
3279 (define_insn "extendqidi2"
3280   [(set (match_operand:DI 0 "register_operand" "=r")
3281         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3282   "TARGET_64BIT"
3283   "movs{bq|x}\t{%1,%0|%0, %1}"
3284    [(set_attr "type" "imovx")
3285     (set_attr "mode" "DI")])
3287 ;; Extend to memory case when source register does die.
3288 (define_split 
3289   [(set (match_operand:DI 0 "memory_operand" "")
3290         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3291    (clobber (reg:CC FLAGS_REG))
3292    (clobber (match_operand:SI 2 "register_operand" ""))]
3293   "(reload_completed
3294     && dead_or_set_p (insn, operands[1])
3295     && !reg_mentioned_p (operands[1], operands[0]))"
3296   [(set (match_dup 3) (match_dup 1))
3297    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3298               (clobber (reg:CC FLAGS_REG))])
3299    (set (match_dup 4) (match_dup 1))]
3300   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302 ;; Extend to memory case when source register does not die.
3303 (define_split 
3304   [(set (match_operand:DI 0 "memory_operand" "")
3305         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3306    (clobber (reg:CC FLAGS_REG))
3307    (clobber (match_operand:SI 2 "register_operand" ""))]
3308   "reload_completed"
3309   [(const_int 0)]
3311   split_di (&operands[0], 1, &operands[3], &operands[4]);
3313   emit_move_insn (operands[3], operands[1]);
3315   /* Generate a cltd if possible and doing so it profitable.  */
3316   if (true_regnum (operands[1]) == 0
3317       && true_regnum (operands[2]) == 1
3318       && (optimize_size || TARGET_USE_CLTD))
3319     {
3320       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3321     }
3322   else
3323     {
3324       emit_move_insn (operands[2], operands[1]);
3325       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3326     }
3327   emit_move_insn (operands[4], operands[2]);
3328   DONE;
3331 ;; Extend to register case.  Optimize case where source and destination
3332 ;; registers match and cases where we can use cltd.
3333 (define_split 
3334   [(set (match_operand:DI 0 "register_operand" "")
3335         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3336    (clobber (reg:CC FLAGS_REG))
3337    (clobber (match_scratch:SI 2 ""))]
3338   "reload_completed"
3339   [(const_int 0)]
3341   split_di (&operands[0], 1, &operands[3], &operands[4]);
3343   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3344     emit_move_insn (operands[3], operands[1]);
3346   /* Generate a cltd if possible and doing so it profitable.  */
3347   if (true_regnum (operands[3]) == 0
3348       && (optimize_size || TARGET_USE_CLTD))
3349     {
3350       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3351       DONE;
3352     }
3354   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3355     emit_move_insn (operands[4], operands[1]);
3357   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3358   DONE;
3361 (define_insn "extendhisi2"
3362   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3363         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3364   ""
3366   switch (get_attr_prefix_0f (insn))
3367     {
3368     case 0:
3369       return "{cwtl|cwde}";
3370     default:
3371       return "movs{wl|x}\t{%1,%0|%0, %1}";
3372     }
3374   [(set_attr "type" "imovx")
3375    (set_attr "mode" "SI")
3376    (set (attr "prefix_0f")
3377      ;; movsx is short decodable while cwtl is vector decoded.
3378      (if_then_else (and (eq_attr "cpu" "!k6")
3379                         (eq_attr "alternative" "0"))
3380         (const_string "0")
3381         (const_string "1")))
3382    (set (attr "modrm")
3383      (if_then_else (eq_attr "prefix_0f" "0")
3384         (const_string "0")
3385         (const_string "1")))])
3387 (define_insn "*extendhisi2_zext"
3388   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3389         (zero_extend:DI
3390           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3391   "TARGET_64BIT"
3393   switch (get_attr_prefix_0f (insn))
3394     {
3395     case 0:
3396       return "{cwtl|cwde}";
3397     default:
3398       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3399     }
3401   [(set_attr "type" "imovx")
3402    (set_attr "mode" "SI")
3403    (set (attr "prefix_0f")
3404      ;; movsx is short decodable while cwtl is vector decoded.
3405      (if_then_else (and (eq_attr "cpu" "!k6")
3406                         (eq_attr "alternative" "0"))
3407         (const_string "0")
3408         (const_string "1")))
3409    (set (attr "modrm")
3410      (if_then_else (eq_attr "prefix_0f" "0")
3411         (const_string "0")
3412         (const_string "1")))])
3414 (define_insn "extendqihi2"
3415   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3416         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3417   ""
3419   switch (get_attr_prefix_0f (insn))
3420     {
3421     case 0:
3422       return "{cbtw|cbw}";
3423     default:
3424       return "movs{bw|x}\t{%1,%0|%0, %1}";
3425     }
3427   [(set_attr "type" "imovx")
3428    (set_attr "mode" "HI")
3429    (set (attr "prefix_0f")
3430      ;; movsx is short decodable while cwtl is vector decoded.
3431      (if_then_else (and (eq_attr "cpu" "!k6")
3432                         (eq_attr "alternative" "0"))
3433         (const_string "0")
3434         (const_string "1")))
3435    (set (attr "modrm")
3436      (if_then_else (eq_attr "prefix_0f" "0")
3437         (const_string "0")
3438         (const_string "1")))])
3440 (define_insn "extendqisi2"
3441   [(set (match_operand:SI 0 "register_operand" "=r")
3442         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3443   ""
3444   "movs{bl|x}\t{%1,%0|%0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3448 (define_insn "*extendqisi2_zext"
3449   [(set (match_operand:DI 0 "register_operand" "=r")
3450         (zero_extend:DI
3451           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3452   "TARGET_64BIT"
3453   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3454    [(set_attr "type" "imovx")
3455     (set_attr "mode" "SI")])
3457 ;; Conversions between float and double.
3459 ;; These are all no-ops in the model used for the 80387.  So just
3460 ;; emit moves.
3462 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3463 (define_insn "*dummy_extendsfdf2"
3464   [(set (match_operand:DF 0 "push_operand" "=<")
3465         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3466   "0"
3467   "#")
3469 (define_split
3470   [(set (match_operand:DF 0 "push_operand" "")
3471         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3472   "!TARGET_64BIT"
3473   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3474    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3476 (define_split
3477   [(set (match_operand:DF 0 "push_operand" "")
3478         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3479   "TARGET_64BIT"
3480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3481    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3483 (define_insn "*dummy_extendsfxf2"
3484   [(set (match_operand:XF 0 "push_operand" "=<")
3485         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3486   "0"
3487   "#")
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492   ""
3493   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3494    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497 (define_split
3498   [(set (match_operand:XF 0 "push_operand" "")
3499         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3500   "TARGET_64BIT"
3501   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3502    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3503   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505 (define_split
3506   [(set (match_operand:XF 0 "push_operand" "")
3507         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508   ""
3509   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3510    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3511   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513 (define_split
3514   [(set (match_operand:XF 0 "push_operand" "")
3515         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3516   "TARGET_64BIT"
3517   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3518    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3519   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521 (define_expand "extendsfdf2"
3522   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3523         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3524   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526   /* ??? Needed for compress_float_constant since all fp constants
3527      are LEGITIMATE_CONSTANT_P.  */
3528   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3529     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3530   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3531     operands[1] = force_reg (SFmode, operands[1]);
3534 (define_insn "*extendsfdf2_mixed"
3535   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3536         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3537   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3538    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3540   switch (which_alternative)
3541     {
3542     case 0:
3543       return output_387_reg_move (insn, operands);
3545     case 1:
3546       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3547         return "fstp%z0\t%y0";
3548       else
3549         return "fst%z0\t%y0";
3551     case 2:
3552       return "cvtss2sd\t{%1, %0|%0, %1}";
3554     default:
3555       gcc_unreachable ();
3556     }
3558   [(set_attr "type" "fmov,fmov,ssecvt")
3559    (set_attr "mode" "SF,XF,DF")])
3561 (define_insn "*extendsfdf2_sse"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3564   "TARGET_SSE2 && TARGET_SSE_MATH
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3566   "cvtss2sd\t{%1, %0|%0, %1}"
3567   [(set_attr "type" "ssecvt")
3568    (set_attr "mode" "DF")])
3570 (define_insn "*extendsfdf2_i387"
3571   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3572         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3573   "TARGET_80387
3574    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3576   switch (which_alternative)
3577     {
3578     case 0:
3579       return output_387_reg_move (insn, operands);
3581     case 1:
3582       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3583         return "fstp%z0\t%y0";
3584       else
3585         return "fst%z0\t%y0";
3587     default:
3588       gcc_unreachable ();
3589     }
3591   [(set_attr "type" "fmov")
3592    (set_attr "mode" "SF,XF")])
3594 (define_expand "extendsfxf2"
3595   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3596         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3597   "TARGET_80387"
3599   /* ??? Needed for compress_float_constant since all fp constants
3600      are LEGITIMATE_CONSTANT_P.  */
3601   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3602     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3603   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3604     operands[1] = force_reg (SFmode, operands[1]);
3607 (define_insn "*extendsfxf2_i387"
3608   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3609         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3610   "TARGET_80387
3611    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3613   switch (which_alternative)
3614     {
3615     case 0:
3616       return output_387_reg_move (insn, operands);
3618     case 1:
3619       /* There is no non-popping store to memory for XFmode.  So if
3620          we need one, follow the store with a load.  */
3621       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622         return "fstp%z0\t%y0";
3623       else
3624         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3626     default:
3627       gcc_unreachable ();
3628     }
3630   [(set_attr "type" "fmov")
3631    (set_attr "mode" "SF,XF")])
3633 (define_expand "extenddfxf2"
3634   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3635         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3636   "TARGET_80387"
3638   /* ??? Needed for compress_float_constant since all fp constants
3639      are LEGITIMATE_CONSTANT_P.  */
3640   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3641     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3642   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3643     operands[1] = force_reg (DFmode, operands[1]);
3646 (define_insn "*extenddfxf2_i387"
3647   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3648         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3649   "TARGET_80387
3650    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3652   switch (which_alternative)
3653     {
3654     case 0:
3655       return output_387_reg_move (insn, operands);
3657     case 1:
3658       /* There is no non-popping store to memory for XFmode.  So if
3659          we need one, follow the store with a load.  */
3660       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3661         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3662       else
3663         return "fstp%z0\t%y0";
3665     default:
3666       gcc_unreachable ();
3667     }
3669   [(set_attr "type" "fmov")
3670    (set_attr "mode" "DF,XF")])
3672 ;; %%% This seems bad bad news.
3673 ;; This cannot output into an f-reg because there is no way to be sure
3674 ;; of truncating in that case.  Otherwise this is just like a simple move
3675 ;; insn.  So we pretend we can output to a reg in order to get better
3676 ;; register preferencing, but we really use a stack slot.
3678 ;; Conversion from DFmode to SFmode.
3680 (define_expand "truncdfsf2"
3681   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3682         (float_truncate:SF
3683           (match_operand:DF 1 "nonimmediate_operand" "")))]
3684   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3686   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3687     operands[1] = force_reg (DFmode, operands[1]);
3689   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3690     ;
3691   else if (flag_unsafe_math_optimizations)
3692     ;
3693   else
3694     {
3695       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3696       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3697       DONE;
3698     }
3701 (define_expand "truncdfsf2_with_temp"
3702   [(parallel [(set (match_operand:SF 0 "" "")
3703                    (float_truncate:SF (match_operand:DF 1 "" "")))
3704               (clobber (match_operand:SF 2 "" ""))])]
3705   "")
3707 (define_insn "*truncdfsf_fast_mixed"
3708   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3709         (float_truncate:SF
3710           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3711   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3713   switch (which_alternative)
3714     {
3715     case 0:
3716       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3717         return "fstp%z0\t%y0";
3718       else
3719         return "fst%z0\t%y0";
3720     case 1:
3721       return output_387_reg_move (insn, operands);
3722     case 2:
3723       return "cvtsd2ss\t{%1, %0|%0, %1}";
3724     default:
3725       gcc_unreachable ();
3726     }
3728   [(set_attr "type" "fmov,fmov,ssecvt")
3729    (set_attr "mode" "SF")])
3731 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3732 ;; because nothing we do here is unsafe.
3733 (define_insn "*truncdfsf_fast_sse"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3737   "TARGET_SSE2 && TARGET_SSE_MATH"
3738   "cvtsd2ss\t{%1, %0|%0, %1}"
3739   [(set_attr "type" "ssecvt")
3740    (set_attr "mode" "SF")])
3742 (define_insn "*truncdfsf_fast_i387"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3746   "TARGET_80387 && flag_unsafe_math_optimizations"
3747   "* return output_387_reg_move (insn, operands);"
3748   [(set_attr "type" "fmov")
3749    (set_attr "mode" "SF")])
3751 (define_insn "*truncdfsf_mixed"
3752   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3753         (float_truncate:SF
3754           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3755    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3756   "TARGET_MIX_SSE_I387"
3758   switch (which_alternative)
3759     {
3760     case 0:
3761       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762         return "fstp%z0\t%y0";
3763       else
3764         return "fst%z0\t%y0";
3765     case 1:
3766       return "#";
3767     case 2:
3768       return "cvtsd2ss\t{%1, %0|%0, %1}";
3769     default:
3770       gcc_unreachable ();
3771     }
3773   [(set_attr "type" "fmov,multi,ssecvt")
3774    (set_attr "unit" "*,i387,*")
3775    (set_attr "mode" "SF")])
3777 (define_insn "*truncdfsf_i387"
3778   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3779         (float_truncate:SF
3780           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3781    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3782   "TARGET_80387"
3784   switch (which_alternative)
3785     {
3786     case 0:
3787       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3788         return "fstp%z0\t%y0";
3789       else
3790         return "fst%z0\t%y0";
3791     case 1:
3792       return "#";
3793     default:
3794       gcc_unreachable ();
3795     }
3797   [(set_attr "type" "fmov,multi")
3798    (set_attr "unit" "*,i387")
3799    (set_attr "mode" "SF")])
3801 (define_insn "*truncdfsf2_i387_1"
3802   [(set (match_operand:SF 0 "memory_operand" "=m")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "register_operand" "f")))]
3805   "TARGET_80387
3806    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3807    && !TARGET_MIX_SSE_I387"
3809   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3810     return "fstp%z0\t%y0";
3811   else
3812     return "fst%z0\t%y0";
3814   [(set_attr "type" "fmov")
3815    (set_attr "mode" "SF")])
3817 (define_split
3818   [(set (match_operand:SF 0 "register_operand" "")
3819         (float_truncate:SF
3820          (match_operand:DF 1 "fp_register_operand" "")))
3821    (clobber (match_operand 2 "" ""))]
3822   "reload_completed"
3823   [(set (match_dup 2) (match_dup 1))
3824    (set (match_dup 0) (match_dup 2))]
3826   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3829 ;; Conversion from XFmode to SFmode.
3831 (define_expand "truncxfsf2"
3832   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3833                    (float_truncate:SF
3834                     (match_operand:XF 1 "register_operand" "")))
3835               (clobber (match_dup 2))])]
3836   "TARGET_80387"
3838   if (flag_unsafe_math_optimizations)
3839     {
3840       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3841       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3842       if (reg != operands[0])
3843         emit_move_insn (operands[0], reg);
3844       DONE;
3845     }
3846   else
3847     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3850 (define_insn "*truncxfsf2_mixed"
3851   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3852         (float_truncate:SF
3853          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3854    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3855   "TARGET_MIX_SSE_I387"
3857   gcc_assert (!which_alternative);
3858   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3859     return "fstp%z0\t%y0";
3860   else
3861     return "fst%z0\t%y0";
3863   [(set_attr "type" "fmov,multi,multi,multi")
3864    (set_attr "unit" "*,i387,i387,i387")
3865    (set_attr "mode" "SF")])
3867 (define_insn "truncxfsf2_i387_noop"
3868   [(set (match_operand:SF 0 "register_operand" "=f")
3869         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3870   "TARGET_80387 && flag_unsafe_math_optimizations"
3872   return output_387_reg_move (insn, operands);
3874   [(set_attr "type" "fmov")
3875    (set_attr "mode" "SF")])
3877 (define_insn "*truncxfsf2_i387"
3878   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3879         (float_truncate:SF
3880          (match_operand:XF 1 "register_operand" "f,f,f")))
3881    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3882   "TARGET_80387"
3884   gcc_assert (!which_alternative);
3885   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3886     return "fstp%z0\t%y0";
3887    else
3888      return "fst%z0\t%y0";
3890   [(set_attr "type" "fmov,multi,multi")
3891    (set_attr "unit" "*,i387,i387")
3892    (set_attr "mode" "SF")])
3894 (define_insn "*truncxfsf2_i387_1"
3895   [(set (match_operand:SF 0 "memory_operand" "=m")
3896         (float_truncate:SF
3897          (match_operand:XF 1 "register_operand" "f")))]
3898   "TARGET_80387"
3900   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3901     return "fstp%z0\t%y0";
3902   else
3903     return "fst%z0\t%y0";
3905   [(set_attr "type" "fmov")
3906    (set_attr "mode" "SF")])
3908 (define_split
3909   [(set (match_operand:SF 0 "register_operand" "")
3910         (float_truncate:SF
3911          (match_operand:XF 1 "register_operand" "")))
3912    (clobber (match_operand:SF 2 "memory_operand" ""))]
3913   "TARGET_80387 && reload_completed"
3914   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3915    (set (match_dup 0) (match_dup 2))]
3916   "")
3918 (define_split
3919   [(set (match_operand:SF 0 "memory_operand" "")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "")))
3922    (clobber (match_operand:SF 2 "memory_operand" ""))]
3923   "TARGET_80387"
3924   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3925   "")
3927 ;; Conversion from XFmode to DFmode.
3929 (define_expand "truncxfdf2"
3930   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3931                    (float_truncate:DF
3932                     (match_operand:XF 1 "register_operand" "")))
3933               (clobber (match_dup 2))])]
3934   "TARGET_80387"
3936   if (flag_unsafe_math_optimizations)
3937     {
3938       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3939       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3940       if (reg != operands[0])
3941         emit_move_insn (operands[0], reg);
3942       DONE;
3943     }
3944   else
3945     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3948 (define_insn "*truncxfdf2_mixed"
3949   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3950         (float_truncate:DF
3951          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3952    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3953   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3955   gcc_assert (!which_alternative);
3956   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3957     return "fstp%z0\t%y0";
3958   else
3959     return "fst%z0\t%y0";
3961   [(set_attr "type" "fmov,multi,multi,multi")
3962    (set_attr "unit" "*,i387,i387,i387")
3963    (set_attr "mode" "DF")])
3965 (define_insn "truncxfdf2_i387_noop"
3966   [(set (match_operand:DF 0 "register_operand" "=f")
3967         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3968   "TARGET_80387 && flag_unsafe_math_optimizations"
3970   return output_387_reg_move (insn, operands);
3972   [(set_attr "type" "fmov")
3973    (set_attr "mode" "DF")])
3975 (define_insn "*truncxfdf2_i387"
3976   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3977         (float_truncate:DF
3978          (match_operand:XF 1 "register_operand" "f,f,f")))
3979    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3980   "TARGET_80387"
3982   gcc_assert (!which_alternative);
3983   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3984     return "fstp%z0\t%y0";
3985   else
3986     return "fst%z0\t%y0";
3988   [(set_attr "type" "fmov,multi,multi")
3989    (set_attr "unit" "*,i387,i387")
3990    (set_attr "mode" "DF")])
3992 (define_insn "*truncxfdf2_i387_1"
3993   [(set (match_operand:DF 0 "memory_operand" "=m")
3994         (float_truncate:DF
3995           (match_operand:XF 1 "register_operand" "f")))]
3996   "TARGET_80387"
3998   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3999     return "fstp%z0\t%y0";
4000   else
4001     return "fst%z0\t%y0";
4003   [(set_attr "type" "fmov")
4004    (set_attr "mode" "DF")])
4006 (define_split
4007   [(set (match_operand:DF 0 "register_operand" "")
4008         (float_truncate:DF
4009          (match_operand:XF 1 "register_operand" "")))
4010    (clobber (match_operand:DF 2 "memory_operand" ""))]
4011   "TARGET_80387 && reload_completed"
4012   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4013    (set (match_dup 0) (match_dup 2))]
4014   "")
4016 (define_split
4017   [(set (match_operand:DF 0 "memory_operand" "")
4018         (float_truncate:DF
4019          (match_operand:XF 1 "register_operand" "")))
4020    (clobber (match_operand:DF 2 "memory_operand" ""))]
4021   "TARGET_80387"
4022   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4023   "")
4025 ;; Signed conversion to DImode.
4027 (define_expand "fix_truncxfdi2"
4028   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4029                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4030               (clobber (reg:CC FLAGS_REG))])]
4031   "TARGET_80387"
4033   if (TARGET_FISTTP)
4034    {
4035      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4036      DONE;
4037    }
4040 (define_expand "fix_trunc<mode>di2"
4041   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4042                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4043               (clobber (reg:CC FLAGS_REG))])]
4044   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4046   if (TARGET_FISTTP
4047       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4048    {
4049      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4050      DONE;
4051    }
4052   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4053    {
4054      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4055      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4056      if (out != operands[0])
4057         emit_move_insn (operands[0], out);
4058      DONE;
4059    }
4062 ;; Signed conversion to SImode.
4064 (define_expand "fix_truncxfsi2"
4065   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4066                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4067               (clobber (reg:CC FLAGS_REG))])]
4068   "TARGET_80387"
4070   if (TARGET_FISTTP)
4071    {
4072      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4073      DONE;
4074    }
4077 (define_expand "fix_trunc<mode>si2"
4078   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4079                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4080               (clobber (reg:CC FLAGS_REG))])]
4081   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4083   if (TARGET_FISTTP
4084       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4085    {
4086      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4087      DONE;
4088    }
4089   if (SSE_FLOAT_MODE_P (<MODE>mode))
4090    {
4091      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4092      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4093      if (out != operands[0])
4094         emit_move_insn (operands[0], out);
4095      DONE;
4096    }
4099 ;; Signed conversion to HImode.
4101 (define_expand "fix_trunc<mode>hi2"
4102   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4103                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4104               (clobber (reg:CC FLAGS_REG))])]
4105   "TARGET_80387
4106    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4108   if (TARGET_FISTTP)
4109    {
4110      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4115 ;; When SSE is available, it is always faster to use it!
4116 (define_insn "fix_truncsfdi_sse"
4117   [(set (match_operand:DI 0 "register_operand" "=r,r")
4118         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4119   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttss2si{q}\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "SF")
4123    (set_attr "athlon_decode" "double,vector")])
4125 (define_insn "fix_truncdfdi_sse"
4126   [(set (match_operand:DI 0 "register_operand" "=r,r")
4127         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4128   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4134 (define_insn "fix_truncsfsi_sse"
4135   [(set (match_operand:SI 0 "register_operand" "=r,r")
4136         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4137   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttss2si\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "DF")
4141    (set_attr "athlon_decode" "double,vector")])
4143 (define_insn "fix_truncdfsi_sse"
4144   [(set (match_operand:SI 0 "register_operand" "=r,r")
4145         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4147   "cvttsd2si\t{%1, %0|%0, %1}"
4148   [(set_attr "type" "sseicvt")
4149    (set_attr "mode" "DF")
4150    (set_attr "athlon_decode" "double,vector")])
4152 ;; Avoid vector decoded forms of the instruction.
4153 (define_peephole2
4154   [(match_scratch:DF 2 "Y")
4155    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160   "")
4162 (define_peephole2
4163   [(match_scratch:SF 2 "x")
4164    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4165         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4166   "TARGET_K8 && !optimize_size"
4167   [(set (match_dup 2) (match_dup 1))
4168    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4169   "")
4171 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4172   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4173         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4174   "TARGET_FISTTP
4175    && FLOAT_MODE_P (GET_MODE (operands[1]))
4176    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4177          && (TARGET_64BIT || <MODE>mode != DImode))
4178         && TARGET_SSE_MATH)
4179    && !(reload_completed || reload_in_progress)"
4180   "#"
4181   "&& 1"
4182   [(const_int 0)]
4184   if (memory_operand (operands[0], VOIDmode))
4185     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4186   else
4187     {
4188       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4189       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4190                                                             operands[1],
4191                                                             operands[2]));
4192     }
4193   DONE;
4195   [(set_attr "type" "fisttp")
4196    (set_attr "mode" "<MODE>")])
4198 (define_insn "fix_trunc<mode>_i387_fisttp"
4199   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4200         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4201    (clobber (match_scratch:XF 2 "=&1f"))]
4202   "TARGET_FISTTP
4203    && FLOAT_MODE_P (GET_MODE (operands[1]))
4204    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4205          && (TARGET_64BIT || <MODE>mode != DImode))
4206         && TARGET_SSE_MATH)"
4207   "* return output_fix_trunc (insn, operands, 1);"
4208   [(set_attr "type" "fisttp")
4209    (set_attr "mode" "<MODE>")])
4211 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4212   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4213         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4214    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4215    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4216   "TARGET_FISTTP
4217    && FLOAT_MODE_P (GET_MODE (operands[1]))
4218    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4219         && (TARGET_64BIT || <MODE>mode != DImode))
4220         && TARGET_SSE_MATH)"
4221   "#"
4222   [(set_attr "type" "fisttp")
4223    (set_attr "mode" "<MODE>")])
4225 (define_split
4226   [(set (match_operand:X87MODEI 0 "register_operand" "")
4227         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4228    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4229    (clobber (match_scratch 3 ""))]
4230   "reload_completed"
4231   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4232               (clobber (match_dup 3))])
4233    (set (match_dup 0) (match_dup 2))]
4234   "")
4236 (define_split
4237   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4238         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4239    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4240    (clobber (match_scratch 3 ""))]
4241   "reload_completed"
4242   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4243               (clobber (match_dup 3))])]
4244   "")
4246 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4247 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4248 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4249 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4250 ;; function in i386.c.
4251 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4252   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4253         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4254    (clobber (reg:CC FLAGS_REG))]
4255   "TARGET_80387 && !TARGET_FISTTP
4256    && FLOAT_MODE_P (GET_MODE (operands[1]))
4257    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258          && (TARGET_64BIT || <MODE>mode != DImode))
4259    && !(reload_completed || reload_in_progress)"
4260   "#"
4261   "&& 1"
4262   [(const_int 0)]
4264   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4266   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4267   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4268   if (memory_operand (operands[0], VOIDmode))
4269     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4270                                          operands[2], operands[3]));
4271   else
4272     {
4273       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4274       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4275                                                      operands[2], operands[3],
4276                                                      operands[4]));
4277     }
4278   DONE;
4280   [(set_attr "type" "fistp")
4281    (set_attr "i387_cw" "trunc")
4282    (set_attr "mode" "<MODE>")])
4284 (define_insn "fix_truncdi_i387"
4285   [(set (match_operand:DI 0 "memory_operand" "=m")
4286         (fix:DI (match_operand 1 "register_operand" "f")))
4287    (use (match_operand:HI 2 "memory_operand" "m"))
4288    (use (match_operand:HI 3 "memory_operand" "m"))
4289    (clobber (match_scratch:XF 4 "=&1f"))]
4290   "TARGET_80387 && !TARGET_FISTTP
4291    && FLOAT_MODE_P (GET_MODE (operands[1]))
4292    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4293   "* return output_fix_trunc (insn, operands, 0);"
4294   [(set_attr "type" "fistp")
4295    (set_attr "i387_cw" "trunc")
4296    (set_attr "mode" "DI")])
4298 (define_insn "fix_truncdi_i387_with_temp"
4299   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4300         (fix:DI (match_operand 1 "register_operand" "f,f")))
4301    (use (match_operand:HI 2 "memory_operand" "m,m"))
4302    (use (match_operand:HI 3 "memory_operand" "m,m"))
4303    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4304    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4305   "TARGET_80387 && !TARGET_FISTTP
4306    && FLOAT_MODE_P (GET_MODE (operands[1]))
4307    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4308   "#"
4309   [(set_attr "type" "fistp")
4310    (set_attr "i387_cw" "trunc")
4311    (set_attr "mode" "DI")])
4313 (define_split 
4314   [(set (match_operand:DI 0 "register_operand" "")
4315         (fix:DI (match_operand 1 "register_operand" "")))
4316    (use (match_operand:HI 2 "memory_operand" ""))
4317    (use (match_operand:HI 3 "memory_operand" ""))
4318    (clobber (match_operand:DI 4 "memory_operand" ""))
4319    (clobber (match_scratch 5 ""))]
4320   "reload_completed"
4321   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4322               (use (match_dup 2))
4323               (use (match_dup 3))
4324               (clobber (match_dup 5))])
4325    (set (match_dup 0) (match_dup 4))]
4326   "")
4328 (define_split 
4329   [(set (match_operand:DI 0 "memory_operand" "")
4330         (fix:DI (match_operand 1 "register_operand" "")))
4331    (use (match_operand:HI 2 "memory_operand" ""))
4332    (use (match_operand:HI 3 "memory_operand" ""))
4333    (clobber (match_operand:DI 4 "memory_operand" ""))
4334    (clobber (match_scratch 5 ""))]
4335   "reload_completed"
4336   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4337               (use (match_dup 2))
4338               (use (match_dup 3))
4339               (clobber (match_dup 5))])]
4340   "")
4342 (define_insn "fix_trunc<mode>_i387"
4343   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4344         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4345    (use (match_operand:HI 2 "memory_operand" "m"))
4346    (use (match_operand:HI 3 "memory_operand" "m"))]
4347   "TARGET_80387 && !TARGET_FISTTP
4348    && FLOAT_MODE_P (GET_MODE (operands[1]))
4349    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4350   "* return output_fix_trunc (insn, operands, 0);"
4351   [(set_attr "type" "fistp")
4352    (set_attr "i387_cw" "trunc")
4353    (set_attr "mode" "<MODE>")])
4355 (define_insn "fix_trunc<mode>_i387_with_temp"
4356   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4357         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4358    (use (match_operand:HI 2 "memory_operand" "m,m"))
4359    (use (match_operand:HI 3 "memory_operand" "m,m"))
4360    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4361   "TARGET_80387 && !TARGET_FISTTP
4362    && FLOAT_MODE_P (GET_MODE (operands[1]))
4363    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4364   "#"
4365   [(set_attr "type" "fistp")
4366    (set_attr "i387_cw" "trunc")
4367    (set_attr "mode" "<MODE>")])
4369 (define_split 
4370   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4371         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4372    (use (match_operand:HI 2 "memory_operand" ""))
4373    (use (match_operand:HI 3 "memory_operand" ""))
4374    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4375   "reload_completed"
4376   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4377               (use (match_dup 2))
4378               (use (match_dup 3))])
4379    (set (match_dup 0) (match_dup 4))]
4380   "")
4382 (define_split 
4383   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4384         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4385    (use (match_operand:HI 2 "memory_operand" ""))
4386    (use (match_operand:HI 3 "memory_operand" ""))
4387    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4388   "reload_completed"
4389   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4390               (use (match_dup 2))
4391               (use (match_dup 3))])]
4392   "")
4394 (define_insn "x86_fnstcw_1"
4395   [(set (match_operand:HI 0 "memory_operand" "=m")
4396         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4397   "TARGET_80387"
4398   "fnstcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")])
4403 (define_insn "x86_fldcw_1"
4404   [(set (reg:HI FPSR_REG)
4405         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4406   "TARGET_80387"
4407   "fldcw\t%0"
4408   [(set_attr "length" "2")
4409    (set_attr "mode" "HI")
4410    (set_attr "unit" "i387")
4411    (set_attr "athlon_decode" "vector")])
4413 ;; Conversion between fixed point and floating point.
4415 ;; Even though we only accept memory inputs, the backend _really_
4416 ;; wants to be able to do this between registers.
4418 (define_expand "floathisf2"
4419   [(set (match_operand:SF 0 "register_operand" "")
4420         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4421   "TARGET_80387 || TARGET_SSE_MATH"
4423   if (TARGET_SSE_MATH)
4424     {
4425       emit_insn (gen_floatsisf2 (operands[0],
4426                                  convert_to_mode (SImode, operands[1], 0)));
4427       DONE;
4428     }
4431 (define_insn "*floathisf2_i387"
4432   [(set (match_operand:SF 0 "register_operand" "=f,f")
4433         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4434   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4435   "@
4436    fild%z1\t%1
4437    #"
4438   [(set_attr "type" "fmov,multi")
4439    (set_attr "mode" "SF")
4440    (set_attr "unit" "*,i387")
4441    (set_attr "fp_int_src" "true")])
4443 (define_expand "floatsisf2"
4444   [(set (match_operand:SF 0 "register_operand" "")
4445         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4446   "TARGET_80387 || TARGET_SSE_MATH"
4447   "")
4449 (define_insn "*floatsisf2_mixed"
4450   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4451         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4452   "TARGET_MIX_SSE_I387"
4453   "@
4454    fild%z1\t%1
4455    #
4456    cvtsi2ss\t{%1, %0|%0, %1}
4457    cvtsi2ss\t{%1, %0|%0, %1}"
4458   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4459    (set_attr "mode" "SF")
4460    (set_attr "unit" "*,i387,*,*")
4461    (set_attr "athlon_decode" "*,*,vector,double")
4462    (set_attr "fp_int_src" "true")])
4464 (define_insn "*floatsisf2_sse"
4465   [(set (match_operand:SF 0 "register_operand" "=x,x")
4466         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4467   "TARGET_SSE_MATH"
4468   "cvtsi2ss\t{%1, %0|%0, %1}"
4469   [(set_attr "type" "sseicvt")
4470    (set_attr "mode" "SF")
4471    (set_attr "athlon_decode" "vector,double")
4472    (set_attr "fp_int_src" "true")])
4474 (define_insn "*floatsisf2_i387"
4475   [(set (match_operand:SF 0 "register_operand" "=f,f")
4476         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4477   "TARGET_80387"
4478   "@
4479    fild%z1\t%1
4480    #"
4481   [(set_attr "type" "fmov,multi")
4482    (set_attr "mode" "SF")
4483    (set_attr "unit" "*,i387")
4484    (set_attr "fp_int_src" "true")])
4486 (define_expand "floatdisf2"
4487   [(set (match_operand:SF 0 "register_operand" "")
4488         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4489   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4490   "")
4492 (define_insn "*floatdisf2_mixed"
4493   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4494         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4495   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4496   "@
4497    fild%z1\t%1
4498    #
4499    cvtsi2ss{q}\t{%1, %0|%0, %1}
4500    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4501   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4502    (set_attr "mode" "SF")
4503    (set_attr "unit" "*,i387,*,*")
4504    (set_attr "athlon_decode" "*,*,vector,double")
4505    (set_attr "fp_int_src" "true")])
4507 (define_insn "*floatdisf2_sse"
4508   [(set (match_operand:SF 0 "register_operand" "=x,x")
4509         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4510   "TARGET_64BIT && TARGET_SSE_MATH"
4511   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4512   [(set_attr "type" "sseicvt")
4513    (set_attr "mode" "SF")
4514    (set_attr "athlon_decode" "vector,double")
4515    (set_attr "fp_int_src" "true")])
4517 (define_insn "*floatdisf2_i387"
4518   [(set (match_operand:SF 0 "register_operand" "=f,f")
4519         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4520   "TARGET_80387"
4521   "@
4522    fild%z1\t%1
4523    #"
4524   [(set_attr "type" "fmov,multi")
4525    (set_attr "mode" "SF")
4526    (set_attr "unit" "*,i387")
4527    (set_attr "fp_int_src" "true")])
4529 (define_expand "floathidf2"
4530   [(set (match_operand:DF 0 "register_operand" "")
4531         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4532   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4534   if (TARGET_SSE2 && TARGET_SSE_MATH)
4535     {
4536       emit_insn (gen_floatsidf2 (operands[0],
4537                                  convert_to_mode (SImode, operands[1], 0)));
4538       DONE;
4539     }
4542 (define_insn "*floathidf2_i387"
4543   [(set (match_operand:DF 0 "register_operand" "=f,f")
4544         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4545   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4546   "@
4547    fild%z1\t%1
4548    #"
4549   [(set_attr "type" "fmov,multi")
4550    (set_attr "mode" "DF")
4551    (set_attr "unit" "*,i387")
4552    (set_attr "fp_int_src" "true")])
4554 (define_expand "floatsidf2"
4555   [(set (match_operand:DF 0 "register_operand" "")
4556         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4557   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558   "")
4560 (define_insn "*floatsidf2_mixed"
4561   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4562         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4563   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4564   "@
4565    fild%z1\t%1
4566    #
4567    cvtsi2sd\t{%1, %0|%0, %1}
4568    cvtsi2sd\t{%1, %0|%0, %1}"
4569   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4570    (set_attr "mode" "DF")
4571    (set_attr "unit" "*,i387,*,*")
4572    (set_attr "athlon_decode" "*,*,double,direct")
4573    (set_attr "fp_int_src" "true")])
4575 (define_insn "*floatsidf2_sse"
4576   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4577         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4578   "TARGET_SSE2 && TARGET_SSE_MATH"
4579   "cvtsi2sd\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "sseicvt")
4581    (set_attr "mode" "DF")
4582    (set_attr "athlon_decode" "double,direct")
4583    (set_attr "fp_int_src" "true")])
4585 (define_insn "*floatsidf2_i387"
4586   [(set (match_operand:DF 0 "register_operand" "=f,f")
4587         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4588   "TARGET_80387"
4589   "@
4590    fild%z1\t%1
4591    #"
4592   [(set_attr "type" "fmov,multi")
4593    (set_attr "mode" "DF")
4594    (set_attr "unit" "*,i387")
4595    (set_attr "fp_int_src" "true")])
4597 (define_expand "floatdidf2"
4598   [(set (match_operand:DF 0 "register_operand" "")
4599         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4600   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4601   "")
4603 (define_insn "*floatdidf2_mixed"
4604   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4605         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4606   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4607   "@
4608    fild%z1\t%1
4609    #
4610    cvtsi2sd{q}\t{%1, %0|%0, %1}
4611    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4612   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4613    (set_attr "mode" "DF")
4614    (set_attr "unit" "*,i387,*,*")
4615    (set_attr "athlon_decode" "*,*,double,direct")
4616    (set_attr "fp_int_src" "true")])
4618 (define_insn "*floatdidf2_sse"
4619   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4620         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4621   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4622   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4623   [(set_attr "type" "sseicvt")
4624    (set_attr "mode" "DF")
4625    (set_attr "athlon_decode" "double,direct")
4626    (set_attr "fp_int_src" "true")])
4628 (define_insn "*floatdidf2_i387"
4629   [(set (match_operand:DF 0 "register_operand" "=f,f")
4630         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4631   "TARGET_80387"
4632   "@
4633    fild%z1\t%1
4634    #"
4635   [(set_attr "type" "fmov,multi")
4636    (set_attr "mode" "DF")
4637    (set_attr "unit" "*,i387")
4638    (set_attr "fp_int_src" "true")])
4640 (define_insn "floathixf2"
4641   [(set (match_operand:XF 0 "register_operand" "=f,f")
4642         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4643   "TARGET_80387"
4644   "@
4645    fild%z1\t%1
4646    #"
4647   [(set_attr "type" "fmov,multi")
4648    (set_attr "mode" "XF")
4649    (set_attr "unit" "*,i387")
4650    (set_attr "fp_int_src" "true")])
4652 (define_insn "floatsixf2"
4653   [(set (match_operand:XF 0 "register_operand" "=f,f")
4654         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4655   "TARGET_80387"
4656   "@
4657    fild%z1\t%1
4658    #"
4659   [(set_attr "type" "fmov,multi")
4660    (set_attr "mode" "XF")
4661    (set_attr "unit" "*,i387")
4662    (set_attr "fp_int_src" "true")])
4664 (define_insn "floatdixf2"
4665   [(set (match_operand:XF 0 "register_operand" "=f,f")
4666         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "XF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4676 ;; %%% Kill these when reload knows how to do it.
4677 (define_split
4678   [(set (match_operand 0 "fp_register_operand" "")
4679         (float (match_operand 1 "register_operand" "")))]
4680   "reload_completed
4681    && TARGET_80387
4682    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4683   [(const_int 0)]
4685   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4686   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4687   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4688   ix86_free_from_memory (GET_MODE (operands[1]));
4689   DONE;
4692 (define_expand "floatunssisf2"
4693   [(use (match_operand:SF 0 "register_operand" ""))
4694    (use (match_operand:SI 1 "register_operand" ""))]
4695   "!TARGET_64BIT && TARGET_SSE_MATH"
4696   "x86_emit_floatuns (operands); DONE;")
4698 (define_expand "floatunsdisf2"
4699   [(use (match_operand:SF 0 "register_operand" ""))
4700    (use (match_operand:DI 1 "register_operand" ""))]
4701   "TARGET_64BIT && TARGET_SSE_MATH"
4702   "x86_emit_floatuns (operands); DONE;")
4704 (define_expand "floatunsdidf2"
4705   [(use (match_operand:DF 0 "register_operand" ""))
4706    (use (match_operand:DI 1 "register_operand" ""))]
4707   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4708   "x86_emit_floatuns (operands); DONE;")
4710 ;; SSE extract/set expanders
4713 ;; Add instructions
4715 ;; %%% splits for addditi3
4717 (define_expand "addti3"
4718   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4720                  (match_operand:TI 2 "x86_64_general_operand" "")))
4721    (clobber (reg:CC FLAGS_REG))]
4722   "TARGET_64BIT"
4723   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4725 (define_insn "*addti3_1"
4726   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4727         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4728                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4729    (clobber (reg:CC FLAGS_REG))]
4730   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4731   "#")
4733 (define_split
4734   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4735         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4736                  (match_operand:TI 2 "general_operand" "")))
4737    (clobber (reg:CC FLAGS_REG))]
4738   "TARGET_64BIT && reload_completed"
4739   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4740                                           UNSPEC_ADD_CARRY))
4741               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4742    (parallel [(set (match_dup 3)
4743                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4744                                      (match_dup 4))
4745                             (match_dup 5)))
4746               (clobber (reg:CC FLAGS_REG))])]
4747   "split_ti (operands+0, 1, operands+0, operands+3);
4748    split_ti (operands+1, 1, operands+1, operands+4);
4749    split_ti (operands+2, 1, operands+2, operands+5);")
4751 ;; %%% splits for addsidi3
4752 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4754 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4756 (define_expand "adddi3"
4757   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4758         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4759                  (match_operand:DI 2 "x86_64_general_operand" "")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   ""
4762   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4764 (define_insn "*adddi3_1"
4765   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4766         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4767                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4770   "#")
4772 (define_split
4773   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4774         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4775                  (match_operand:DI 2 "general_operand" "")))
4776    (clobber (reg:CC FLAGS_REG))]
4777   "!TARGET_64BIT && reload_completed"
4778   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779                                           UNSPEC_ADD_CARRY))
4780               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4781    (parallel [(set (match_dup 3)
4782                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4783                                      (match_dup 4))
4784                             (match_dup 5)))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "split_di (operands+0, 1, operands+0, operands+3);
4787    split_di (operands+1, 1, operands+1, operands+4);
4788    split_di (operands+2, 1, operands+2, operands+5);")
4790 (define_insn "adddi3_carry_rex64"
4791   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4792           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4793                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4794                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4795    (clobber (reg:CC FLAGS_REG))]
4796   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4797   "adc{q}\t{%2, %0|%0, %2}"
4798   [(set_attr "type" "alu")
4799    (set_attr "pent_pair" "pu")
4800    (set_attr "mode" "DI")])
4802 (define_insn "*adddi3_cc_rex64"
4803   [(set (reg:CC FLAGS_REG)
4804         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4805                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4806                    UNSPEC_ADD_CARRY))
4807    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4808         (plus:DI (match_dup 1) (match_dup 2)))]
4809   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4810   "add{q}\t{%2, %0|%0, %2}"
4811   [(set_attr "type" "alu")
4812    (set_attr "mode" "DI")])
4814 (define_insn "addqi3_carry"
4815   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4816           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4817                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4818                    (match_operand:QI 2 "general_operand" "qi,qm")))
4819    (clobber (reg:CC FLAGS_REG))]
4820   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4821   "adc{b}\t{%2, %0|%0, %2}"
4822   [(set_attr "type" "alu")
4823    (set_attr "pent_pair" "pu")
4824    (set_attr "mode" "QI")])
4826 (define_insn "addhi3_carry"
4827   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4828           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4829                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4830                    (match_operand:HI 2 "general_operand" "ri,rm")))
4831    (clobber (reg:CC FLAGS_REG))]
4832   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4833   "adc{w}\t{%2, %0|%0, %2}"
4834   [(set_attr "type" "alu")
4835    (set_attr "pent_pair" "pu")
4836    (set_attr "mode" "HI")])
4838 (define_insn "addsi3_carry"
4839   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4840           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4841                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4842                    (match_operand:SI 2 "general_operand" "ri,rm")))
4843    (clobber (reg:CC FLAGS_REG))]
4844   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4845   "adc{l}\t{%2, %0|%0, %2}"
4846   [(set_attr "type" "alu")
4847    (set_attr "pent_pair" "pu")
4848    (set_attr "mode" "SI")])
4850 (define_insn "*addsi3_carry_zext"
4851   [(set (match_operand:DI 0 "register_operand" "=r")
4852           (zero_extend:DI 
4853             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4854                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4855                      (match_operand:SI 2 "general_operand" "rim"))))
4856    (clobber (reg:CC FLAGS_REG))]
4857   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4858   "adc{l}\t{%2, %k0|%k0, %2}"
4859   [(set_attr "type" "alu")
4860    (set_attr "pent_pair" "pu")
4861    (set_attr "mode" "SI")])
4863 (define_insn "*addsi3_cc"
4864   [(set (reg:CC FLAGS_REG)
4865         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4866                     (match_operand:SI 2 "general_operand" "ri,rm")]
4867                    UNSPEC_ADD_CARRY))
4868    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4869         (plus:SI (match_dup 1) (match_dup 2)))]
4870   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4871   "add{l}\t{%2, %0|%0, %2}"
4872   [(set_attr "type" "alu")
4873    (set_attr "mode" "SI")])
4875 (define_insn "addqi3_cc"
4876   [(set (reg:CC FLAGS_REG)
4877         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4878                     (match_operand:QI 2 "general_operand" "qi,qm")]
4879                    UNSPEC_ADD_CARRY))
4880    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4881         (plus:QI (match_dup 1) (match_dup 2)))]
4882   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4883   "add{b}\t{%2, %0|%0, %2}"
4884   [(set_attr "type" "alu")
4885    (set_attr "mode" "QI")])
4887 (define_expand "addsi3"
4888   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4889                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4890                             (match_operand:SI 2 "general_operand" "")))
4891               (clobber (reg:CC FLAGS_REG))])]
4892   ""
4893   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4895 (define_insn "*lea_1"
4896   [(set (match_operand:SI 0 "register_operand" "=r")
4897         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4898   "!TARGET_64BIT"
4899   "lea{l}\t{%a1, %0|%0, %a1}"
4900   [(set_attr "type" "lea")
4901    (set_attr "mode" "SI")])
4903 (define_insn "*lea_1_rex64"
4904   [(set (match_operand:SI 0 "register_operand" "=r")
4905         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %0|%0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4911 (define_insn "*lea_1_zext"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (zero_extend:DI
4914          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4915   "TARGET_64BIT"
4916   "lea{l}\t{%a1, %k0|%k0, %a1}"
4917   [(set_attr "type" "lea")
4918    (set_attr "mode" "SI")])
4920 (define_insn "*lea_2_rex64"
4921   [(set (match_operand:DI 0 "register_operand" "=r")
4922         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4923   "TARGET_64BIT"
4924   "lea{q}\t{%a1, %0|%0, %a1}"
4925   [(set_attr "type" "lea")
4926    (set_attr "mode" "DI")])
4928 ;; The lea patterns for non-Pmodes needs to be matched by several
4929 ;; insns converted to real lea by splitters.
4931 (define_insn_and_split "*lea_general_1"
4932   [(set (match_operand 0 "register_operand" "=r")
4933         (plus (plus (match_operand 1 "index_register_operand" "l")
4934                     (match_operand 2 "register_operand" "r"))
4935               (match_operand 3 "immediate_operand" "i")))]
4936   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4937     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4938    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4939    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4940    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4941    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4942        || GET_MODE (operands[3]) == VOIDmode)"
4943   "#"
4944   "&& reload_completed"
4945   [(const_int 0)]
4947   rtx pat;
4948   operands[0] = gen_lowpart (SImode, operands[0]);
4949   operands[1] = gen_lowpart (Pmode, operands[1]);
4950   operands[2] = gen_lowpart (Pmode, operands[2]);
4951   operands[3] = gen_lowpart (Pmode, operands[3]);
4952   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4953                       operands[3]);
4954   if (Pmode != SImode)
4955     pat = gen_rtx_SUBREG (SImode, pat, 0);
4956   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4957   DONE;
4959   [(set_attr "type" "lea")
4960    (set_attr "mode" "SI")])
4962 (define_insn_and_split "*lea_general_1_zext"
4963   [(set (match_operand:DI 0 "register_operand" "=r")
4964         (zero_extend:DI
4965           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4966                             (match_operand:SI 2 "register_operand" "r"))
4967                    (match_operand:SI 3 "immediate_operand" "i"))))]
4968   "TARGET_64BIT"
4969   "#"
4970   "&& reload_completed"
4971   [(set (match_dup 0)
4972         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4973                                                      (match_dup 2))
4974                                             (match_dup 3)) 0)))]
4976   operands[1] = gen_lowpart (Pmode, operands[1]);
4977   operands[2] = gen_lowpart (Pmode, operands[2]);
4978   operands[3] = gen_lowpart (Pmode, operands[3]);
4980   [(set_attr "type" "lea")
4981    (set_attr "mode" "SI")])
4983 (define_insn_and_split "*lea_general_2"
4984   [(set (match_operand 0 "register_operand" "=r")
4985         (plus (mult (match_operand 1 "index_register_operand" "l")
4986                     (match_operand 2 "const248_operand" "i"))
4987               (match_operand 3 "nonmemory_operand" "ri")))]
4988   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4989     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4990    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4991    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4992    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4993        || GET_MODE (operands[3]) == VOIDmode)"
4994   "#"
4995   "&& reload_completed"
4996   [(const_int 0)]
4998   rtx pat;
4999   operands[0] = gen_lowpart (SImode, operands[0]);
5000   operands[1] = gen_lowpart (Pmode, operands[1]);
5001   operands[3] = gen_lowpart (Pmode, operands[3]);
5002   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5003                       operands[3]);
5004   if (Pmode != SImode)
5005     pat = gen_rtx_SUBREG (SImode, pat, 0);
5006   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5007   DONE;
5009   [(set_attr "type" "lea")
5010    (set_attr "mode" "SI")])
5012 (define_insn_and_split "*lea_general_2_zext"
5013   [(set (match_operand:DI 0 "register_operand" "=r")
5014         (zero_extend:DI
5015           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5016                             (match_operand:SI 2 "const248_operand" "n"))
5017                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5018   "TARGET_64BIT"
5019   "#"
5020   "&& reload_completed"
5021   [(set (match_dup 0)
5022         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5023                                                      (match_dup 2))
5024                                             (match_dup 3)) 0)))]
5026   operands[1] = gen_lowpart (Pmode, operands[1]);
5027   operands[3] = gen_lowpart (Pmode, operands[3]);
5029   [(set_attr "type" "lea")
5030    (set_attr "mode" "SI")])
5032 (define_insn_and_split "*lea_general_3"
5033   [(set (match_operand 0 "register_operand" "=r")
5034         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5035                           (match_operand 2 "const248_operand" "i"))
5036                     (match_operand 3 "register_operand" "r"))
5037               (match_operand 4 "immediate_operand" "i")))]
5038   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5039     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5040    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5041    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5042    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5043   "#"
5044   "&& reload_completed"
5045   [(const_int 0)]
5047   rtx pat;
5048   operands[0] = gen_lowpart (SImode, operands[0]);
5049   operands[1] = gen_lowpart (Pmode, operands[1]);
5050   operands[3] = gen_lowpart (Pmode, operands[3]);
5051   operands[4] = gen_lowpart (Pmode, operands[4]);
5052   pat = gen_rtx_PLUS (Pmode,
5053                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5054                                                          operands[2]),
5055                                     operands[3]),
5056                       operands[4]);
5057   if (Pmode != SImode)
5058     pat = gen_rtx_SUBREG (SImode, pat, 0);
5059   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5060   DONE;
5062   [(set_attr "type" "lea")
5063    (set_attr "mode" "SI")])
5065 (define_insn_and_split "*lea_general_3_zext"
5066   [(set (match_operand:DI 0 "register_operand" "=r")
5067         (zero_extend:DI
5068           (plus:SI (plus:SI (mult:SI
5069                               (match_operand:SI 1 "index_register_operand" "l")
5070                               (match_operand:SI 2 "const248_operand" "n"))
5071                             (match_operand:SI 3 "register_operand" "r"))
5072                    (match_operand:SI 4 "immediate_operand" "i"))))]
5073   "TARGET_64BIT"
5074   "#"
5075   "&& reload_completed"
5076   [(set (match_dup 0)
5077         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5078                                                               (match_dup 2))
5079                                                      (match_dup 3))
5080                                             (match_dup 4)) 0)))]
5082   operands[1] = gen_lowpart (Pmode, operands[1]);
5083   operands[3] = gen_lowpart (Pmode, operands[3]);
5084   operands[4] = gen_lowpart (Pmode, operands[4]);
5086   [(set_attr "type" "lea")
5087    (set_attr "mode" "SI")])
5089 (define_insn "*adddi_1_rex64"
5090   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5091         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5092                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5093    (clobber (reg:CC FLAGS_REG))]
5094   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5096   switch (get_attr_type (insn))
5097     {
5098     case TYPE_LEA:
5099       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5100       return "lea{q}\t{%a2, %0|%0, %a2}";
5102     case TYPE_INCDEC:
5103       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5104       if (operands[2] == const1_rtx)
5105         return "inc{q}\t%0";
5106       else
5107         {
5108           gcc_assert (operands[2] == constm1_rtx);
5109           return "dec{q}\t%0";
5110         }
5112     default:
5113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5115       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5116          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5117       if (GET_CODE (operands[2]) == CONST_INT
5118           /* Avoid overflows.  */
5119           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5120           && (INTVAL (operands[2]) == 128
5121               || (INTVAL (operands[2]) < 0
5122                   && INTVAL (operands[2]) != -128)))
5123         {
5124           operands[2] = GEN_INT (-INTVAL (operands[2]));
5125           return "sub{q}\t{%2, %0|%0, %2}";
5126         }
5127       return "add{q}\t{%2, %0|%0, %2}";
5128     }
5130   [(set (attr "type")
5131      (cond [(eq_attr "alternative" "2")
5132               (const_string "lea")
5133             ; Current assemblers are broken and do not allow @GOTOFF in
5134             ; ought but a memory context.
5135             (match_operand:DI 2 "pic_symbolic_operand" "")
5136               (const_string "lea")
5137             (match_operand:DI 2 "incdec_operand" "")
5138               (const_string "incdec")
5139            ]
5140            (const_string "alu")))
5141    (set_attr "mode" "DI")])
5143 ;; Convert lea to the lea pattern to avoid flags dependency.
5144 (define_split
5145   [(set (match_operand:DI 0 "register_operand" "")
5146         (plus:DI (match_operand:DI 1 "register_operand" "")
5147                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5148    (clobber (reg:CC FLAGS_REG))]
5149   "TARGET_64BIT && reload_completed
5150    && true_regnum (operands[0]) != true_regnum (operands[1])"
5151   [(set (match_dup 0)
5152         (plus:DI (match_dup 1)
5153                  (match_dup 2)))]
5154   "")
5156 (define_insn "*adddi_2_rex64"
5157   [(set (reg FLAGS_REG)
5158         (compare
5159           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5160                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5161           (const_int 0)))                       
5162    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5163         (plus:DI (match_dup 1) (match_dup 2)))]
5164   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5165    && ix86_binary_operator_ok (PLUS, DImode, operands)
5166    /* Current assemblers are broken and do not allow @GOTOFF in
5167       ought but a memory context.  */
5168    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5170   switch (get_attr_type (insn))
5171     {
5172     case TYPE_INCDEC:
5173       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5174       if (operands[2] == const1_rtx)
5175         return "inc{q}\t%0";
5176       else
5177         {
5178           gcc_assert (operands[2] == constm1_rtx);
5179           return "dec{q}\t%0";
5180         }
5182     default:
5183       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5184       /* ???? We ought to handle there the 32bit case too
5185          - do we need new constraint?  */
5186       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5187          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5188       if (GET_CODE (operands[2]) == CONST_INT
5189           /* Avoid overflows.  */
5190           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5191           && (INTVAL (operands[2]) == 128
5192               || (INTVAL (operands[2]) < 0
5193                   && INTVAL (operands[2]) != -128)))
5194         {
5195           operands[2] = GEN_INT (-INTVAL (operands[2]));
5196           return "sub{q}\t{%2, %0|%0, %2}";
5197         }
5198       return "add{q}\t{%2, %0|%0, %2}";
5199     }
5201   [(set (attr "type")
5202      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5203         (const_string "incdec")
5204         (const_string "alu")))
5205    (set_attr "mode" "DI")])
5207 (define_insn "*adddi_3_rex64"
5208   [(set (reg FLAGS_REG)
5209         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5210                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5211    (clobber (match_scratch:DI 0 "=r"))]
5212   "TARGET_64BIT
5213    && ix86_match_ccmode (insn, CCZmode)
5214    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5215    /* Current assemblers are broken and do not allow @GOTOFF in
5216       ought but a memory context.  */
5217    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5219   switch (get_attr_type (insn))
5220     {
5221     case TYPE_INCDEC:
5222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223       if (operands[2] == const1_rtx)
5224         return "inc{q}\t%0";
5225       else
5226         {
5227           gcc_assert (operands[2] == constm1_rtx);
5228           return "dec{q}\t%0";
5229         }
5231     default:
5232       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5233       /* ???? We ought to handle there the 32bit case too
5234          - do we need new constraint?  */
5235       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5236          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5237       if (GET_CODE (operands[2]) == CONST_INT
5238           /* Avoid overflows.  */
5239           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5240           && (INTVAL (operands[2]) == 128
5241               || (INTVAL (operands[2]) < 0
5242                   && INTVAL (operands[2]) != -128)))
5243         {
5244           operands[2] = GEN_INT (-INTVAL (operands[2]));
5245           return "sub{q}\t{%2, %0|%0, %2}";
5246         }
5247       return "add{q}\t{%2, %0|%0, %2}";
5248     }
5250   [(set (attr "type")
5251      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5252         (const_string "incdec")
5253         (const_string "alu")))
5254    (set_attr "mode" "DI")])
5256 ; For comparisons against 1, -1 and 128, we may generate better code
5257 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5258 ; is matched then.  We can't accept general immediate, because for
5259 ; case of overflows,  the result is messed up.
5260 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5261 ; when negated.
5262 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5263 ; only for comparisons not depending on it.
5264 (define_insn "*adddi_4_rex64"
5265   [(set (reg FLAGS_REG)
5266         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5267                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5268    (clobber (match_scratch:DI 0 "=rm"))]
5269   "TARGET_64BIT
5270    &&  ix86_match_ccmode (insn, CCGCmode)"
5272   switch (get_attr_type (insn))
5273     {
5274     case TYPE_INCDEC:
5275       if (operands[2] == constm1_rtx)
5276         return "inc{q}\t%0";
5277       else
5278         {
5279           gcc_assert (operands[2] == const1_rtx);
5280           return "dec{q}\t%0";
5281         }
5283     default:
5284       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5285       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5286          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5287       if ((INTVAL (operands[2]) == -128
5288            || (INTVAL (operands[2]) > 0
5289                && INTVAL (operands[2]) != 128))
5290           /* Avoid overflows.  */
5291           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5292         return "sub{q}\t{%2, %0|%0, %2}";
5293       operands[2] = GEN_INT (-INTVAL (operands[2]));
5294       return "add{q}\t{%2, %0|%0, %2}";
5295     }
5297   [(set (attr "type")
5298      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5299         (const_string "incdec")
5300         (const_string "alu")))
5301    (set_attr "mode" "DI")])
5303 (define_insn "*adddi_5_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare
5306           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5307                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5308           (const_int 0)))                       
5309    (clobber (match_scratch:DI 0 "=r"))]
5310   "TARGET_64BIT
5311    && ix86_match_ccmode (insn, CCGOCmode)
5312    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5313    /* Current assemblers are broken and do not allow @GOTOFF in
5314       ought but a memory context.  */
5315    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5317   switch (get_attr_type (insn))
5318     {
5319     case TYPE_INCDEC:
5320       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5321       if (operands[2] == const1_rtx)
5322         return "inc{q}\t%0";
5323       else
5324         {
5325           gcc_assert (operands[2] == constm1_rtx);
5326           return "dec{q}\t%0";
5327         }
5329     default:
5330       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5331       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5332          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5333       if (GET_CODE (operands[2]) == CONST_INT
5334           /* Avoid overflows.  */
5335           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5336           && (INTVAL (operands[2]) == 128
5337               || (INTVAL (operands[2]) < 0
5338                   && INTVAL (operands[2]) != -128)))
5339         {
5340           operands[2] = GEN_INT (-INTVAL (operands[2]));
5341           return "sub{q}\t{%2, %0|%0, %2}";
5342         }
5343       return "add{q}\t{%2, %0|%0, %2}";
5344     }
5346   [(set (attr "type")
5347      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5348         (const_string "incdec")
5349         (const_string "alu")))
5350    (set_attr "mode" "DI")])
5353 (define_insn "*addsi_1"
5354   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5355         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5356                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5357    (clobber (reg:CC FLAGS_REG))]
5358   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5360   switch (get_attr_type (insn))
5361     {
5362     case TYPE_LEA:
5363       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5364       return "lea{l}\t{%a2, %0|%0, %a2}";
5366     case TYPE_INCDEC:
5367       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5368       if (operands[2] == const1_rtx)
5369         return "inc{l}\t%0";
5370       else
5371         {
5372           gcc_assert (operands[2] == constm1_rtx);
5373           return "dec{l}\t%0";
5374         }
5376     default:
5377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5379       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5380          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5381       if (GET_CODE (operands[2]) == CONST_INT
5382           && (INTVAL (operands[2]) == 128
5383               || (INTVAL (operands[2]) < 0
5384                   && INTVAL (operands[2]) != -128)))
5385         {
5386           operands[2] = GEN_INT (-INTVAL (operands[2]));
5387           return "sub{l}\t{%2, %0|%0, %2}";
5388         }
5389       return "add{l}\t{%2, %0|%0, %2}";
5390     }
5392   [(set (attr "type")
5393      (cond [(eq_attr "alternative" "2")
5394               (const_string "lea")
5395             ; Current assemblers are broken and do not allow @GOTOFF in
5396             ; ought but a memory context.
5397             (match_operand:SI 2 "pic_symbolic_operand" "")
5398               (const_string "lea")
5399             (match_operand:SI 2 "incdec_operand" "")
5400               (const_string "incdec")
5401            ]
5402            (const_string "alu")))
5403    (set_attr "mode" "SI")])
5405 ;; Convert lea to the lea pattern to avoid flags dependency.
5406 (define_split
5407   [(set (match_operand 0 "register_operand" "")
5408         (plus (match_operand 1 "register_operand" "")
5409               (match_operand 2 "nonmemory_operand" "")))
5410    (clobber (reg:CC FLAGS_REG))]
5411   "reload_completed
5412    && true_regnum (operands[0]) != true_regnum (operands[1])"
5413   [(const_int 0)]
5415   rtx pat;
5416   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5417      may confuse gen_lowpart.  */
5418   if (GET_MODE (operands[0]) != Pmode)
5419     {
5420       operands[1] = gen_lowpart (Pmode, operands[1]);
5421       operands[2] = gen_lowpart (Pmode, operands[2]);
5422     }
5423   operands[0] = gen_lowpart (SImode, operands[0]);
5424   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5425   if (Pmode != SImode)
5426     pat = gen_rtx_SUBREG (SImode, pat, 0);
5427   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5428   DONE;
5431 ;; It may seem that nonimmediate operand is proper one for operand 1.
5432 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5433 ;; we take care in ix86_binary_operator_ok to not allow two memory
5434 ;; operands so proper swapping will be done in reload.  This allow
5435 ;; patterns constructed from addsi_1 to match.
5436 (define_insn "addsi_1_zext"
5437   [(set (match_operand:DI 0 "register_operand" "=r,r")
5438         (zero_extend:DI
5439           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5440                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5441    (clobber (reg:CC FLAGS_REG))]
5442   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5444   switch (get_attr_type (insn))
5445     {
5446     case TYPE_LEA:
5447       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5448       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5450     case TYPE_INCDEC:
5451       if (operands[2] == const1_rtx)
5452         return "inc{l}\t%k0";
5453       else
5454         {
5455           gcc_assert (operands[2] == constm1_rtx);
5456           return "dec{l}\t%k0";
5457         }
5459     default:
5460       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5461          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5462       if (GET_CODE (operands[2]) == CONST_INT
5463           && (INTVAL (operands[2]) == 128
5464               || (INTVAL (operands[2]) < 0
5465                   && INTVAL (operands[2]) != -128)))
5466         {
5467           operands[2] = GEN_INT (-INTVAL (operands[2]));
5468           return "sub{l}\t{%2, %k0|%k0, %2}";
5469         }
5470       return "add{l}\t{%2, %k0|%k0, %2}";
5471     }
5473   [(set (attr "type")
5474      (cond [(eq_attr "alternative" "1")
5475               (const_string "lea")
5476             ; Current assemblers are broken and do not allow @GOTOFF in
5477             ; ought but a memory context.
5478             (match_operand:SI 2 "pic_symbolic_operand" "")
5479               (const_string "lea")
5480             (match_operand:SI 2 "incdec_operand" "")
5481               (const_string "incdec")
5482            ]
5483            (const_string "alu")))
5484    (set_attr "mode" "SI")])
5486 ;; Convert lea to the lea pattern to avoid flags dependency.
5487 (define_split
5488   [(set (match_operand:DI 0 "register_operand" "")
5489         (zero_extend:DI
5490           (plus:SI (match_operand:SI 1 "register_operand" "")
5491                    (match_operand:SI 2 "nonmemory_operand" ""))))
5492    (clobber (reg:CC FLAGS_REG))]
5493   "TARGET_64BIT && reload_completed
5494    && true_regnum (operands[0]) != true_regnum (operands[1])"
5495   [(set (match_dup 0)
5496         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5498   operands[1] = gen_lowpart (Pmode, operands[1]);
5499   operands[2] = gen_lowpart (Pmode, operands[2]);
5502 (define_insn "*addsi_2"
5503   [(set (reg FLAGS_REG)
5504         (compare
5505           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5506                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5507           (const_int 0)))                       
5508    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5509         (plus:SI (match_dup 1) (match_dup 2)))]
5510   "ix86_match_ccmode (insn, CCGOCmode)
5511    && ix86_binary_operator_ok (PLUS, SImode, operands)
5512    /* Current assemblers are broken and do not allow @GOTOFF in
5513       ought but a memory context.  */
5514    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5516   switch (get_attr_type (insn))
5517     {
5518     case TYPE_INCDEC:
5519       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5520       if (operands[2] == const1_rtx)
5521         return "inc{l}\t%0";
5522       else
5523         {
5524           gcc_assert (operands[2] == constm1_rtx);
5525           return "dec{l}\t%0";
5526         }
5528     default:
5529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5531          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5532       if (GET_CODE (operands[2]) == CONST_INT
5533           && (INTVAL (operands[2]) == 128
5534               || (INTVAL (operands[2]) < 0
5535                   && INTVAL (operands[2]) != -128)))
5536         {
5537           operands[2] = GEN_INT (-INTVAL (operands[2]));
5538           return "sub{l}\t{%2, %0|%0, %2}";
5539         }
5540       return "add{l}\t{%2, %0|%0, %2}";
5541     }
5543   [(set (attr "type")
5544      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5545         (const_string "incdec")
5546         (const_string "alu")))
5547    (set_attr "mode" "SI")])
5549 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5550 (define_insn "*addsi_2_zext"
5551   [(set (reg FLAGS_REG)
5552         (compare
5553           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5554                    (match_operand:SI 2 "general_operand" "rmni"))
5555           (const_int 0)))                       
5556    (set (match_operand:DI 0 "register_operand" "=r")
5557         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5558   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5559    && ix86_binary_operator_ok (PLUS, SImode, operands)
5560    /* Current assemblers are broken and do not allow @GOTOFF in
5561       ought but a memory context.  */
5562    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5564   switch (get_attr_type (insn))
5565     {
5566     case TYPE_INCDEC:
5567       if (operands[2] == const1_rtx)
5568         return "inc{l}\t%k0";
5569       else
5570         {
5571           gcc_assert (operands[2] == constm1_rtx);
5572           return "dec{l}\t%k0";
5573         }
5575     default:
5576       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5577          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5578       if (GET_CODE (operands[2]) == CONST_INT
5579           && (INTVAL (operands[2]) == 128
5580               || (INTVAL (operands[2]) < 0
5581                   && INTVAL (operands[2]) != -128)))
5582         {
5583           operands[2] = GEN_INT (-INTVAL (operands[2]));
5584           return "sub{l}\t{%2, %k0|%k0, %2}";
5585         }
5586       return "add{l}\t{%2, %k0|%k0, %2}";
5587     }
5589   [(set (attr "type")
5590      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5591         (const_string "incdec")
5592         (const_string "alu")))
5593    (set_attr "mode" "SI")])
5595 (define_insn "*addsi_3"
5596   [(set (reg FLAGS_REG)
5597         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5598                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5599    (clobber (match_scratch:SI 0 "=r"))]
5600   "ix86_match_ccmode (insn, CCZmode)
5601    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5602    /* Current assemblers are broken and do not allow @GOTOFF in
5603       ought but a memory context.  */
5604    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5606   switch (get_attr_type (insn))
5607     {
5608     case TYPE_INCDEC:
5609       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610       if (operands[2] == const1_rtx)
5611         return "inc{l}\t%0";
5612       else
5613         {
5614           gcc_assert (operands[2] == constm1_rtx);
5615           return "dec{l}\t%0";
5616         }
5618     default:
5619       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5620       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5621          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5622       if (GET_CODE (operands[2]) == CONST_INT
5623           && (INTVAL (operands[2]) == 128
5624               || (INTVAL (operands[2]) < 0
5625                   && INTVAL (operands[2]) != -128)))
5626         {
5627           operands[2] = GEN_INT (-INTVAL (operands[2]));
5628           return "sub{l}\t{%2, %0|%0, %2}";
5629         }
5630       return "add{l}\t{%2, %0|%0, %2}";
5631     }
5633   [(set (attr "type")
5634      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5635         (const_string "incdec")
5636         (const_string "alu")))
5637    (set_attr "mode" "SI")])
5639 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5640 (define_insn "*addsi_3_zext"
5641   [(set (reg FLAGS_REG)
5642         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5643                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5644    (set (match_operand:DI 0 "register_operand" "=r")
5645         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5646   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5647    && ix86_binary_operator_ok (PLUS, SImode, operands)
5648    /* Current assemblers are broken and do not allow @GOTOFF in
5649       ought but a memory context.  */
5650    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5652   switch (get_attr_type (insn))
5653     {
5654     case TYPE_INCDEC:
5655       if (operands[2] == const1_rtx)
5656         return "inc{l}\t%k0";
5657       else
5658         {
5659           gcc_assert (operands[2] == constm1_rtx);
5660           return "dec{l}\t%k0";
5661         }
5663     default:
5664       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5665          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5666       if (GET_CODE (operands[2]) == CONST_INT
5667           && (INTVAL (operands[2]) == 128
5668               || (INTVAL (operands[2]) < 0
5669                   && INTVAL (operands[2]) != -128)))
5670         {
5671           operands[2] = GEN_INT (-INTVAL (operands[2]));
5672           return "sub{l}\t{%2, %k0|%k0, %2}";
5673         }
5674       return "add{l}\t{%2, %k0|%k0, %2}";
5675     }
5677   [(set (attr "type")
5678      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5679         (const_string "incdec")
5680         (const_string "alu")))
5681    (set_attr "mode" "SI")])
5683 ; For comparisons against 1, -1 and 128, we may generate better code
5684 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5685 ; is matched then.  We can't accept general immediate, because for
5686 ; case of overflows,  the result is messed up.
5687 ; This pattern also don't hold of 0x80000000, since the value overflows
5688 ; when negated.
5689 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5690 ; only for comparisons not depending on it.
5691 (define_insn "*addsi_4"
5692   [(set (reg FLAGS_REG)
5693         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5694                  (match_operand:SI 2 "const_int_operand" "n")))
5695    (clobber (match_scratch:SI 0 "=rm"))]
5696   "ix86_match_ccmode (insn, CCGCmode)
5697    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5699   switch (get_attr_type (insn))
5700     {
5701     case TYPE_INCDEC:
5702       if (operands[2] == constm1_rtx)
5703         return "inc{l}\t%0";
5704       else
5705         {
5706           gcc_assert (operands[2] == const1_rtx);
5707           return "dec{l}\t%0";
5708         }
5710     default:
5711       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5712       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5713          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5714       if ((INTVAL (operands[2]) == -128
5715            || (INTVAL (operands[2]) > 0
5716                && INTVAL (operands[2]) != 128)))
5717         return "sub{l}\t{%2, %0|%0, %2}";
5718       operands[2] = GEN_INT (-INTVAL (operands[2]));
5719       return "add{l}\t{%2, %0|%0, %2}";
5720     }
5722   [(set (attr "type")
5723      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5724         (const_string "incdec")
5725         (const_string "alu")))
5726    (set_attr "mode" "SI")])
5728 (define_insn "*addsi_5"
5729   [(set (reg FLAGS_REG)
5730         (compare
5731           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732                    (match_operand:SI 2 "general_operand" "rmni"))
5733           (const_int 0)))                       
5734    (clobber (match_scratch:SI 0 "=r"))]
5735   "ix86_match_ccmode (insn, CCGOCmode)
5736    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5737    /* Current assemblers are broken and do not allow @GOTOFF in
5738       ought but a memory context.  */
5739    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741   switch (get_attr_type (insn))
5742     {
5743     case TYPE_INCDEC:
5744       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745       if (operands[2] == const1_rtx)
5746         return "inc{l}\t%0";
5747       else
5748         {
5749           gcc_assert (operands[2] == constm1_rtx);
5750           return "dec{l}\t%0";
5751         }
5753     default:
5754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5756          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5757       if (GET_CODE (operands[2]) == CONST_INT
5758           && (INTVAL (operands[2]) == 128
5759               || (INTVAL (operands[2]) < 0
5760                   && INTVAL (operands[2]) != -128)))
5761         {
5762           operands[2] = GEN_INT (-INTVAL (operands[2]));
5763           return "sub{l}\t{%2, %0|%0, %2}";
5764         }
5765       return "add{l}\t{%2, %0|%0, %2}";
5766     }
5768   [(set (attr "type")
5769      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5770         (const_string "incdec")
5771         (const_string "alu")))
5772    (set_attr "mode" "SI")])
5774 (define_expand "addhi3"
5775   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5776                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5777                             (match_operand:HI 2 "general_operand" "")))
5778               (clobber (reg:CC FLAGS_REG))])]
5779   "TARGET_HIMODE_MATH"
5780   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5782 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5783 ;; type optimizations enabled by define-splits.  This is not important
5784 ;; for PII, and in fact harmful because of partial register stalls.
5786 (define_insn "*addhi_1_lea"
5787   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5788         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5789                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5790    (clobber (reg:CC FLAGS_REG))]
5791   "!TARGET_PARTIAL_REG_STALL
5792    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5794   switch (get_attr_type (insn))
5795     {
5796     case TYPE_LEA:
5797       return "#";
5798     case TYPE_INCDEC:
5799       if (operands[2] == const1_rtx)
5800         return "inc{w}\t%0";
5801       else
5802         {
5803           gcc_assert (operands[2] == constm1_rtx);
5804           return "dec{w}\t%0";
5805         }
5807     default:
5808       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5809          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5810       if (GET_CODE (operands[2]) == CONST_INT
5811           && (INTVAL (operands[2]) == 128
5812               || (INTVAL (operands[2]) < 0
5813                   && INTVAL (operands[2]) != -128)))
5814         {
5815           operands[2] = GEN_INT (-INTVAL (operands[2]));
5816           return "sub{w}\t{%2, %0|%0, %2}";
5817         }
5818       return "add{w}\t{%2, %0|%0, %2}";
5819     }
5821   [(set (attr "type")
5822      (if_then_else (eq_attr "alternative" "2")
5823         (const_string "lea")
5824         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5825            (const_string "incdec")
5826            (const_string "alu"))))
5827    (set_attr "mode" "HI,HI,SI")])
5829 (define_insn "*addhi_1"
5830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5831         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5832                  (match_operand:HI 2 "general_operand" "ri,rm")))
5833    (clobber (reg:CC FLAGS_REG))]
5834   "TARGET_PARTIAL_REG_STALL
5835    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_INCDEC:
5840       if (operands[2] == const1_rtx)
5841         return "inc{w}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return "dec{w}\t%0";
5846         }
5848     default:
5849       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5850          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5851       if (GET_CODE (operands[2]) == CONST_INT
5852           && (INTVAL (operands[2]) == 128
5853               || (INTVAL (operands[2]) < 0
5854                   && INTVAL (operands[2]) != -128)))
5855         {
5856           operands[2] = GEN_INT (-INTVAL (operands[2]));
5857           return "sub{w}\t{%2, %0|%0, %2}";
5858         }
5859       return "add{w}\t{%2, %0|%0, %2}";
5860     }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set_attr "mode" "HI")])
5868 (define_insn "*addhi_2"
5869   [(set (reg FLAGS_REG)
5870         (compare
5871           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5872                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5873           (const_int 0)))                       
5874    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5875         (plus:HI (match_dup 1) (match_dup 2)))]
5876   "ix86_match_ccmode (insn, CCGOCmode)
5877    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5879   switch (get_attr_type (insn))
5880     {
5881     case TYPE_INCDEC:
5882       if (operands[2] == const1_rtx)
5883         return "inc{w}\t%0";
5884       else
5885         {
5886           gcc_assert (operands[2] == constm1_rtx);
5887           return "dec{w}\t%0";
5888         }
5890     default:
5891       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5892          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5893       if (GET_CODE (operands[2]) == CONST_INT
5894           && (INTVAL (operands[2]) == 128
5895               || (INTVAL (operands[2]) < 0
5896                   && INTVAL (operands[2]) != -128)))
5897         {
5898           operands[2] = GEN_INT (-INTVAL (operands[2]));
5899           return "sub{w}\t{%2, %0|%0, %2}";
5900         }
5901       return "add{w}\t{%2, %0|%0, %2}";
5902     }
5904   [(set (attr "type")
5905      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5906         (const_string "incdec")
5907         (const_string "alu")))
5908    (set_attr "mode" "HI")])
5910 (define_insn "*addhi_3"
5911   [(set (reg FLAGS_REG)
5912         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5913                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5914    (clobber (match_scratch:HI 0 "=r"))]
5915   "ix86_match_ccmode (insn, CCZmode)
5916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5918   switch (get_attr_type (insn))
5919     {
5920     case TYPE_INCDEC:
5921       if (operands[2] == const1_rtx)
5922         return "inc{w}\t%0";
5923       else
5924         {
5925           gcc_assert (operands[2] == constm1_rtx);
5926           return "dec{w}\t%0";
5927         }
5929     default:
5930       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5932       if (GET_CODE (operands[2]) == CONST_INT
5933           && (INTVAL (operands[2]) == 128
5934               || (INTVAL (operands[2]) < 0
5935                   && INTVAL (operands[2]) != -128)))
5936         {
5937           operands[2] = GEN_INT (-INTVAL (operands[2]));
5938           return "sub{w}\t{%2, %0|%0, %2}";
5939         }
5940       return "add{w}\t{%2, %0|%0, %2}";
5941     }
5943   [(set (attr "type")
5944      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5945         (const_string "incdec")
5946         (const_string "alu")))
5947    (set_attr "mode" "HI")])
5949 ; See comments above addsi_4 for details.
5950 (define_insn "*addhi_4"
5951   [(set (reg FLAGS_REG)
5952         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5953                  (match_operand:HI 2 "const_int_operand" "n")))
5954    (clobber (match_scratch:HI 0 "=rm"))]
5955   "ix86_match_ccmode (insn, CCGCmode)
5956    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5958   switch (get_attr_type (insn))
5959     {
5960     case TYPE_INCDEC:
5961       if (operands[2] == constm1_rtx)
5962         return "inc{w}\t%0";
5963       else
5964         {
5965           gcc_assert (operands[2] == const1_rtx);
5966           return "dec{w}\t%0";
5967         }
5969     default:
5970       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5971       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5973       if ((INTVAL (operands[2]) == -128
5974            || (INTVAL (operands[2]) > 0
5975                && INTVAL (operands[2]) != 128)))
5976         return "sub{w}\t{%2, %0|%0, %2}";
5977       operands[2] = GEN_INT (-INTVAL (operands[2]));
5978       return "add{w}\t{%2, %0|%0, %2}";
5979     }
5981   [(set (attr "type")
5982      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983         (const_string "incdec")
5984         (const_string "alu")))
5985    (set_attr "mode" "SI")])
5988 (define_insn "*addhi_5"
5989   [(set (reg FLAGS_REG)
5990         (compare
5991           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5992                    (match_operand:HI 2 "general_operand" "rmni"))
5993           (const_int 0)))                       
5994    (clobber (match_scratch:HI 0 "=r"))]
5995   "ix86_match_ccmode (insn, CCGOCmode)
5996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5998   switch (get_attr_type (insn))
5999     {
6000     case TYPE_INCDEC:
6001       if (operands[2] == const1_rtx)
6002         return "inc{w}\t%0";
6003       else
6004         {
6005           gcc_assert (operands[2] == constm1_rtx);
6006           return "dec{w}\t%0";
6007         }
6009     default:
6010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6012       if (GET_CODE (operands[2]) == CONST_INT
6013           && (INTVAL (operands[2]) == 128
6014               || (INTVAL (operands[2]) < 0
6015                   && INTVAL (operands[2]) != -128)))
6016         {
6017           operands[2] = GEN_INT (-INTVAL (operands[2]));
6018           return "sub{w}\t{%2, %0|%0, %2}";
6019         }
6020       return "add{w}\t{%2, %0|%0, %2}";
6021     }
6023   [(set (attr "type")
6024      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6025         (const_string "incdec")
6026         (const_string "alu")))
6027    (set_attr "mode" "HI")])
6029 (define_expand "addqi3"
6030   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6031                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6032                             (match_operand:QI 2 "general_operand" "")))
6033               (clobber (reg:CC FLAGS_REG))])]
6034   "TARGET_QIMODE_MATH"
6035   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6037 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6038 (define_insn "*addqi_1_lea"
6039   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6040         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6041                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6042    (clobber (reg:CC FLAGS_REG))]
6043   "!TARGET_PARTIAL_REG_STALL
6044    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6046   int widen = (which_alternative == 2);
6047   switch (get_attr_type (insn))
6048     {
6049     case TYPE_LEA:
6050       return "#";
6051     case TYPE_INCDEC:
6052       if (operands[2] == const1_rtx)
6053         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6054       else
6055         {
6056           gcc_assert (operands[2] == constm1_rtx);
6057           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6058         }
6060     default:
6061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6063       if (GET_CODE (operands[2]) == CONST_INT
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           if (widen)
6070             return "sub{l}\t{%2, %k0|%k0, %2}";
6071           else
6072             return "sub{b}\t{%2, %0|%0, %2}";
6073         }
6074       if (widen)
6075         return "add{l}\t{%k2, %k0|%k0, %k2}";
6076       else
6077         return "add{b}\t{%2, %0|%0, %2}";
6078     }
6080   [(set (attr "type")
6081      (if_then_else (eq_attr "alternative" "3")
6082         (const_string "lea")
6083         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6084            (const_string "incdec")
6085            (const_string "alu"))))
6086    (set_attr "mode" "QI,QI,SI,SI")])
6088 (define_insn "*addqi_1"
6089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6090         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6091                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6092    (clobber (reg:CC FLAGS_REG))]
6093   "TARGET_PARTIAL_REG_STALL
6094    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6096   int widen = (which_alternative == 2);
6097   switch (get_attr_type (insn))
6098     {
6099     case TYPE_INCDEC:
6100       if (operands[2] == const1_rtx)
6101         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6102       else
6103         {
6104           gcc_assert (operands[2] == constm1_rtx);
6105           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6106         }
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (GET_CODE (operands[2]) == CONST_INT
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           if (widen)
6118             return "sub{l}\t{%2, %k0|%k0, %2}";
6119           else
6120             return "sub{b}\t{%2, %0|%0, %2}";
6121         }
6122       if (widen)
6123         return "add{l}\t{%k2, %k0|%k0, %k2}";
6124       else
6125         return "add{b}\t{%2, %0|%0, %2}";
6126     }
6128   [(set (attr "type")
6129      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6130         (const_string "incdec")
6131         (const_string "alu")))
6132    (set_attr "mode" "QI,QI,SI")])
6134 (define_insn "*addqi_1_slp"
6135   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6136         (plus:QI (match_dup 0)
6137                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6138    (clobber (reg:CC FLAGS_REG))]
6139   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6140    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6142   switch (get_attr_type (insn))
6143     {
6144     case TYPE_INCDEC:
6145       if (operands[1] == const1_rtx)
6146         return "inc{b}\t%0";
6147       else
6148         {
6149           gcc_assert (operands[1] == constm1_rtx);
6150           return "dec{b}\t%0";
6151         }
6153     default:
6154       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6155       if (GET_CODE (operands[1]) == CONST_INT
6156           && INTVAL (operands[1]) < 0)
6157         {
6158           operands[1] = GEN_INT (-INTVAL (operands[1]));
6159           return "sub{b}\t{%1, %0|%0, %1}";
6160         }
6161       return "add{b}\t{%1, %0|%0, %1}";
6162     }
6164   [(set (attr "type")
6165      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6166         (const_string "incdec")
6167         (const_string "alu1")))
6168    (set (attr "memory")
6169      (if_then_else (match_operand 1 "memory_operand" "")
6170         (const_string "load")
6171         (const_string "none")))
6172    (set_attr "mode" "QI")])
6174 (define_insn "*addqi_2"
6175   [(set (reg FLAGS_REG)
6176         (compare
6177           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6178                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6179           (const_int 0)))
6180    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6181         (plus:QI (match_dup 1) (match_dup 2)))]
6182   "ix86_match_ccmode (insn, CCGOCmode)
6183    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6185   switch (get_attr_type (insn))
6186     {
6187     case TYPE_INCDEC:
6188       if (operands[2] == const1_rtx)
6189         return "inc{b}\t%0";
6190       else
6191         {
6192           gcc_assert (operands[2] == constm1_rtx
6193                       || (GET_CODE (operands[2]) == CONST_INT
6194                           && INTVAL (operands[2]) == 255));
6195           return "dec{b}\t%0";
6196         }
6198     default:
6199       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6200       if (GET_CODE (operands[2]) == CONST_INT
6201           && INTVAL (operands[2]) < 0)
6202         {
6203           operands[2] = GEN_INT (-INTVAL (operands[2]));
6204           return "sub{b}\t{%2, %0|%0, %2}";
6205         }
6206       return "add{b}\t{%2, %0|%0, %2}";
6207     }
6209   [(set (attr "type")
6210      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6211         (const_string "incdec")
6212         (const_string "alu")))
6213    (set_attr "mode" "QI")])
6215 (define_insn "*addqi_3"
6216   [(set (reg FLAGS_REG)
6217         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6218                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6219    (clobber (match_scratch:QI 0 "=q"))]
6220   "ix86_match_ccmode (insn, CCZmode)
6221    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6223   switch (get_attr_type (insn))
6224     {
6225     case TYPE_INCDEC:
6226       if (operands[2] == const1_rtx)
6227         return "inc{b}\t%0";
6228       else
6229         {
6230           gcc_assert (operands[2] == constm1_rtx
6231                       || (GET_CODE (operands[2]) == CONST_INT
6232                           && INTVAL (operands[2]) == 255));
6233           return "dec{b}\t%0";
6234         }
6236     default:
6237       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6238       if (GET_CODE (operands[2]) == CONST_INT
6239           && INTVAL (operands[2]) < 0)
6240         {
6241           operands[2] = GEN_INT (-INTVAL (operands[2]));
6242           return "sub{b}\t{%2, %0|%0, %2}";
6243         }
6244       return "add{b}\t{%2, %0|%0, %2}";
6245     }
6247   [(set (attr "type")
6248      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249         (const_string "incdec")
6250         (const_string "alu")))
6251    (set_attr "mode" "QI")])
6253 ; See comments above addsi_4 for details.
6254 (define_insn "*addqi_4"
6255   [(set (reg FLAGS_REG)
6256         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6257                  (match_operand:QI 2 "const_int_operand" "n")))
6258    (clobber (match_scratch:QI 0 "=qm"))]
6259   "ix86_match_ccmode (insn, CCGCmode)
6260    && (INTVAL (operands[2]) & 0xff) != 0x80"
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       if (operands[2] == constm1_rtx
6266           || (GET_CODE (operands[2]) == CONST_INT
6267               && INTVAL (operands[2]) == 255))
6268         return "inc{b}\t%0";
6269       else
6270         {
6271           gcc_assert (operands[2] == const1_rtx);
6272           return "dec{b}\t%0";
6273         }
6275     default:
6276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6277       if (INTVAL (operands[2]) < 0)
6278         {
6279           operands[2] = GEN_INT (-INTVAL (operands[2]));
6280           return "add{b}\t{%2, %0|%0, %2}";
6281         }
6282       return "sub{b}\t{%2, %0|%0, %2}";
6283     }
6285   [(set (attr "type")
6286      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6287         (const_string "incdec")
6288         (const_string "alu")))
6289    (set_attr "mode" "QI")])
6292 (define_insn "*addqi_5"
6293   [(set (reg FLAGS_REG)
6294         (compare
6295           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6296                    (match_operand:QI 2 "general_operand" "qmni"))
6297           (const_int 0)))
6298    (clobber (match_scratch:QI 0 "=q"))]
6299   "ix86_match_ccmode (insn, CCGOCmode)
6300    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6302   switch (get_attr_type (insn))
6303     {
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == constm1_rtx
6310                       || (GET_CODE (operands[2]) == CONST_INT
6311                           && INTVAL (operands[2]) == 255));
6312           return "dec{b}\t%0";
6313         }
6315     default:
6316       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6317       if (GET_CODE (operands[2]) == CONST_INT
6318           && INTVAL (operands[2]) < 0)
6319         {
6320           operands[2] = GEN_INT (-INTVAL (operands[2]));
6321           return "sub{b}\t{%2, %0|%0, %2}";
6322         }
6323       return "add{b}\t{%2, %0|%0, %2}";
6324     }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu")))
6330    (set_attr "mode" "QI")])
6333 (define_insn "addqi_ext_1"
6334   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6335                          (const_int 8)
6336                          (const_int 8))
6337         (plus:SI
6338           (zero_extract:SI
6339             (match_operand 1 "ext_register_operand" "0")
6340             (const_int 8)
6341             (const_int 8))
6342           (match_operand:QI 2 "general_operand" "Qmn")))
6343    (clobber (reg:CC FLAGS_REG))]
6344   "!TARGET_64BIT"
6346   switch (get_attr_type (insn))
6347     {
6348     case TYPE_INCDEC:
6349       if (operands[2] == const1_rtx)
6350         return "inc{b}\t%h0";
6351       else
6352         {
6353           gcc_assert (operands[2] == constm1_rtx
6354                       || (GET_CODE (operands[2]) == CONST_INT
6355                           && INTVAL (operands[2]) == 255));
6356           return "dec{b}\t%h0";
6357         }
6359     default:
6360       return "add{b}\t{%2, %h0|%h0, %2}";
6361     }
6363   [(set (attr "type")
6364      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6365         (const_string "incdec")
6366         (const_string "alu")))
6367    (set_attr "mode" "QI")])
6369 (define_insn "*addqi_ext_1_rex64"
6370   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6371                          (const_int 8)
6372                          (const_int 8))
6373         (plus:SI
6374           (zero_extract:SI
6375             (match_operand 1 "ext_register_operand" "0")
6376             (const_int 8)
6377             (const_int 8))
6378           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6379    (clobber (reg:CC FLAGS_REG))]
6380   "TARGET_64BIT"
6382   switch (get_attr_type (insn))
6383     {
6384     case TYPE_INCDEC:
6385       if (operands[2] == const1_rtx)
6386         return "inc{b}\t%h0";
6387       else
6388         {
6389           gcc_assert (operands[2] == constm1_rtx
6390                       || (GET_CODE (operands[2]) == CONST_INT
6391                           && INTVAL (operands[2]) == 255));
6392           return "dec{b}\t%h0";
6393         }
6395     default:
6396       return "add{b}\t{%2, %h0|%h0, %2}";
6397     }
6399   [(set (attr "type")
6400      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6401         (const_string "incdec")
6402         (const_string "alu")))
6403    (set_attr "mode" "QI")])
6405 (define_insn "*addqi_ext_2"
6406   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6407                          (const_int 8)
6408                          (const_int 8))
6409         (plus:SI
6410           (zero_extract:SI
6411             (match_operand 1 "ext_register_operand" "%0")
6412             (const_int 8)
6413             (const_int 8))
6414           (zero_extract:SI
6415             (match_operand 2 "ext_register_operand" "Q")
6416             (const_int 8)
6417             (const_int 8))))
6418    (clobber (reg:CC FLAGS_REG))]
6419   ""
6420   "add{b}\t{%h2, %h0|%h0, %h2}"
6421   [(set_attr "type" "alu")
6422    (set_attr "mode" "QI")])
6424 ;; The patterns that match these are at the end of this file.
6426 (define_expand "addxf3"
6427   [(set (match_operand:XF 0 "register_operand" "")
6428         (plus:XF (match_operand:XF 1 "register_operand" "")
6429                  (match_operand:XF 2 "register_operand" "")))]
6430   "TARGET_80387"
6431   "")
6433 (define_expand "adddf3"
6434   [(set (match_operand:DF 0 "register_operand" "")
6435         (plus:DF (match_operand:DF 1 "register_operand" "")
6436                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6437   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6438   "")
6440 (define_expand "addsf3"
6441   [(set (match_operand:SF 0 "register_operand" "")
6442         (plus:SF (match_operand:SF 1 "register_operand" "")
6443                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6444   "TARGET_80387 || TARGET_SSE_MATH"
6445   "")
6447 ;; Subtract instructions
6449 ;; %%% splits for subditi3
6451 (define_expand "subti3"
6452   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6453                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6454                              (match_operand:TI 2 "x86_64_general_operand" "")))
6455               (clobber (reg:CC FLAGS_REG))])]
6456   "TARGET_64BIT"
6457   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6459 (define_insn "*subti3_1"
6460   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6461         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6462                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6463    (clobber (reg:CC FLAGS_REG))]
6464   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6465   "#")
6467 (define_split
6468   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6469         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6470                   (match_operand:TI 2 "general_operand" "")))
6471    (clobber (reg:CC FLAGS_REG))]
6472   "TARGET_64BIT && reload_completed"
6473   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6474               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6475    (parallel [(set (match_dup 3)
6476                    (minus:DI (match_dup 4)
6477                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6478                                       (match_dup 5))))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   "split_ti (operands+0, 1, operands+0, operands+3);
6481    split_ti (operands+1, 1, operands+1, operands+4);
6482    split_ti (operands+2, 1, operands+2, operands+5);")
6484 ;; %%% splits for subsidi3
6486 (define_expand "subdi3"
6487   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6488                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6489                              (match_operand:DI 2 "x86_64_general_operand" "")))
6490               (clobber (reg:CC FLAGS_REG))])]
6491   ""
6492   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6494 (define_insn "*subdi3_1"
6495   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6496         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6497                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6498    (clobber (reg:CC FLAGS_REG))]
6499   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6500   "#")
6502 (define_split
6503   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6504         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6505                   (match_operand:DI 2 "general_operand" "")))
6506    (clobber (reg:CC FLAGS_REG))]
6507   "!TARGET_64BIT && reload_completed"
6508   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6509               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6510    (parallel [(set (match_dup 3)
6511                    (minus:SI (match_dup 4)
6512                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6513                                       (match_dup 5))))
6514               (clobber (reg:CC FLAGS_REG))])]
6515   "split_di (operands+0, 1, operands+0, operands+3);
6516    split_di (operands+1, 1, operands+1, operands+4);
6517    split_di (operands+2, 1, operands+2, operands+5);")
6519 (define_insn "subdi3_carry_rex64"
6520   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6521           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6522             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6523                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6524    (clobber (reg:CC FLAGS_REG))]
6525   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6526   "sbb{q}\t{%2, %0|%0, %2}"
6527   [(set_attr "type" "alu")
6528    (set_attr "pent_pair" "pu")
6529    (set_attr "mode" "DI")])
6531 (define_insn "*subdi_1_rex64"
6532   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6533         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6534                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6535    (clobber (reg:CC FLAGS_REG))]
6536   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6537   "sub{q}\t{%2, %0|%0, %2}"
6538   [(set_attr "type" "alu")
6539    (set_attr "mode" "DI")])
6541 (define_insn "*subdi_2_rex64"
6542   [(set (reg FLAGS_REG)
6543         (compare
6544           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6545                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6546           (const_int 0)))
6547    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6548         (minus:DI (match_dup 1) (match_dup 2)))]
6549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6550    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6551   "sub{q}\t{%2, %0|%0, %2}"
6552   [(set_attr "type" "alu")
6553    (set_attr "mode" "DI")])
6555 (define_insn "*subdi_3_rex63"
6556   [(set (reg FLAGS_REG)
6557         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6560         (minus:DI (match_dup 1) (match_dup 2)))]
6561   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6562    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6563   "sub{q}\t{%2, %0|%0, %2}"
6564   [(set_attr "type" "alu")
6565    (set_attr "mode" "DI")])
6567 (define_insn "subqi3_carry"
6568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6569           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6570             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6571                (match_operand:QI 2 "general_operand" "qi,qm"))))
6572    (clobber (reg:CC FLAGS_REG))]
6573   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6574   "sbb{b}\t{%2, %0|%0, %2}"
6575   [(set_attr "type" "alu")
6576    (set_attr "pent_pair" "pu")
6577    (set_attr "mode" "QI")])
6579 (define_insn "subhi3_carry"
6580   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6581           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6582             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6583                (match_operand:HI 2 "general_operand" "ri,rm"))))
6584    (clobber (reg:CC FLAGS_REG))]
6585   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6586   "sbb{w}\t{%2, %0|%0, %2}"
6587   [(set_attr "type" "alu")
6588    (set_attr "pent_pair" "pu")
6589    (set_attr "mode" "HI")])
6591 (define_insn "subsi3_carry"
6592   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6593           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6594             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6595                (match_operand:SI 2 "general_operand" "ri,rm"))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6598   "sbb{l}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "pent_pair" "pu")
6601    (set_attr "mode" "SI")])
6603 (define_insn "subsi3_carry_zext"
6604   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6605           (zero_extend:DI
6606             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6607               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6608                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6609    (clobber (reg:CC FLAGS_REG))]
6610   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6611   "sbb{l}\t{%2, %k0|%k0, %2}"
6612   [(set_attr "type" "alu")
6613    (set_attr "pent_pair" "pu")
6614    (set_attr "mode" "SI")])
6616 (define_expand "subsi3"
6617   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6618                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6619                              (match_operand:SI 2 "general_operand" "")))
6620               (clobber (reg:CC FLAGS_REG))])]
6621   ""
6622   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6624 (define_insn "*subsi_1"
6625   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6626         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6627                   (match_operand:SI 2 "general_operand" "ri,rm")))
6628    (clobber (reg:CC FLAGS_REG))]
6629   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6630   "sub{l}\t{%2, %0|%0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "SI")])
6634 (define_insn "*subsi_1_zext"
6635   [(set (match_operand:DI 0 "register_operand" "=r")
6636         (zero_extend:DI
6637           (minus:SI (match_operand:SI 1 "register_operand" "0")
6638                     (match_operand:SI 2 "general_operand" "rim"))))
6639    (clobber (reg:CC FLAGS_REG))]
6640   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641   "sub{l}\t{%2, %k0|%k0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "mode" "SI")])
6645 (define_insn "*subsi_2"
6646   [(set (reg FLAGS_REG)
6647         (compare
6648           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6649                     (match_operand:SI 2 "general_operand" "ri,rm"))
6650           (const_int 0)))
6651    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6652         (minus:SI (match_dup 1) (match_dup 2)))]
6653   "ix86_match_ccmode (insn, CCGOCmode)
6654    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6655   "sub{l}\t{%2, %0|%0, %2}"
6656   [(set_attr "type" "alu")
6657    (set_attr "mode" "SI")])
6659 (define_insn "*subsi_2_zext"
6660   [(set (reg FLAGS_REG)
6661         (compare
6662           (minus:SI (match_operand:SI 1 "register_operand" "0")
6663                     (match_operand:SI 2 "general_operand" "rim"))
6664           (const_int 0)))
6665    (set (match_operand:DI 0 "register_operand" "=r")
6666         (zero_extend:DI
6667           (minus:SI (match_dup 1)
6668                     (match_dup 2))))]
6669   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6670    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6671   "sub{l}\t{%2, %k0|%k0, %2}"
6672   [(set_attr "type" "alu")
6673    (set_attr "mode" "SI")])
6675 (define_insn "*subsi_3"
6676   [(set (reg FLAGS_REG)
6677         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6678                  (match_operand:SI 2 "general_operand" "ri,rm")))
6679    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6680         (minus:SI (match_dup 1) (match_dup 2)))]
6681   "ix86_match_ccmode (insn, CCmode)
6682    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6683   "sub{l}\t{%2, %0|%0, %2}"
6684   [(set_attr "type" "alu")
6685    (set_attr "mode" "SI")])
6687 (define_insn "*subsi_3_zext"
6688   [(set (reg FLAGS_REG)
6689         (compare (match_operand:SI 1 "register_operand" "0")
6690                  (match_operand:SI 2 "general_operand" "rim")))
6691    (set (match_operand:DI 0 "register_operand" "=r")
6692         (zero_extend:DI
6693           (minus:SI (match_dup 1)
6694                     (match_dup 2))))]
6695   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6696    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6697   "sub{q}\t{%2, %0|%0, %2}"
6698   [(set_attr "type" "alu")
6699    (set_attr "mode" "DI")])
6701 (define_expand "subhi3"
6702   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6703                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6704                              (match_operand:HI 2 "general_operand" "")))
6705               (clobber (reg:CC FLAGS_REG))])]
6706   "TARGET_HIMODE_MATH"
6707   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6709 (define_insn "*subhi_1"
6710   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6711         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6712                   (match_operand:HI 2 "general_operand" "ri,rm")))
6713    (clobber (reg:CC FLAGS_REG))]
6714   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6715   "sub{w}\t{%2, %0|%0, %2}"
6716   [(set_attr "type" "alu")
6717    (set_attr "mode" "HI")])
6719 (define_insn "*subhi_2"
6720   [(set (reg FLAGS_REG)
6721         (compare
6722           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6723                     (match_operand:HI 2 "general_operand" "ri,rm"))
6724           (const_int 0)))
6725    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6726         (minus:HI (match_dup 1) (match_dup 2)))]
6727   "ix86_match_ccmode (insn, CCGOCmode)
6728    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6729   "sub{w}\t{%2, %0|%0, %2}"
6730   [(set_attr "type" "alu")
6731    (set_attr "mode" "HI")])
6733 (define_insn "*subhi_3"
6734   [(set (reg FLAGS_REG)
6735         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736                  (match_operand:HI 2 "general_operand" "ri,rm")))
6737    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6738         (minus:HI (match_dup 1) (match_dup 2)))]
6739   "ix86_match_ccmode (insn, CCmode)
6740    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6741   "sub{w}\t{%2, %0|%0, %2}"
6742   [(set_attr "type" "alu")
6743    (set_attr "mode" "HI")])
6745 (define_expand "subqi3"
6746   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6747                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6748                              (match_operand:QI 2 "general_operand" "")))
6749               (clobber (reg:CC FLAGS_REG))])]
6750   "TARGET_QIMODE_MATH"
6751   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6753 (define_insn "*subqi_1"
6754   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6755         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6756                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6757    (clobber (reg:CC FLAGS_REG))]
6758   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6759   "sub{b}\t{%2, %0|%0, %2}"
6760   [(set_attr "type" "alu")
6761    (set_attr "mode" "QI")])
6763 (define_insn "*subqi_1_slp"
6764   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6765         (minus:QI (match_dup 0)
6766                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6767    (clobber (reg:CC FLAGS_REG))]
6768   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6769    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6770   "sub{b}\t{%1, %0|%0, %1}"
6771   [(set_attr "type" "alu1")
6772    (set_attr "mode" "QI")])
6774 (define_insn "*subqi_2"
6775   [(set (reg FLAGS_REG)
6776         (compare
6777           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6778                     (match_operand:QI 2 "general_operand" "qi,qm"))
6779           (const_int 0)))
6780    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6781         (minus:HI (match_dup 1) (match_dup 2)))]
6782   "ix86_match_ccmode (insn, CCGOCmode)
6783    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6784   "sub{b}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "QI")])
6788 (define_insn "*subqi_3"
6789   [(set (reg FLAGS_REG)
6790         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6791                  (match_operand:QI 2 "general_operand" "qi,qm")))
6792    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6793         (minus:HI (match_dup 1) (match_dup 2)))]
6794   "ix86_match_ccmode (insn, CCmode)
6795    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6796   "sub{b}\t{%2, %0|%0, %2}"
6797   [(set_attr "type" "alu")
6798    (set_attr "mode" "QI")])
6800 ;; The patterns that match these are at the end of this file.
6802 (define_expand "subxf3"
6803   [(set (match_operand:XF 0 "register_operand" "")
6804         (minus:XF (match_operand:XF 1 "register_operand" "")
6805                   (match_operand:XF 2 "register_operand" "")))]
6806   "TARGET_80387"
6807   "")
6809 (define_expand "subdf3"
6810   [(set (match_operand:DF 0 "register_operand" "")
6811         (minus:DF (match_operand:DF 1 "register_operand" "")
6812                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6813   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6814   "")
6816 (define_expand "subsf3"
6817   [(set (match_operand:SF 0 "register_operand" "")
6818         (minus:SF (match_operand:SF 1 "register_operand" "")
6819                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6820   "TARGET_80387 || TARGET_SSE_MATH"
6821   "")
6823 ;; Multiply instructions
6825 (define_expand "muldi3"
6826   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6827                    (mult:DI (match_operand:DI 1 "register_operand" "")
6828                             (match_operand:DI 2 "x86_64_general_operand" "")))
6829               (clobber (reg:CC FLAGS_REG))])]
6830   "TARGET_64BIT"
6831   "")
6833 (define_insn "*muldi3_1_rex64"
6834   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6835         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6836                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6837    (clobber (reg:CC FLAGS_REG))]
6838   "TARGET_64BIT
6839    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6840   "@
6841    imul{q}\t{%2, %1, %0|%0, %1, %2}
6842    imul{q}\t{%2, %1, %0|%0, %1, %2}
6843    imul{q}\t{%2, %0|%0, %2}"
6844   [(set_attr "type" "imul")
6845    (set_attr "prefix_0f" "0,0,1")
6846    (set (attr "athlon_decode")
6847         (cond [(eq_attr "cpu" "athlon")
6848                   (const_string "vector")
6849                (eq_attr "alternative" "1")
6850                   (const_string "vector")
6851                (and (eq_attr "alternative" "2")
6852                     (match_operand 1 "memory_operand" ""))
6853                   (const_string "vector")]
6854               (const_string "direct")))
6855    (set_attr "mode" "DI")])
6857 (define_expand "mulsi3"
6858   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6859                    (mult:SI (match_operand:SI 1 "register_operand" "")
6860                             (match_operand:SI 2 "general_operand" "")))
6861               (clobber (reg:CC FLAGS_REG))])]
6862   ""
6863   "")
6865 (define_insn "*mulsi3_1"
6866   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6867         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6868                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6869    (clobber (reg:CC FLAGS_REG))]
6870   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6871   "@
6872    imul{l}\t{%2, %1, %0|%0, %1, %2}
6873    imul{l}\t{%2, %1, %0|%0, %1, %2}
6874    imul{l}\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" "SI")])
6888 (define_insn "*mulsi3_1_zext"
6889   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6890         (zero_extend:DI
6891           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6893    (clobber (reg:CC FLAGS_REG))]
6894   "TARGET_64BIT
6895    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6896   "@
6897    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6898    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6899    imul{l}\t{%2, %k0|%k0, %2}"
6900   [(set_attr "type" "imul")
6901    (set_attr "prefix_0f" "0,0,1")
6902    (set (attr "athlon_decode")
6903         (cond [(eq_attr "cpu" "athlon")
6904                   (const_string "vector")
6905                (eq_attr "alternative" "1")
6906                   (const_string "vector")
6907                (and (eq_attr "alternative" "2")
6908                     (match_operand 1 "memory_operand" ""))
6909                   (const_string "vector")]
6910               (const_string "direct")))
6911    (set_attr "mode" "SI")])
6913 (define_expand "mulhi3"
6914   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6915                    (mult:HI (match_operand:HI 1 "register_operand" "")
6916                             (match_operand:HI 2 "general_operand" "")))
6917               (clobber (reg:CC FLAGS_REG))])]
6918   "TARGET_HIMODE_MATH"
6919   "")
6921 (define_insn "*mulhi3_1"
6922   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6923         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6924                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6925    (clobber (reg:CC FLAGS_REG))]
6926   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6927   "@
6928    imul{w}\t{%2, %1, %0|%0, %1, %2}
6929    imul{w}\t{%2, %1, %0|%0, %1, %2}
6930    imul{w}\t{%2, %0|%0, %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,2")
6937                   (const_string "vector")]
6938               (const_string "direct")))
6939    (set_attr "mode" "HI")])
6941 (define_expand "mulqi3"
6942   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6943                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6944                             (match_operand:QI 2 "register_operand" "")))
6945               (clobber (reg:CC FLAGS_REG))])]
6946   "TARGET_QIMODE_MATH"
6947   "")
6949 (define_insn "*mulqi3_1"
6950   [(set (match_operand:QI 0 "register_operand" "=a")
6951         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6952                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6953    (clobber (reg:CC FLAGS_REG))]
6954   "TARGET_QIMODE_MATH
6955    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6956   "mul{b}\t%2"
6957   [(set_attr "type" "imul")
6958    (set_attr "length_immediate" "0")
6959    (set (attr "athlon_decode")
6960      (if_then_else (eq_attr "cpu" "athlon")
6961         (const_string "vector")
6962         (const_string "direct")))
6963    (set_attr "mode" "QI")])
6965 (define_expand "umulqihi3"
6966   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6967                    (mult:HI (zero_extend:HI
6968                               (match_operand:QI 1 "nonimmediate_operand" ""))
6969                             (zero_extend:HI
6970                               (match_operand:QI 2 "register_operand" ""))))
6971               (clobber (reg:CC FLAGS_REG))])]
6972   "TARGET_QIMODE_MATH"
6973   "")
6975 (define_insn "*umulqihi3_1"
6976   [(set (match_operand:HI 0 "register_operand" "=a")
6977         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6978                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6979    (clobber (reg:CC FLAGS_REG))]
6980   "TARGET_QIMODE_MATH
6981    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6982   "mul{b}\t%2"
6983   [(set_attr "type" "imul")
6984    (set_attr "length_immediate" "0")
6985    (set (attr "athlon_decode")
6986      (if_then_else (eq_attr "cpu" "athlon")
6987         (const_string "vector")
6988         (const_string "direct")))
6989    (set_attr "mode" "QI")])
6991 (define_expand "mulqihi3"
6992   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6993                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6994                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6995               (clobber (reg:CC FLAGS_REG))])]
6996   "TARGET_QIMODE_MATH"
6997   "")
6999 (define_insn "*mulqihi3_insn"
7000   [(set (match_operand:HI 0 "register_operand" "=a")
7001         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "TARGET_QIMODE_MATH
7005    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006   "imul{b}\t%2"
7007   [(set_attr "type" "imul")
7008    (set_attr "length_immediate" "0")
7009    (set (attr "athlon_decode")
7010      (if_then_else (eq_attr "cpu" "athlon")
7011         (const_string "vector")
7012         (const_string "direct")))
7013    (set_attr "mode" "QI")])
7015 (define_expand "umulditi3"
7016   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7017                    (mult:TI (zero_extend:TI
7018                               (match_operand:DI 1 "nonimmediate_operand" ""))
7019                             (zero_extend:TI
7020                               (match_operand:DI 2 "register_operand" ""))))
7021               (clobber (reg:CC FLAGS_REG))])]
7022   "TARGET_64BIT"
7023   "")
7025 (define_insn "*umulditi3_insn"
7026   [(set (match_operand:TI 0 "register_operand" "=A")
7027         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7028                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7029    (clobber (reg:CC FLAGS_REG))]
7030   "TARGET_64BIT
7031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7032   "mul{q}\t%2"
7033   [(set_attr "type" "imul")
7034    (set_attr "length_immediate" "0")
7035    (set (attr "athlon_decode")
7036      (if_then_else (eq_attr "cpu" "athlon")
7037         (const_string "vector")
7038         (const_string "double")))
7039    (set_attr "mode" "DI")])
7041 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7042 (define_expand "umulsidi3"
7043   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7044                    (mult:DI (zero_extend:DI
7045                               (match_operand:SI 1 "nonimmediate_operand" ""))
7046                             (zero_extend:DI
7047                               (match_operand:SI 2 "register_operand" ""))))
7048               (clobber (reg:CC FLAGS_REG))])]
7049   "!TARGET_64BIT"
7050   "")
7052 (define_insn "*umulsidi3_insn"
7053   [(set (match_operand:DI 0 "register_operand" "=A")
7054         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7055                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7056    (clobber (reg:CC FLAGS_REG))]
7057   "!TARGET_64BIT
7058    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7059   "mul{l}\t%2"
7060   [(set_attr "type" "imul")
7061    (set_attr "length_immediate" "0")
7062    (set (attr "athlon_decode")
7063      (if_then_else (eq_attr "cpu" "athlon")
7064         (const_string "vector")
7065         (const_string "double")))
7066    (set_attr "mode" "SI")])
7068 (define_expand "mulditi3"
7069   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7070                    (mult:TI (sign_extend:TI
7071                               (match_operand:DI 1 "nonimmediate_operand" ""))
7072                             (sign_extend:TI
7073                               (match_operand:DI 2 "register_operand" ""))))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   "TARGET_64BIT"
7076   "")
7078 (define_insn "*mulditi3_insn"
7079   [(set (match_operand:TI 0 "register_operand" "=A")
7080         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7081                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_64BIT
7084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7085   "imul{q}\t%2"
7086   [(set_attr "type" "imul")
7087    (set_attr "length_immediate" "0")
7088    (set (attr "athlon_decode")
7089      (if_then_else (eq_attr "cpu" "athlon")
7090         (const_string "vector")
7091         (const_string "double")))
7092    (set_attr "mode" "DI")])
7094 (define_expand "mulsidi3"
7095   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7096                    (mult:DI (sign_extend:DI
7097                               (match_operand:SI 1 "nonimmediate_operand" ""))
7098                             (sign_extend:DI
7099                               (match_operand:SI 2 "register_operand" ""))))
7100               (clobber (reg:CC FLAGS_REG))])]
7101   "!TARGET_64BIT"
7102   "")
7104 (define_insn "*mulsidi3_insn"
7105   [(set (match_operand:DI 0 "register_operand" "=A")
7106         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7107                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "!TARGET_64BIT
7110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111   "imul{l}\t%2"
7112   [(set_attr "type" "imul")
7113    (set_attr "length_immediate" "0")
7114    (set (attr "athlon_decode")
7115      (if_then_else (eq_attr "cpu" "athlon")
7116         (const_string "vector")
7117         (const_string "double")))
7118    (set_attr "mode" "SI")])
7120 (define_expand "umuldi3_highpart"
7121   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7122                    (truncate:DI
7123                      (lshiftrt:TI
7124                        (mult:TI (zero_extend:TI
7125                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7126                                 (zero_extend:TI
7127                                   (match_operand:DI 2 "register_operand" "")))
7128                        (const_int 64))))
7129               (clobber (match_scratch:DI 3 ""))
7130               (clobber (reg:CC FLAGS_REG))])]
7131   "TARGET_64BIT"
7132   "")
7134 (define_insn "*umuldi3_highpart_rex64"
7135   [(set (match_operand:DI 0 "register_operand" "=d")
7136         (truncate:DI
7137           (lshiftrt:TI
7138             (mult:TI (zero_extend:TI
7139                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7140                      (zero_extend:TI
7141                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7142             (const_int 64))))
7143    (clobber (match_scratch:DI 3 "=1"))
7144    (clobber (reg:CC FLAGS_REG))]
7145   "TARGET_64BIT
7146    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7147   "mul{q}\t%2"
7148   [(set_attr "type" "imul")
7149    (set_attr "length_immediate" "0")
7150    (set (attr "athlon_decode")
7151      (if_then_else (eq_attr "cpu" "athlon")
7152         (const_string "vector")
7153         (const_string "double")))
7154    (set_attr "mode" "DI")])
7156 (define_expand "umulsi3_highpart"
7157   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7158                    (truncate:SI
7159                      (lshiftrt:DI
7160                        (mult:DI (zero_extend:DI
7161                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7162                                 (zero_extend:DI
7163                                   (match_operand:SI 2 "register_operand" "")))
7164                        (const_int 32))))
7165               (clobber (match_scratch:SI 3 ""))
7166               (clobber (reg:CC FLAGS_REG))])]
7167   ""
7168   "")
7170 (define_insn "*umulsi3_highpart_insn"
7171   [(set (match_operand:SI 0 "register_operand" "=d")
7172         (truncate:SI
7173           (lshiftrt:DI
7174             (mult:DI (zero_extend:DI
7175                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7176                      (zero_extend:DI
7177                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7178             (const_int 32))))
7179    (clobber (match_scratch:SI 3 "=1"))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7182   "mul{l}\t%2"
7183   [(set_attr "type" "imul")
7184    (set_attr "length_immediate" "0")
7185    (set (attr "athlon_decode")
7186      (if_then_else (eq_attr "cpu" "athlon")
7187         (const_string "vector")
7188         (const_string "double")))
7189    (set_attr "mode" "SI")])
7191 (define_insn "*umulsi3_highpart_zext"
7192   [(set (match_operand:DI 0 "register_operand" "=d")
7193         (zero_extend:DI (truncate:SI
7194           (lshiftrt:DI
7195             (mult:DI (zero_extend:DI
7196                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7197                      (zero_extend:DI
7198                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7199             (const_int 32)))))
7200    (clobber (match_scratch:SI 3 "=1"))
7201    (clobber (reg:CC FLAGS_REG))]
7202   "TARGET_64BIT
7203    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7204   "mul{l}\t%2"
7205   [(set_attr "type" "imul")
7206    (set_attr "length_immediate" "0")
7207    (set (attr "athlon_decode")
7208      (if_then_else (eq_attr "cpu" "athlon")
7209         (const_string "vector")
7210         (const_string "double")))
7211    (set_attr "mode" "SI")])
7213 (define_expand "smuldi3_highpart"
7214   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7215                    (truncate:DI
7216                      (lshiftrt:TI
7217                        (mult:TI (sign_extend:TI
7218                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7219                                 (sign_extend:TI
7220                                   (match_operand:DI 2 "register_operand" "")))
7221                        (const_int 64))))
7222               (clobber (match_scratch:DI 3 ""))
7223               (clobber (reg:CC FLAGS_REG))])]
7224   "TARGET_64BIT"
7225   "")
7227 (define_insn "*smuldi3_highpart_rex64"
7228   [(set (match_operand:DI 0 "register_operand" "=d")
7229         (truncate:DI
7230           (lshiftrt:TI
7231             (mult:TI (sign_extend:TI
7232                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7233                      (sign_extend:TI
7234                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7235             (const_int 64))))
7236    (clobber (match_scratch:DI 3 "=1"))
7237    (clobber (reg:CC FLAGS_REG))]
7238   "TARGET_64BIT
7239    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7240   "imul{q}\t%2"
7241   [(set_attr "type" "imul")
7242    (set (attr "athlon_decode")
7243      (if_then_else (eq_attr "cpu" "athlon")
7244         (const_string "vector")
7245         (const_string "double")))
7246    (set_attr "mode" "DI")])
7248 (define_expand "smulsi3_highpart"
7249   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7250                    (truncate:SI
7251                      (lshiftrt:DI
7252                        (mult:DI (sign_extend:DI
7253                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7254                                 (sign_extend:DI
7255                                   (match_operand:SI 2 "register_operand" "")))
7256                        (const_int 32))))
7257               (clobber (match_scratch:SI 3 ""))
7258               (clobber (reg:CC FLAGS_REG))])]
7259   ""
7260   "")
7262 (define_insn "*smulsi3_highpart_insn"
7263   [(set (match_operand:SI 0 "register_operand" "=d")
7264         (truncate:SI
7265           (lshiftrt:DI
7266             (mult:DI (sign_extend:DI
7267                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7268                      (sign_extend:DI
7269                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7270             (const_int 32))))
7271    (clobber (match_scratch:SI 3 "=1"))
7272    (clobber (reg:CC FLAGS_REG))]
7273   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7274   "imul{l}\t%2"
7275   [(set_attr "type" "imul")
7276    (set (attr "athlon_decode")
7277      (if_then_else (eq_attr "cpu" "athlon")
7278         (const_string "vector")
7279         (const_string "double")))
7280    (set_attr "mode" "SI")])
7282 (define_insn "*smulsi3_highpart_zext"
7283   [(set (match_operand:DI 0 "register_operand" "=d")
7284         (zero_extend:DI (truncate:SI
7285           (lshiftrt:DI
7286             (mult:DI (sign_extend:DI
7287                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7288                      (sign_extend:DI
7289                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7290             (const_int 32)))))
7291    (clobber (match_scratch:SI 3 "=1"))
7292    (clobber (reg:CC FLAGS_REG))]
7293   "TARGET_64BIT
7294    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7295   "imul{l}\t%2"
7296   [(set_attr "type" "imul")
7297    (set (attr "athlon_decode")
7298      (if_then_else (eq_attr "cpu" "athlon")
7299         (const_string "vector")
7300         (const_string "double")))
7301    (set_attr "mode" "SI")])
7303 ;; The patterns that match these are at the end of this file.
7305 (define_expand "mulxf3"
7306   [(set (match_operand:XF 0 "register_operand" "")
7307         (mult:XF (match_operand:XF 1 "register_operand" "")
7308                  (match_operand:XF 2 "register_operand" "")))]
7309   "TARGET_80387"
7310   "")
7312 (define_expand "muldf3"
7313   [(set (match_operand:DF 0 "register_operand" "")
7314         (mult:DF (match_operand:DF 1 "register_operand" "")
7315                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7316   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7317   "")
7319 (define_expand "mulsf3"
7320   [(set (match_operand:SF 0 "register_operand" "")
7321         (mult:SF (match_operand:SF 1 "register_operand" "")
7322                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7323   "TARGET_80387 || TARGET_SSE_MATH"
7324   "")
7326 ;; Divide instructions
7328 (define_insn "divqi3"
7329   [(set (match_operand:QI 0 "register_operand" "=a")
7330         (div:QI (match_operand:HI 1 "register_operand" "0")
7331                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "TARGET_QIMODE_MATH"
7334   "idiv{b}\t%2"
7335   [(set_attr "type" "idiv")
7336    (set_attr "mode" "QI")])
7338 (define_insn "udivqi3"
7339   [(set (match_operand:QI 0 "register_operand" "=a")
7340         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7341                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7342    (clobber (reg:CC FLAGS_REG))]
7343   "TARGET_QIMODE_MATH"
7344   "div{b}\t%2"
7345   [(set_attr "type" "idiv")
7346    (set_attr "mode" "QI")])
7348 ;; The patterns that match these are at the end of this file.
7350 (define_expand "divxf3"
7351   [(set (match_operand:XF 0 "register_operand" "")
7352         (div:XF (match_operand:XF 1 "register_operand" "")
7353                 (match_operand:XF 2 "register_operand" "")))]
7354   "TARGET_80387"
7355   "")
7357 (define_expand "divdf3"
7358   [(set (match_operand:DF 0 "register_operand" "")
7359         (div:DF (match_operand:DF 1 "register_operand" "")
7360                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7361    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7362    "")
7364 (define_expand "divsf3"
7365   [(set (match_operand:SF 0 "register_operand" "")
7366         (div:SF (match_operand:SF 1 "register_operand" "")
7367                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7368   "TARGET_80387 || TARGET_SSE_MATH"
7369   "")
7371 ;; Remainder instructions.
7373 (define_expand "divmoddi4"
7374   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7375                    (div:DI (match_operand:DI 1 "register_operand" "")
7376                            (match_operand:DI 2 "nonimmediate_operand" "")))
7377               (set (match_operand:DI 3 "register_operand" "")
7378                    (mod:DI (match_dup 1) (match_dup 2)))
7379               (clobber (reg:CC FLAGS_REG))])]
7380   "TARGET_64BIT"
7381   "")
7383 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7384 ;; Penalize eax case slightly because it results in worse scheduling
7385 ;; of code.
7386 (define_insn "*divmoddi4_nocltd_rex64"
7387   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7388         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7389                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7390    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7391         (mod:DI (match_dup 2) (match_dup 3)))
7392    (clobber (reg:CC FLAGS_REG))]
7393   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7394   "#"
7395   [(set_attr "type" "multi")])
7397 (define_insn "*divmoddi4_cltd_rex64"
7398   [(set (match_operand:DI 0 "register_operand" "=a")
7399         (div:DI (match_operand:DI 2 "register_operand" "a")
7400                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7401    (set (match_operand:DI 1 "register_operand" "=&d")
7402         (mod:DI (match_dup 2) (match_dup 3)))
7403    (clobber (reg:CC FLAGS_REG))]
7404   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7405   "#"
7406   [(set_attr "type" "multi")])
7408 (define_insn "*divmoddi_noext_rex64"
7409   [(set (match_operand:DI 0 "register_operand" "=a")
7410         (div:DI (match_operand:DI 1 "register_operand" "0")
7411                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7412    (set (match_operand:DI 3 "register_operand" "=d")
7413         (mod:DI (match_dup 1) (match_dup 2)))
7414    (use (match_operand:DI 4 "register_operand" "3"))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT"
7417   "idiv{q}\t%2"
7418   [(set_attr "type" "idiv")
7419    (set_attr "mode" "DI")])
7421 (define_split
7422   [(set (match_operand:DI 0 "register_operand" "")
7423         (div:DI (match_operand:DI 1 "register_operand" "")
7424                 (match_operand:DI 2 "nonimmediate_operand" "")))
7425    (set (match_operand:DI 3 "register_operand" "")
7426         (mod:DI (match_dup 1) (match_dup 2)))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_64BIT && reload_completed"
7429   [(parallel [(set (match_dup 3)
7430                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7431               (clobber (reg:CC FLAGS_REG))])
7432    (parallel [(set (match_dup 0)
7433                    (div:DI (reg:DI 0) (match_dup 2)))
7434               (set (match_dup 3)
7435                    (mod:DI (reg:DI 0) (match_dup 2)))
7436               (use (match_dup 3))
7437               (clobber (reg:CC FLAGS_REG))])]
7439   /* Avoid use of cltd in favor of a mov+shift.  */
7440   if (!TARGET_USE_CLTD && !optimize_size)
7441     {
7442       if (true_regnum (operands[1]))
7443         emit_move_insn (operands[0], operands[1]);
7444       else
7445         emit_move_insn (operands[3], operands[1]);
7446       operands[4] = operands[3];
7447     }
7448   else
7449     {
7450       gcc_assert (!true_regnum (operands[1]));
7451       operands[4] = operands[1];
7452     }
7456 (define_expand "divmodsi4"
7457   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7458                    (div:SI (match_operand:SI 1 "register_operand" "")
7459                            (match_operand:SI 2 "nonimmediate_operand" "")))
7460               (set (match_operand:SI 3 "register_operand" "")
7461                    (mod:SI (match_dup 1) (match_dup 2)))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   ""
7464   "")
7466 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7467 ;; Penalize eax case slightly because it results in worse scheduling
7468 ;; of code.
7469 (define_insn "*divmodsi4_nocltd"
7470   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7471         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7472                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7473    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7474         (mod:SI (match_dup 2) (match_dup 3)))
7475    (clobber (reg:CC FLAGS_REG))]
7476   "!optimize_size && !TARGET_USE_CLTD"
7477   "#"
7478   [(set_attr "type" "multi")])
7480 (define_insn "*divmodsi4_cltd"
7481   [(set (match_operand:SI 0 "register_operand" "=a")
7482         (div:SI (match_operand:SI 2 "register_operand" "a")
7483                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7484    (set (match_operand:SI 1 "register_operand" "=&d")
7485         (mod:SI (match_dup 2) (match_dup 3)))
7486    (clobber (reg:CC FLAGS_REG))]
7487   "optimize_size || TARGET_USE_CLTD"
7488   "#"
7489   [(set_attr "type" "multi")])
7491 (define_insn "*divmodsi_noext"
7492   [(set (match_operand:SI 0 "register_operand" "=a")
7493         (div:SI (match_operand:SI 1 "register_operand" "0")
7494                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7495    (set (match_operand:SI 3 "register_operand" "=d")
7496         (mod:SI (match_dup 1) (match_dup 2)))
7497    (use (match_operand:SI 4 "register_operand" "3"))
7498    (clobber (reg:CC FLAGS_REG))]
7499   ""
7500   "idiv{l}\t%2"
7501   [(set_attr "type" "idiv")
7502    (set_attr "mode" "SI")])
7504 (define_split
7505   [(set (match_operand:SI 0 "register_operand" "")
7506         (div:SI (match_operand:SI 1 "register_operand" "")
7507                 (match_operand:SI 2 "nonimmediate_operand" "")))
7508    (set (match_operand:SI 3 "register_operand" "")
7509         (mod:SI (match_dup 1) (match_dup 2)))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "reload_completed"
7512   [(parallel [(set (match_dup 3)
7513                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7514               (clobber (reg:CC FLAGS_REG))])
7515    (parallel [(set (match_dup 0)
7516                    (div:SI (reg:SI 0) (match_dup 2)))
7517               (set (match_dup 3)
7518                    (mod:SI (reg:SI 0) (match_dup 2)))
7519               (use (match_dup 3))
7520               (clobber (reg:CC FLAGS_REG))])]
7522   /* Avoid use of cltd in favor of a mov+shift.  */
7523   if (!TARGET_USE_CLTD && !optimize_size)
7524     {
7525       if (true_regnum (operands[1]))
7526         emit_move_insn (operands[0], operands[1]);
7527       else
7528         emit_move_insn (operands[3], operands[1]);
7529       operands[4] = operands[3];
7530     }
7531   else
7532     {
7533       gcc_assert (!true_regnum (operands[1]));
7534       operands[4] = operands[1];
7535     }
7537 ;; %%% Split me.
7538 (define_insn "divmodhi4"
7539   [(set (match_operand:HI 0 "register_operand" "=a")
7540         (div:HI (match_operand:HI 1 "register_operand" "0")
7541                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7542    (set (match_operand:HI 3 "register_operand" "=&d")
7543         (mod:HI (match_dup 1) (match_dup 2)))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "TARGET_HIMODE_MATH"
7546   "cwtd\;idiv{w}\t%2"
7547   [(set_attr "type" "multi")
7548    (set_attr "length_immediate" "0")
7549    (set_attr "mode" "SI")])
7551 (define_insn "udivmoddi4"
7552   [(set (match_operand:DI 0 "register_operand" "=a")
7553         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7554                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7555    (set (match_operand:DI 3 "register_operand" "=&d")
7556         (umod:DI (match_dup 1) (match_dup 2)))
7557    (clobber (reg:CC FLAGS_REG))]
7558   "TARGET_64BIT"
7559   "xor{q}\t%3, %3\;div{q}\t%2"
7560   [(set_attr "type" "multi")
7561    (set_attr "length_immediate" "0")
7562    (set_attr "mode" "DI")])
7564 (define_insn "*udivmoddi4_noext"
7565   [(set (match_operand:DI 0 "register_operand" "=a")
7566         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7567                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7568    (set (match_operand:DI 3 "register_operand" "=d")
7569         (umod:DI (match_dup 1) (match_dup 2)))
7570    (use (match_dup 3))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "TARGET_64BIT"
7573   "div{q}\t%2"
7574   [(set_attr "type" "idiv")
7575    (set_attr "mode" "DI")])
7577 (define_split
7578   [(set (match_operand:DI 0 "register_operand" "")
7579         (udiv:DI (match_operand:DI 1 "register_operand" "")
7580                  (match_operand:DI 2 "nonimmediate_operand" "")))
7581    (set (match_operand:DI 3 "register_operand" "")
7582         (umod:DI (match_dup 1) (match_dup 2)))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "TARGET_64BIT && reload_completed"
7585   [(set (match_dup 3) (const_int 0))
7586    (parallel [(set (match_dup 0)
7587                    (udiv:DI (match_dup 1) (match_dup 2)))
7588               (set (match_dup 3)
7589                    (umod:DI (match_dup 1) (match_dup 2)))
7590               (use (match_dup 3))
7591               (clobber (reg:CC FLAGS_REG))])]
7592   "")
7594 (define_insn "udivmodsi4"
7595   [(set (match_operand:SI 0 "register_operand" "=a")
7596         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7597                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7598    (set (match_operand:SI 3 "register_operand" "=&d")
7599         (umod:SI (match_dup 1) (match_dup 2)))
7600    (clobber (reg:CC FLAGS_REG))]
7601   ""
7602   "xor{l}\t%3, %3\;div{l}\t%2"
7603   [(set_attr "type" "multi")
7604    (set_attr "length_immediate" "0")
7605    (set_attr "mode" "SI")])
7607 (define_insn "*udivmodsi4_noext"
7608   [(set (match_operand:SI 0 "register_operand" "=a")
7609         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7610                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7611    (set (match_operand:SI 3 "register_operand" "=d")
7612         (umod:SI (match_dup 1) (match_dup 2)))
7613    (use (match_dup 3))
7614    (clobber (reg:CC FLAGS_REG))]
7615   ""
7616   "div{l}\t%2"
7617   [(set_attr "type" "idiv")
7618    (set_attr "mode" "SI")])
7620 (define_split
7621   [(set (match_operand:SI 0 "register_operand" "")
7622         (udiv:SI (match_operand:SI 1 "register_operand" "")
7623                  (match_operand:SI 2 "nonimmediate_operand" "")))
7624    (set (match_operand:SI 3 "register_operand" "")
7625         (umod:SI (match_dup 1) (match_dup 2)))
7626    (clobber (reg:CC FLAGS_REG))]
7627   "reload_completed"
7628   [(set (match_dup 3) (const_int 0))
7629    (parallel [(set (match_dup 0)
7630                    (udiv:SI (match_dup 1) (match_dup 2)))
7631               (set (match_dup 3)
7632                    (umod:SI (match_dup 1) (match_dup 2)))
7633               (use (match_dup 3))
7634               (clobber (reg:CC FLAGS_REG))])]
7635   "")
7637 (define_expand "udivmodhi4"
7638   [(set (match_dup 4) (const_int 0))
7639    (parallel [(set (match_operand:HI 0 "register_operand" "")
7640                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7641                             (match_operand:HI 2 "nonimmediate_operand" "")))
7642               (set (match_operand:HI 3 "register_operand" "")
7643                    (umod:HI (match_dup 1) (match_dup 2)))
7644               (use (match_dup 4))
7645               (clobber (reg:CC FLAGS_REG))])]
7646   "TARGET_HIMODE_MATH"
7647   "operands[4] = gen_reg_rtx (HImode);")
7649 (define_insn "*udivmodhi_noext"
7650   [(set (match_operand:HI 0 "register_operand" "=a")
7651         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7652                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7653    (set (match_operand:HI 3 "register_operand" "=d")
7654         (umod:HI (match_dup 1) (match_dup 2)))
7655    (use (match_operand:HI 4 "register_operand" "3"))
7656    (clobber (reg:CC FLAGS_REG))]
7657   ""
7658   "div{w}\t%2"
7659   [(set_attr "type" "idiv")
7660    (set_attr "mode" "HI")])
7662 ;; We cannot use div/idiv for double division, because it causes
7663 ;; "division by zero" on the overflow and that's not what we expect
7664 ;; from truncate.  Because true (non truncating) double division is
7665 ;; never generated, we can't create this insn anyway.
7667 ;(define_insn ""
7668 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7669 ;       (truncate:SI
7670 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7671 ;                  (zero_extend:DI
7672 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7673 ;   (set (match_operand:SI 3 "register_operand" "=d")
7674 ;       (truncate:SI
7675 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7676 ;   (clobber (reg:CC FLAGS_REG))]
7677 ;  ""
7678 ;  "div{l}\t{%2, %0|%0, %2}"
7679 ;  [(set_attr "type" "idiv")])
7681 ;;- Logical AND instructions
7683 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7684 ;; Note that this excludes ah.
7686 (define_insn "*testdi_1_rex64"
7687   [(set (reg FLAGS_REG)
7688         (compare
7689           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7690                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7691           (const_int 0)))]
7692   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7693    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7694   "@
7695    test{l}\t{%k1, %k0|%k0, %k1}
7696    test{l}\t{%k1, %k0|%k0, %k1}
7697    test{q}\t{%1, %0|%0, %1}
7698    test{q}\t{%1, %0|%0, %1}
7699    test{q}\t{%1, %0|%0, %1}"
7700   [(set_attr "type" "test")
7701    (set_attr "modrm" "0,1,0,1,1")
7702    (set_attr "mode" "SI,SI,DI,DI,DI")
7703    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7705 (define_insn "testsi_1"
7706   [(set (reg FLAGS_REG)
7707         (compare
7708           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7709                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7710           (const_int 0)))]
7711   "ix86_match_ccmode (insn, CCNOmode)
7712    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7713   "test{l}\t{%1, %0|%0, %1}"
7714   [(set_attr "type" "test")
7715    (set_attr "modrm" "0,1,1")
7716    (set_attr "mode" "SI")
7717    (set_attr "pent_pair" "uv,np,uv")])
7719 (define_expand "testsi_ccno_1"
7720   [(set (reg:CCNO FLAGS_REG)
7721         (compare:CCNO
7722           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7723                   (match_operand:SI 1 "nonmemory_operand" ""))
7724           (const_int 0)))]
7725   ""
7726   "")
7728 (define_insn "*testhi_1"
7729   [(set (reg FLAGS_REG)
7730         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7731                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7732                  (const_int 0)))]
7733   "ix86_match_ccmode (insn, CCNOmode)
7734    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7735   "test{w}\t{%1, %0|%0, %1}"
7736   [(set_attr "type" "test")
7737    (set_attr "modrm" "0,1,1")
7738    (set_attr "mode" "HI")
7739    (set_attr "pent_pair" "uv,np,uv")])
7741 (define_expand "testqi_ccz_1"
7742   [(set (reg:CCZ FLAGS_REG)
7743         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7744                              (match_operand:QI 1 "nonmemory_operand" ""))
7745                  (const_int 0)))]
7746   ""
7747   "")
7749 (define_insn "*testqi_1_maybe_si"
7750   [(set (reg FLAGS_REG)
7751         (compare
7752           (and:QI
7753             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7754             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7755           (const_int 0)))]
7756    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7757     && ix86_match_ccmode (insn,
7758                          GET_CODE (operands[1]) == CONST_INT
7759                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7761   if (which_alternative == 3)
7762     {
7763       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7764         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7765       return "test{l}\t{%1, %k0|%k0, %1}";
7766     }
7767   return "test{b}\t{%1, %0|%0, %1}";
7769   [(set_attr "type" "test")
7770    (set_attr "modrm" "0,1,1,1")
7771    (set_attr "mode" "QI,QI,QI,SI")
7772    (set_attr "pent_pair" "uv,np,uv,np")])
7774 (define_insn "*testqi_1"
7775   [(set (reg FLAGS_REG)
7776         (compare
7777           (and:QI
7778             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7779             (match_operand:QI 1 "general_operand" "n,n,qn"))
7780           (const_int 0)))]
7781   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7782    && ix86_match_ccmode (insn, CCNOmode)"
7783   "test{b}\t{%1, %0|%0, %1}"
7784   [(set_attr "type" "test")
7785    (set_attr "modrm" "0,1,1")
7786    (set_attr "mode" "QI")
7787    (set_attr "pent_pair" "uv,np,uv")])
7789 (define_expand "testqi_ext_ccno_0"
7790   [(set (reg:CCNO FLAGS_REG)
7791         (compare:CCNO
7792           (and:SI
7793             (zero_extract:SI
7794               (match_operand 0 "ext_register_operand" "")
7795               (const_int 8)
7796               (const_int 8))
7797             (match_operand 1 "const_int_operand" ""))
7798           (const_int 0)))]
7799   ""
7800   "")
7802 (define_insn "*testqi_ext_0"
7803   [(set (reg FLAGS_REG)
7804         (compare
7805           (and:SI
7806             (zero_extract:SI
7807               (match_operand 0 "ext_register_operand" "Q")
7808               (const_int 8)
7809               (const_int 8))
7810             (match_operand 1 "const_int_operand" "n"))
7811           (const_int 0)))]
7812   "ix86_match_ccmode (insn, CCNOmode)"
7813   "test{b}\t{%1, %h0|%h0, %1}"
7814   [(set_attr "type" "test")
7815    (set_attr "mode" "QI")
7816    (set_attr "length_immediate" "1")
7817    (set_attr "pent_pair" "np")])
7819 (define_insn "*testqi_ext_1"
7820   [(set (reg FLAGS_REG)
7821         (compare
7822           (and:SI
7823             (zero_extract:SI
7824               (match_operand 0 "ext_register_operand" "Q")
7825               (const_int 8)
7826               (const_int 8))
7827             (zero_extend:SI
7828               (match_operand:QI 1 "general_operand" "Qm")))
7829           (const_int 0)))]
7830   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7831    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7832   "test{b}\t{%1, %h0|%h0, %1}"
7833   [(set_attr "type" "test")
7834    (set_attr "mode" "QI")])
7836 (define_insn "*testqi_ext_1_rex64"
7837   [(set (reg FLAGS_REG)
7838         (compare
7839           (and:SI
7840             (zero_extract:SI
7841               (match_operand 0 "ext_register_operand" "Q")
7842               (const_int 8)
7843               (const_int 8))
7844             (zero_extend:SI
7845               (match_operand:QI 1 "register_operand" "Q")))
7846           (const_int 0)))]
7847   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7848   "test{b}\t{%1, %h0|%h0, %1}"
7849   [(set_attr "type" "test")
7850    (set_attr "mode" "QI")])
7852 (define_insn "*testqi_ext_2"
7853   [(set (reg FLAGS_REG)
7854         (compare
7855           (and:SI
7856             (zero_extract:SI
7857               (match_operand 0 "ext_register_operand" "Q")
7858               (const_int 8)
7859               (const_int 8))
7860             (zero_extract:SI
7861               (match_operand 1 "ext_register_operand" "Q")
7862               (const_int 8)
7863               (const_int 8)))
7864           (const_int 0)))]
7865   "ix86_match_ccmode (insn, CCNOmode)"
7866   "test{b}\t{%h1, %h0|%h0, %h1}"
7867   [(set_attr "type" "test")
7868    (set_attr "mode" "QI")])
7870 ;; Combine likes to form bit extractions for some tests.  Humor it.
7871 (define_insn "*testqi_ext_3"
7872   [(set (reg FLAGS_REG)
7873         (compare (zero_extract:SI
7874                    (match_operand 0 "nonimmediate_operand" "rm")
7875                    (match_operand:SI 1 "const_int_operand" "")
7876                    (match_operand:SI 2 "const_int_operand" ""))
7877                  (const_int 0)))]
7878   "ix86_match_ccmode (insn, CCNOmode)
7879    && (GET_MODE (operands[0]) == SImode
7880        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7881        || GET_MODE (operands[0]) == HImode
7882        || GET_MODE (operands[0]) == QImode)"
7883   "#")
7885 (define_insn "*testqi_ext_3_rex64"
7886   [(set (reg FLAGS_REG)
7887         (compare (zero_extract:DI
7888                    (match_operand 0 "nonimmediate_operand" "rm")
7889                    (match_operand:DI 1 "const_int_operand" "")
7890                    (match_operand:DI 2 "const_int_operand" ""))
7891                  (const_int 0)))]
7892   "TARGET_64BIT
7893    && ix86_match_ccmode (insn, CCNOmode)
7894    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7895    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7896    /* Ensure that resulting mask is zero or sign extended operand.  */
7897    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7898        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7899            && INTVAL (operands[1]) > 32))
7900    && (GET_MODE (operands[0]) == SImode
7901        || GET_MODE (operands[0]) == DImode
7902        || GET_MODE (operands[0]) == HImode
7903        || GET_MODE (operands[0]) == QImode)"
7904   "#")
7906 (define_split
7907   [(set (match_operand 0 "flags_reg_operand" "")
7908         (match_operator 1 "compare_operator"
7909           [(zero_extract
7910              (match_operand 2 "nonimmediate_operand" "")
7911              (match_operand 3 "const_int_operand" "")
7912              (match_operand 4 "const_int_operand" ""))
7913            (const_int 0)]))]
7914   "ix86_match_ccmode (insn, CCNOmode)"
7915   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7917   rtx val = operands[2];
7918   HOST_WIDE_INT len = INTVAL (operands[3]);
7919   HOST_WIDE_INT pos = INTVAL (operands[4]);
7920   HOST_WIDE_INT mask;
7921   enum machine_mode mode, submode;
7923   mode = GET_MODE (val);
7924   if (GET_CODE (val) == MEM)
7925     {
7926       /* ??? Combine likes to put non-volatile mem extractions in QImode
7927          no matter the size of the test.  So find a mode that works.  */
7928       if (! MEM_VOLATILE_P (val))
7929         {
7930           mode = smallest_mode_for_size (pos + len, MODE_INT);
7931           val = adjust_address (val, mode, 0);
7932         }
7933     }
7934   else if (GET_CODE (val) == SUBREG
7935            && (submode = GET_MODE (SUBREG_REG (val)),
7936                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7937            && pos + len <= GET_MODE_BITSIZE (submode))
7938     {
7939       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7940       mode = submode;
7941       val = SUBREG_REG (val);
7942     }
7943   else if (mode == HImode && pos + len <= 8)
7944     {
7945       /* Small HImode tests can be converted to QImode.  */
7946       mode = QImode;
7947       val = gen_lowpart (QImode, val);
7948     }
7950   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7951   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7953   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7956 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7957 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7958 ;; this is relatively important trick.
7959 ;; Do the conversion only post-reload to avoid limiting of the register class
7960 ;; to QI regs.
7961 (define_split
7962   [(set (match_operand 0 "flags_reg_operand" "")
7963         (match_operator 1 "compare_operator"
7964           [(and (match_operand 2 "register_operand" "")
7965                 (match_operand 3 "const_int_operand" ""))
7966            (const_int 0)]))]
7967    "reload_completed
7968     && QI_REG_P (operands[2])
7969     && GET_MODE (operands[2]) != QImode
7970     && ((ix86_match_ccmode (insn, CCZmode)
7971          && !(INTVAL (operands[3]) & ~(255 << 8)))
7972         || (ix86_match_ccmode (insn, CCNOmode)
7973             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7974   [(set (match_dup 0)
7975         (match_op_dup 1
7976           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7977                    (match_dup 3))
7978            (const_int 0)]))]
7979   "operands[2] = gen_lowpart (SImode, operands[2]);
7980    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7982 (define_split
7983   [(set (match_operand 0 "flags_reg_operand" "")
7984         (match_operator 1 "compare_operator"
7985           [(and (match_operand 2 "nonimmediate_operand" "")
7986                 (match_operand 3 "const_int_operand" ""))
7987            (const_int 0)]))]
7988    "reload_completed
7989     && GET_MODE (operands[2]) != QImode
7990     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7991     && ((ix86_match_ccmode (insn, CCZmode)
7992          && !(INTVAL (operands[3]) & ~255))
7993         || (ix86_match_ccmode (insn, CCNOmode)
7994             && !(INTVAL (operands[3]) & ~127)))"
7995   [(set (match_dup 0)
7996         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7997                          (const_int 0)]))]
7998   "operands[2] = gen_lowpart (QImode, operands[2]);
7999    operands[3] = gen_lowpart (QImode, operands[3]);")
8002 ;; %%% This used to optimize known byte-wide and operations to memory,
8003 ;; and sometimes to QImode registers.  If this is considered useful,
8004 ;; it should be done with splitters.
8006 (define_expand "anddi3"
8007   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8008         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8009                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8010    (clobber (reg:CC FLAGS_REG))]
8011   "TARGET_64BIT"
8012   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8014 (define_insn "*anddi_1_rex64"
8015   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8016         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8017                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8018    (clobber (reg:CC FLAGS_REG))]
8019   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8021   switch (get_attr_type (insn))
8022     {
8023     case TYPE_IMOVX:
8024       {
8025         enum machine_mode mode;
8027         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8028         if (INTVAL (operands[2]) == 0xff)
8029           mode = QImode;
8030         else
8031           {
8032             gcc_assert (INTVAL (operands[2]) == 0xffff);
8033             mode = HImode;
8034           }
8035         
8036         operands[1] = gen_lowpart (mode, operands[1]);
8037         if (mode == QImode)
8038           return "movz{bq|x}\t{%1,%0|%0, %1}";
8039         else
8040           return "movz{wq|x}\t{%1,%0|%0, %1}";
8041       }
8043     default:
8044       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8045       if (get_attr_mode (insn) == MODE_SI)
8046         return "and{l}\t{%k2, %k0|%k0, %k2}";
8047       else
8048         return "and{q}\t{%2, %0|%0, %2}";
8049     }
8051   [(set_attr "type" "alu,alu,alu,imovx")
8052    (set_attr "length_immediate" "*,*,*,0")
8053    (set_attr "mode" "SI,DI,DI,DI")])
8055 (define_insn "*anddi_2"
8056   [(set (reg FLAGS_REG)
8057         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8058                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8059                  (const_int 0)))
8060    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8061         (and:DI (match_dup 1) (match_dup 2)))]
8062   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8063    && ix86_binary_operator_ok (AND, DImode, operands)"
8064   "@
8065    and{l}\t{%k2, %k0|%k0, %k2}
8066    and{q}\t{%2, %0|%0, %2}
8067    and{q}\t{%2, %0|%0, %2}"
8068   [(set_attr "type" "alu")
8069    (set_attr "mode" "SI,DI,DI")])
8071 (define_expand "andsi3"
8072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8073         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8074                 (match_operand:SI 2 "general_operand" "")))
8075    (clobber (reg:CC FLAGS_REG))]
8076   ""
8077   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8079 (define_insn "*andsi_1"
8080   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8081         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8082                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8083    (clobber (reg:CC FLAGS_REG))]
8084   "ix86_binary_operator_ok (AND, SImode, operands)"
8086   switch (get_attr_type (insn))
8087     {
8088     case TYPE_IMOVX:
8089       {
8090         enum machine_mode mode;
8092         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8093         if (INTVAL (operands[2]) == 0xff)
8094           mode = QImode;
8095         else
8096           {
8097             gcc_assert (INTVAL (operands[2]) == 0xffff);
8098             mode = HImode;
8099           }
8100         
8101         operands[1] = gen_lowpart (mode, operands[1]);
8102         if (mode == QImode)
8103           return "movz{bl|x}\t{%1,%0|%0, %1}";
8104         else
8105           return "movz{wl|x}\t{%1,%0|%0, %1}";
8106       }
8108     default:
8109       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8110       return "and{l}\t{%2, %0|%0, %2}";
8111     }
8113   [(set_attr "type" "alu,alu,imovx")
8114    (set_attr "length_immediate" "*,*,0")
8115    (set_attr "mode" "SI")])
8117 (define_split
8118   [(set (match_operand 0 "register_operand" "")
8119         (and (match_dup 0)
8120              (const_int -65536)))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8123   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8124   "operands[1] = gen_lowpart (HImode, operands[0]);")
8126 (define_split
8127   [(set (match_operand 0 "ext_register_operand" "")
8128         (and (match_dup 0)
8129              (const_int -256)))
8130    (clobber (reg:CC FLAGS_REG))]
8131   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8132   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8133   "operands[1] = gen_lowpart (QImode, operands[0]);")
8135 (define_split
8136   [(set (match_operand 0 "ext_register_operand" "")
8137         (and (match_dup 0)
8138              (const_int -65281)))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8141   [(parallel [(set (zero_extract:SI (match_dup 0)
8142                                     (const_int 8)
8143                                     (const_int 8))
8144                    (xor:SI 
8145                      (zero_extract:SI (match_dup 0)
8146                                       (const_int 8)
8147                                       (const_int 8))
8148                      (zero_extract:SI (match_dup 0)
8149                                       (const_int 8)
8150                                       (const_int 8))))
8151               (clobber (reg:CC FLAGS_REG))])]
8152   "operands[0] = gen_lowpart (SImode, operands[0]);")
8154 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8155 (define_insn "*andsi_1_zext"
8156   [(set (match_operand:DI 0 "register_operand" "=r")
8157         (zero_extend:DI
8158           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8159                   (match_operand:SI 2 "general_operand" "rim"))))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8162   "and{l}\t{%2, %k0|%k0, %2}"
8163   [(set_attr "type" "alu")
8164    (set_attr "mode" "SI")])
8166 (define_insn "*andsi_2"
8167   [(set (reg FLAGS_REG)
8168         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8169                          (match_operand:SI 2 "general_operand" "rim,ri"))
8170                  (const_int 0)))
8171    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8172         (and:SI (match_dup 1) (match_dup 2)))]
8173   "ix86_match_ccmode (insn, CCNOmode)
8174    && ix86_binary_operator_ok (AND, SImode, operands)"
8175   "and{l}\t{%2, %0|%0, %2}"
8176   [(set_attr "type" "alu")
8177    (set_attr "mode" "SI")])
8179 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8180 (define_insn "*andsi_2_zext"
8181   [(set (reg FLAGS_REG)
8182         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8183                          (match_operand:SI 2 "general_operand" "rim"))
8184                  (const_int 0)))
8185    (set (match_operand:DI 0 "register_operand" "=r")
8186         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8187   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8188    && ix86_binary_operator_ok (AND, SImode, operands)"
8189   "and{l}\t{%2, %k0|%k0, %2}"
8190   [(set_attr "type" "alu")
8191    (set_attr "mode" "SI")])
8193 (define_expand "andhi3"
8194   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8195         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8196                 (match_operand:HI 2 "general_operand" "")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "TARGET_HIMODE_MATH"
8199   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8201 (define_insn "*andhi_1"
8202   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8203         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8204                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "ix86_binary_operator_ok (AND, HImode, operands)"
8208   switch (get_attr_type (insn))
8209     {
8210     case TYPE_IMOVX:
8211       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8212       gcc_assert (INTVAL (operands[2]) == 0xff);
8213       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8215     default:
8216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218       return "and{w}\t{%2, %0|%0, %2}";
8219     }
8221   [(set_attr "type" "alu,alu,imovx")
8222    (set_attr "length_immediate" "*,*,0")
8223    (set_attr "mode" "HI,HI,SI")])
8225 (define_insn "*andhi_2"
8226   [(set (reg FLAGS_REG)
8227         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8228                          (match_operand:HI 2 "general_operand" "rim,ri"))
8229                  (const_int 0)))
8230    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8231         (and:HI (match_dup 1) (match_dup 2)))]
8232   "ix86_match_ccmode (insn, CCNOmode)
8233    && ix86_binary_operator_ok (AND, HImode, operands)"
8234   "and{w}\t{%2, %0|%0, %2}"
8235   [(set_attr "type" "alu")
8236    (set_attr "mode" "HI")])
8238 (define_expand "andqi3"
8239   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8240         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8241                 (match_operand:QI 2 "general_operand" "")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "TARGET_QIMODE_MATH"
8244   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8246 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8247 (define_insn "*andqi_1"
8248   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8249         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8250                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "ix86_binary_operator_ok (AND, QImode, operands)"
8253   "@
8254    and{b}\t{%2, %0|%0, %2}
8255    and{b}\t{%2, %0|%0, %2}
8256    and{l}\t{%k2, %k0|%k0, %k2}"
8257   [(set_attr "type" "alu")
8258    (set_attr "mode" "QI,QI,SI")])
8260 (define_insn "*andqi_1_slp"
8261   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8262         (and:QI (match_dup 0)
8263                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8264    (clobber (reg:CC FLAGS_REG))]
8265   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8266    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8267   "and{b}\t{%1, %0|%0, %1}"
8268   [(set_attr "type" "alu1")
8269    (set_attr "mode" "QI")])
8271 (define_insn "*andqi_2_maybe_si"
8272   [(set (reg FLAGS_REG)
8273         (compare (and:QI
8274                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8275                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8276                  (const_int 0)))
8277    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8278         (and:QI (match_dup 1) (match_dup 2)))]
8279   "ix86_binary_operator_ok (AND, QImode, operands)
8280    && ix86_match_ccmode (insn,
8281                          GET_CODE (operands[2]) == CONST_INT
8282                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8284   if (which_alternative == 2)
8285     {
8286       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8287         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8288       return "and{l}\t{%2, %k0|%k0, %2}";
8289     }
8290   return "and{b}\t{%2, %0|%0, %2}";
8292   [(set_attr "type" "alu")
8293    (set_attr "mode" "QI,QI,SI")])
8295 (define_insn "*andqi_2"
8296   [(set (reg FLAGS_REG)
8297         (compare (and:QI
8298                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8299                    (match_operand:QI 2 "general_operand" "qim,qi"))
8300                  (const_int 0)))
8301    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8302         (and:QI (match_dup 1) (match_dup 2)))]
8303   "ix86_match_ccmode (insn, CCNOmode)
8304    && ix86_binary_operator_ok (AND, QImode, operands)"
8305   "and{b}\t{%2, %0|%0, %2}"
8306   [(set_attr "type" "alu")
8307    (set_attr "mode" "QI")])
8309 (define_insn "*andqi_2_slp"
8310   [(set (reg FLAGS_REG)
8311         (compare (and:QI
8312                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8313                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8314                  (const_int 0)))
8315    (set (strict_low_part (match_dup 0))
8316         (and:QI (match_dup 0) (match_dup 1)))]
8317   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8318    && ix86_match_ccmode (insn, CCNOmode)
8319    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8320   "and{b}\t{%1, %0|%0, %1}"
8321   [(set_attr "type" "alu1")
8322    (set_attr "mode" "QI")])
8324 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8325 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8326 ;; for a QImode operand, which of course failed.
8328 (define_insn "andqi_ext_0"
8329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8330                          (const_int 8)
8331                          (const_int 8))
8332         (and:SI 
8333           (zero_extract:SI
8334             (match_operand 1 "ext_register_operand" "0")
8335             (const_int 8)
8336             (const_int 8))
8337           (match_operand 2 "const_int_operand" "n")))
8338    (clobber (reg:CC FLAGS_REG))]
8339   ""
8340   "and{b}\t{%2, %h0|%h0, %2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "length_immediate" "1")
8343    (set_attr "mode" "QI")])
8345 ;; Generated by peephole translating test to and.  This shows up
8346 ;; often in fp comparisons.
8348 (define_insn "*andqi_ext_0_cc"
8349   [(set (reg FLAGS_REG)
8350         (compare
8351           (and:SI
8352             (zero_extract:SI
8353               (match_operand 1 "ext_register_operand" "0")
8354               (const_int 8)
8355               (const_int 8))
8356             (match_operand 2 "const_int_operand" "n"))
8357           (const_int 0)))
8358    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8359                          (const_int 8)
8360                          (const_int 8))
8361         (and:SI 
8362           (zero_extract:SI
8363             (match_dup 1)
8364             (const_int 8)
8365             (const_int 8))
8366           (match_dup 2)))]
8367   "ix86_match_ccmode (insn, CCNOmode)"
8368   "and{b}\t{%2, %h0|%h0, %2}"
8369   [(set_attr "type" "alu")
8370    (set_attr "length_immediate" "1")
8371    (set_attr "mode" "QI")])
8373 (define_insn "*andqi_ext_1"
8374   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8375                          (const_int 8)
8376                          (const_int 8))
8377         (and:SI 
8378           (zero_extract:SI
8379             (match_operand 1 "ext_register_operand" "0")
8380             (const_int 8)
8381             (const_int 8))
8382           (zero_extend:SI
8383             (match_operand:QI 2 "general_operand" "Qm"))))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "!TARGET_64BIT"
8386   "and{b}\t{%2, %h0|%h0, %2}"
8387   [(set_attr "type" "alu")
8388    (set_attr "length_immediate" "0")
8389    (set_attr "mode" "QI")])
8391 (define_insn "*andqi_ext_1_rex64"
8392   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8393                          (const_int 8)
8394                          (const_int 8))
8395         (and:SI 
8396           (zero_extract:SI
8397             (match_operand 1 "ext_register_operand" "0")
8398             (const_int 8)
8399             (const_int 8))
8400           (zero_extend:SI
8401             (match_operand 2 "ext_register_operand" "Q"))))
8402    (clobber (reg:CC FLAGS_REG))]
8403   "TARGET_64BIT"
8404   "and{b}\t{%2, %h0|%h0, %2}"
8405   [(set_attr "type" "alu")
8406    (set_attr "length_immediate" "0")
8407    (set_attr "mode" "QI")])
8409 (define_insn "*andqi_ext_2"
8410   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8411                          (const_int 8)
8412                          (const_int 8))
8413         (and:SI
8414           (zero_extract:SI
8415             (match_operand 1 "ext_register_operand" "%0")
8416             (const_int 8)
8417             (const_int 8))
8418           (zero_extract:SI
8419             (match_operand 2 "ext_register_operand" "Q")
8420             (const_int 8)
8421             (const_int 8))))
8422    (clobber (reg:CC FLAGS_REG))]
8423   ""
8424   "and{b}\t{%h2, %h0|%h0, %h2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "length_immediate" "0")
8427    (set_attr "mode" "QI")])
8429 ;; Convert wide AND instructions with immediate operand to shorter QImode
8430 ;; equivalents when possible.
8431 ;; Don't do the splitting with memory operands, since it introduces risk
8432 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8433 ;; for size, but that can (should?) be handled by generic code instead.
8434 (define_split
8435   [(set (match_operand 0 "register_operand" "")
8436         (and (match_operand 1 "register_operand" "")
8437              (match_operand 2 "const_int_operand" "")))
8438    (clobber (reg:CC FLAGS_REG))]
8439    "reload_completed
8440     && QI_REG_P (operands[0])
8441     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8442     && !(~INTVAL (operands[2]) & ~(255 << 8))
8443     && GET_MODE (operands[0]) != QImode"
8444   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8445                    (and:SI (zero_extract:SI (match_dup 1)
8446                                             (const_int 8) (const_int 8))
8447                            (match_dup 2)))
8448               (clobber (reg:CC FLAGS_REG))])]
8449   "operands[0] = gen_lowpart (SImode, operands[0]);
8450    operands[1] = gen_lowpart (SImode, operands[1]);
8451    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8453 ;; Since AND can be encoded with sign extended immediate, this is only
8454 ;; profitable when 7th bit is not set.
8455 (define_split
8456   [(set (match_operand 0 "register_operand" "")
8457         (and (match_operand 1 "general_operand" "")
8458              (match_operand 2 "const_int_operand" "")))
8459    (clobber (reg:CC FLAGS_REG))]
8460    "reload_completed
8461     && ANY_QI_REG_P (operands[0])
8462     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8463     && !(~INTVAL (operands[2]) & ~255)
8464     && !(INTVAL (operands[2]) & 128)
8465     && GET_MODE (operands[0]) != QImode"
8466   [(parallel [(set (strict_low_part (match_dup 0))
8467                    (and:QI (match_dup 1)
8468                            (match_dup 2)))
8469               (clobber (reg:CC FLAGS_REG))])]
8470   "operands[0] = gen_lowpart (QImode, operands[0]);
8471    operands[1] = gen_lowpart (QImode, operands[1]);
8472    operands[2] = gen_lowpart (QImode, operands[2]);")
8474 ;; Logical inclusive OR instructions
8476 ;; %%% This used to optimize known byte-wide and operations to memory.
8477 ;; If this is considered useful, it should be done with splitters.
8479 (define_expand "iordi3"
8480   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8481         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8482                 (match_operand:DI 2 "x86_64_general_operand" "")))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "TARGET_64BIT"
8485   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8487 (define_insn "*iordi_1_rex64"
8488   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8489         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8490                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8491    (clobber (reg:CC FLAGS_REG))]
8492   "TARGET_64BIT
8493    && ix86_binary_operator_ok (IOR, DImode, operands)"
8494   "or{q}\t{%2, %0|%0, %2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "mode" "DI")])
8498 (define_insn "*iordi_2_rex64"
8499   [(set (reg FLAGS_REG)
8500         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8501                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8502                  (const_int 0)))
8503    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8504         (ior:DI (match_dup 1) (match_dup 2)))]
8505   "TARGET_64BIT
8506    && ix86_match_ccmode (insn, CCNOmode)
8507    && ix86_binary_operator_ok (IOR, DImode, operands)"
8508   "or{q}\t{%2, %0|%0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "DI")])
8512 (define_insn "*iordi_3_rex64"
8513   [(set (reg FLAGS_REG)
8514         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8515                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8516                  (const_int 0)))
8517    (clobber (match_scratch:DI 0 "=r"))]
8518   "TARGET_64BIT
8519    && ix86_match_ccmode (insn, CCNOmode)
8520    && ix86_binary_operator_ok (IOR, DImode, operands)"
8521   "or{q}\t{%2, %0|%0, %2}"
8522   [(set_attr "type" "alu")
8523    (set_attr "mode" "DI")])
8526 (define_expand "iorsi3"
8527   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8528         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8529                 (match_operand:SI 2 "general_operand" "")))
8530    (clobber (reg:CC FLAGS_REG))]
8531   ""
8532   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8534 (define_insn "*iorsi_1"
8535   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8536         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8537                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8538    (clobber (reg:CC FLAGS_REG))]
8539   "ix86_binary_operator_ok (IOR, SImode, operands)"
8540   "or{l}\t{%2, %0|%0, %2}"
8541   [(set_attr "type" "alu")
8542    (set_attr "mode" "SI")])
8544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8545 (define_insn "*iorsi_1_zext"
8546   [(set (match_operand:DI 0 "register_operand" "=rm")
8547         (zero_extend:DI
8548           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8549                   (match_operand:SI 2 "general_operand" "rim"))))
8550    (clobber (reg:CC FLAGS_REG))]
8551   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8552   "or{l}\t{%2, %k0|%k0, %2}"
8553   [(set_attr "type" "alu")
8554    (set_attr "mode" "SI")])
8556 (define_insn "*iorsi_1_zext_imm"
8557   [(set (match_operand:DI 0 "register_operand" "=rm")
8558         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8559                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8560    (clobber (reg:CC FLAGS_REG))]
8561   "TARGET_64BIT"
8562   "or{l}\t{%2, %k0|%k0, %2}"
8563   [(set_attr "type" "alu")
8564    (set_attr "mode" "SI")])
8566 (define_insn "*iorsi_2"
8567   [(set (reg FLAGS_REG)
8568         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8569                          (match_operand:SI 2 "general_operand" "rim,ri"))
8570                  (const_int 0)))
8571    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8572         (ior:SI (match_dup 1) (match_dup 2)))]
8573   "ix86_match_ccmode (insn, CCNOmode)
8574    && ix86_binary_operator_ok (IOR, SImode, operands)"
8575   "or{l}\t{%2, %0|%0, %2}"
8576   [(set_attr "type" "alu")
8577    (set_attr "mode" "SI")])
8579 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8580 ;; ??? Special case for immediate operand is missing - it is tricky.
8581 (define_insn "*iorsi_2_zext"
8582   [(set (reg FLAGS_REG)
8583         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8584                          (match_operand:SI 2 "general_operand" "rim"))
8585                  (const_int 0)))
8586    (set (match_operand:DI 0 "register_operand" "=r")
8587         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8588   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8589    && ix86_binary_operator_ok (IOR, SImode, operands)"
8590   "or{l}\t{%2, %k0|%k0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "SI")])
8594 (define_insn "*iorsi_2_zext_imm"
8595   [(set (reg FLAGS_REG)
8596         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8597                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8598                  (const_int 0)))
8599    (set (match_operand:DI 0 "register_operand" "=r")
8600         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8601   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8602    && ix86_binary_operator_ok (IOR, SImode, operands)"
8603   "or{l}\t{%2, %k0|%k0, %2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "mode" "SI")])
8607 (define_insn "*iorsi_3"
8608   [(set (reg FLAGS_REG)
8609         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8610                          (match_operand:SI 2 "general_operand" "rim"))
8611                  (const_int 0)))
8612    (clobber (match_scratch:SI 0 "=r"))]
8613   "ix86_match_ccmode (insn, CCNOmode)
8614    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8615   "or{l}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "SI")])
8619 (define_expand "iorhi3"
8620   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8621         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8622                 (match_operand:HI 2 "general_operand" "")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "TARGET_HIMODE_MATH"
8625   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8627 (define_insn "*iorhi_1"
8628   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8629         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8630                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "ix86_binary_operator_ok (IOR, HImode, operands)"
8633   "or{w}\t{%2, %0|%0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "HI")])
8637 (define_insn "*iorhi_2"
8638   [(set (reg FLAGS_REG)
8639         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8640                          (match_operand:HI 2 "general_operand" "rim,ri"))
8641                  (const_int 0)))
8642    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8643         (ior:HI (match_dup 1) (match_dup 2)))]
8644   "ix86_match_ccmode (insn, CCNOmode)
8645    && ix86_binary_operator_ok (IOR, HImode, operands)"
8646   "or{w}\t{%2, %0|%0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "HI")])
8650 (define_insn "*iorhi_3"
8651   [(set (reg FLAGS_REG)
8652         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8653                          (match_operand:HI 2 "general_operand" "rim"))
8654                  (const_int 0)))
8655    (clobber (match_scratch:HI 0 "=r"))]
8656   "ix86_match_ccmode (insn, CCNOmode)
8657    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8658   "or{w}\t{%2, %0|%0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "HI")])
8662 (define_expand "iorqi3"
8663   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8664         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8665                 (match_operand:QI 2 "general_operand" "")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "TARGET_QIMODE_MATH"
8668   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8670 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8671 (define_insn "*iorqi_1"
8672   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8673         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8674                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8675    (clobber (reg:CC FLAGS_REG))]
8676   "ix86_binary_operator_ok (IOR, QImode, operands)"
8677   "@
8678    or{b}\t{%2, %0|%0, %2}
8679    or{b}\t{%2, %0|%0, %2}
8680    or{l}\t{%k2, %k0|%k0, %k2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "QI,QI,SI")])
8684 (define_insn "*iorqi_1_slp"
8685   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8686         (ior:QI (match_dup 0)
8687                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8688    (clobber (reg:CC FLAGS_REG))]
8689   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8690    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8691   "or{b}\t{%1, %0|%0, %1}"
8692   [(set_attr "type" "alu1")
8693    (set_attr "mode" "QI")])
8695 (define_insn "*iorqi_2"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8698                          (match_operand:QI 2 "general_operand" "qim,qi"))
8699                  (const_int 0)))
8700    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8701         (ior:QI (match_dup 1) (match_dup 2)))]
8702   "ix86_match_ccmode (insn, CCNOmode)
8703    && ix86_binary_operator_ok (IOR, QImode, operands)"
8704   "or{b}\t{%2, %0|%0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "mode" "QI")])
8708 (define_insn "*iorqi_2_slp"
8709   [(set (reg FLAGS_REG)
8710         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8711                          (match_operand:QI 1 "general_operand" "qim,qi"))
8712                  (const_int 0)))
8713    (set (strict_low_part (match_dup 0))
8714         (ior:QI (match_dup 0) (match_dup 1)))]
8715   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8716    && ix86_match_ccmode (insn, CCNOmode)
8717    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8718   "or{b}\t{%1, %0|%0, %1}"
8719   [(set_attr "type" "alu1")
8720    (set_attr "mode" "QI")])
8722 (define_insn "*iorqi_3"
8723   [(set (reg FLAGS_REG)
8724         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8725                          (match_operand:QI 2 "general_operand" "qim"))
8726                  (const_int 0)))
8727    (clobber (match_scratch:QI 0 "=q"))]
8728   "ix86_match_ccmode (insn, CCNOmode)
8729    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8730   "or{b}\t{%2, %0|%0, %2}"
8731   [(set_attr "type" "alu")
8732    (set_attr "mode" "QI")])
8734 (define_insn "iorqi_ext_0"
8735   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8736                          (const_int 8)
8737                          (const_int 8))
8738         (ior:SI 
8739           (zero_extract:SI
8740             (match_operand 1 "ext_register_operand" "0")
8741             (const_int 8)
8742             (const_int 8))
8743           (match_operand 2 "const_int_operand" "n")))
8744    (clobber (reg:CC FLAGS_REG))]
8745   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8746   "or{b}\t{%2, %h0|%h0, %2}"
8747   [(set_attr "type" "alu")
8748    (set_attr "length_immediate" "1")
8749    (set_attr "mode" "QI")])
8751 (define_insn "*iorqi_ext_1"
8752   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8753                          (const_int 8)
8754                          (const_int 8))
8755         (ior:SI 
8756           (zero_extract:SI
8757             (match_operand 1 "ext_register_operand" "0")
8758             (const_int 8)
8759             (const_int 8))
8760           (zero_extend:SI
8761             (match_operand:QI 2 "general_operand" "Qm"))))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "!TARGET_64BIT
8764    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8765   "or{b}\t{%2, %h0|%h0, %2}"
8766   [(set_attr "type" "alu")
8767    (set_attr "length_immediate" "0")
8768    (set_attr "mode" "QI")])
8770 (define_insn "*iorqi_ext_1_rex64"
8771   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772                          (const_int 8)
8773                          (const_int 8))
8774         (ior:SI 
8775           (zero_extract:SI
8776             (match_operand 1 "ext_register_operand" "0")
8777             (const_int 8)
8778             (const_int 8))
8779           (zero_extend:SI
8780             (match_operand 2 "ext_register_operand" "Q"))))
8781    (clobber (reg:CC FLAGS_REG))]
8782   "TARGET_64BIT
8783    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8784   "or{b}\t{%2, %h0|%h0, %2}"
8785   [(set_attr "type" "alu")
8786    (set_attr "length_immediate" "0")
8787    (set_attr "mode" "QI")])
8789 (define_insn "*iorqi_ext_2"
8790   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8791                          (const_int 8)
8792                          (const_int 8))
8793         (ior:SI 
8794           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8795                            (const_int 8)
8796                            (const_int 8))
8797           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8798                            (const_int 8)
8799                            (const_int 8))))
8800    (clobber (reg:CC FLAGS_REG))]
8801   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8802   "ior{b}\t{%h2, %h0|%h0, %h2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "length_immediate" "0")
8805    (set_attr "mode" "QI")])
8807 (define_split
8808   [(set (match_operand 0 "register_operand" "")
8809         (ior (match_operand 1 "register_operand" "")
8810              (match_operand 2 "const_int_operand" "")))
8811    (clobber (reg:CC FLAGS_REG))]
8812    "reload_completed
8813     && QI_REG_P (operands[0])
8814     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8815     && !(INTVAL (operands[2]) & ~(255 << 8))
8816     && GET_MODE (operands[0]) != QImode"
8817   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8818                    (ior:SI (zero_extract:SI (match_dup 1)
8819                                             (const_int 8) (const_int 8))
8820                            (match_dup 2)))
8821               (clobber (reg:CC FLAGS_REG))])]
8822   "operands[0] = gen_lowpart (SImode, operands[0]);
8823    operands[1] = gen_lowpart (SImode, operands[1]);
8824    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8826 ;; Since OR can be encoded with sign extended immediate, this is only
8827 ;; profitable when 7th bit is set.
8828 (define_split
8829   [(set (match_operand 0 "register_operand" "")
8830         (ior (match_operand 1 "general_operand" "")
8831              (match_operand 2 "const_int_operand" "")))
8832    (clobber (reg:CC FLAGS_REG))]
8833    "reload_completed
8834     && ANY_QI_REG_P (operands[0])
8835     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8836     && !(INTVAL (operands[2]) & ~255)
8837     && (INTVAL (operands[2]) & 128)
8838     && GET_MODE (operands[0]) != QImode"
8839   [(parallel [(set (strict_low_part (match_dup 0))
8840                    (ior:QI (match_dup 1)
8841                            (match_dup 2)))
8842               (clobber (reg:CC FLAGS_REG))])]
8843   "operands[0] = gen_lowpart (QImode, operands[0]);
8844    operands[1] = gen_lowpart (QImode, operands[1]);
8845    operands[2] = gen_lowpart (QImode, operands[2]);")
8847 ;; Logical XOR instructions
8849 ;; %%% This used to optimize known byte-wide and operations to memory.
8850 ;; If this is considered useful, it should be done with splitters.
8852 (define_expand "xordi3"
8853   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8854         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8855                 (match_operand:DI 2 "x86_64_general_operand" "")))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "TARGET_64BIT"
8858   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8860 (define_insn "*xordi_1_rex64"
8861   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8862         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8863                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT
8866    && ix86_binary_operator_ok (XOR, DImode, operands)"
8867   "@
8868    xor{q}\t{%2, %0|%0, %2}
8869    xor{q}\t{%2, %0|%0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "mode" "DI,DI")])
8873 (define_insn "*xordi_2_rex64"
8874   [(set (reg FLAGS_REG)
8875         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877                  (const_int 0)))
8878    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879         (xor:DI (match_dup 1) (match_dup 2)))]
8880   "TARGET_64BIT
8881    && ix86_match_ccmode (insn, CCNOmode)
8882    && ix86_binary_operator_ok (XOR, DImode, operands)"
8883   "@
8884    xor{q}\t{%2, %0|%0, %2}
8885    xor{q}\t{%2, %0|%0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "DI,DI")])
8889 (define_insn "*xordi_3_rex64"
8890   [(set (reg FLAGS_REG)
8891         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8892                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8893                  (const_int 0)))
8894    (clobber (match_scratch:DI 0 "=r"))]
8895   "TARGET_64BIT
8896    && ix86_match_ccmode (insn, CCNOmode)
8897    && ix86_binary_operator_ok (XOR, DImode, operands)"
8898   "xor{q}\t{%2, %0|%0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "mode" "DI")])
8902 (define_expand "xorsi3"
8903   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8904         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8905                 (match_operand:SI 2 "general_operand" "")))
8906    (clobber (reg:CC FLAGS_REG))]
8907   ""
8908   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8910 (define_insn "*xorsi_1"
8911   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8912         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8913                 (match_operand:SI 2 "general_operand" "ri,rm")))
8914    (clobber (reg:CC FLAGS_REG))]
8915   "ix86_binary_operator_ok (XOR, SImode, operands)"
8916   "xor{l}\t{%2, %0|%0, %2}"
8917   [(set_attr "type" "alu")
8918    (set_attr "mode" "SI")])
8920 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8921 ;; Add speccase for immediates
8922 (define_insn "*xorsi_1_zext"
8923   [(set (match_operand:DI 0 "register_operand" "=r")
8924         (zero_extend:DI
8925           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8926                   (match_operand:SI 2 "general_operand" "rim"))))
8927    (clobber (reg:CC FLAGS_REG))]
8928   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8929   "xor{l}\t{%2, %k0|%k0, %2}"
8930   [(set_attr "type" "alu")
8931    (set_attr "mode" "SI")])
8933 (define_insn "*xorsi_1_zext_imm"
8934   [(set (match_operand:DI 0 "register_operand" "=r")
8935         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8936                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8937    (clobber (reg:CC FLAGS_REG))]
8938   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8939   "xor{l}\t{%2, %k0|%k0, %2}"
8940   [(set_attr "type" "alu")
8941    (set_attr "mode" "SI")])
8943 (define_insn "*xorsi_2"
8944   [(set (reg FLAGS_REG)
8945         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8946                          (match_operand:SI 2 "general_operand" "rim,ri"))
8947                  (const_int 0)))
8948    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8949         (xor:SI (match_dup 1) (match_dup 2)))]
8950   "ix86_match_ccmode (insn, CCNOmode)
8951    && ix86_binary_operator_ok (XOR, SImode, operands)"
8952   "xor{l}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "SI")])
8956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957 ;; ??? Special case for immediate operand is missing - it is tricky.
8958 (define_insn "*xorsi_2_zext"
8959   [(set (reg FLAGS_REG)
8960         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8961                          (match_operand:SI 2 "general_operand" "rim"))
8962                  (const_int 0)))
8963    (set (match_operand:DI 0 "register_operand" "=r")
8964         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8965   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8966    && ix86_binary_operator_ok (XOR, SImode, operands)"
8967   "xor{l}\t{%2, %k0|%k0, %2}"
8968   [(set_attr "type" "alu")
8969    (set_attr "mode" "SI")])
8971 (define_insn "*xorsi_2_zext_imm"
8972   [(set (reg FLAGS_REG)
8973         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8974                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8975                  (const_int 0)))
8976    (set (match_operand:DI 0 "register_operand" "=r")
8977         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8978   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979    && ix86_binary_operator_ok (XOR, SImode, operands)"
8980   "xor{l}\t{%2, %k0|%k0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8984 (define_insn "*xorsi_3"
8985   [(set (reg FLAGS_REG)
8986         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8987                          (match_operand:SI 2 "general_operand" "rim"))
8988                  (const_int 0)))
8989    (clobber (match_scratch:SI 0 "=r"))]
8990   "ix86_match_ccmode (insn, CCNOmode)
8991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8992   "xor{l}\t{%2, %0|%0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "SI")])
8996 (define_expand "xorhi3"
8997   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8998         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8999                 (match_operand:HI 2 "general_operand" "")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   "TARGET_HIMODE_MATH"
9002   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9004 (define_insn "*xorhi_1"
9005   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9006         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9007                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "ix86_binary_operator_ok (XOR, HImode, operands)"
9010   "xor{w}\t{%2, %0|%0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "HI")])
9014 (define_insn "*xorhi_2"
9015   [(set (reg FLAGS_REG)
9016         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9017                          (match_operand:HI 2 "general_operand" "rim,ri"))
9018                  (const_int 0)))
9019    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9020         (xor:HI (match_dup 1) (match_dup 2)))]
9021   "ix86_match_ccmode (insn, CCNOmode)
9022    && ix86_binary_operator_ok (XOR, HImode, operands)"
9023   "xor{w}\t{%2, %0|%0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "HI")])
9027 (define_insn "*xorhi_3"
9028   [(set (reg FLAGS_REG)
9029         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9030                          (match_operand:HI 2 "general_operand" "rim"))
9031                  (const_int 0)))
9032    (clobber (match_scratch:HI 0 "=r"))]
9033   "ix86_match_ccmode (insn, CCNOmode)
9034    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9035   "xor{w}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "HI")])
9039 (define_expand "xorqi3"
9040   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9041         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9042                 (match_operand:QI 2 "general_operand" "")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "TARGET_QIMODE_MATH"
9045   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9047 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9048 (define_insn "*xorqi_1"
9049   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9050         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9051                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9052    (clobber (reg:CC FLAGS_REG))]
9053   "ix86_binary_operator_ok (XOR, QImode, operands)"
9054   "@
9055    xor{b}\t{%2, %0|%0, %2}
9056    xor{b}\t{%2, %0|%0, %2}
9057    xor{l}\t{%k2, %k0|%k0, %k2}"
9058   [(set_attr "type" "alu")
9059    (set_attr "mode" "QI,QI,SI")])
9061 (define_insn "*xorqi_1_slp"
9062   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9063         (xor:QI (match_dup 0)
9064                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9065    (clobber (reg:CC FLAGS_REG))]
9066   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9067    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9068   "xor{b}\t{%1, %0|%0, %1}"
9069   [(set_attr "type" "alu1")
9070    (set_attr "mode" "QI")])
9072 (define_insn "xorqi_ext_0"
9073   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9074                          (const_int 8)
9075                          (const_int 8))
9076         (xor:SI 
9077           (zero_extract:SI
9078             (match_operand 1 "ext_register_operand" "0")
9079             (const_int 8)
9080             (const_int 8))
9081           (match_operand 2 "const_int_operand" "n")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9084   "xor{b}\t{%2, %h0|%h0, %2}"
9085   [(set_attr "type" "alu")
9086    (set_attr "length_immediate" "1")
9087    (set_attr "mode" "QI")])
9089 (define_insn "*xorqi_ext_1"
9090   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9091                          (const_int 8)
9092                          (const_int 8))
9093         (xor:SI 
9094           (zero_extract:SI
9095             (match_operand 1 "ext_register_operand" "0")
9096             (const_int 8)
9097             (const_int 8))
9098           (zero_extend:SI
9099             (match_operand:QI 2 "general_operand" "Qm"))))
9100    (clobber (reg:CC FLAGS_REG))]
9101   "!TARGET_64BIT
9102    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9103   "xor{b}\t{%2, %h0|%h0, %2}"
9104   [(set_attr "type" "alu")
9105    (set_attr "length_immediate" "0")
9106    (set_attr "mode" "QI")])
9108 (define_insn "*xorqi_ext_1_rex64"
9109   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110                          (const_int 8)
9111                          (const_int 8))
9112         (xor:SI 
9113           (zero_extract:SI
9114             (match_operand 1 "ext_register_operand" "0")
9115             (const_int 8)
9116             (const_int 8))
9117           (zero_extend:SI
9118             (match_operand 2 "ext_register_operand" "Q"))))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "TARGET_64BIT
9121    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9122   "xor{b}\t{%2, %h0|%h0, %2}"
9123   [(set_attr "type" "alu")
9124    (set_attr "length_immediate" "0")
9125    (set_attr "mode" "QI")])
9127 (define_insn "*xorqi_ext_2"
9128   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129                          (const_int 8)
9130                          (const_int 8))
9131         (xor:SI 
9132           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9133                            (const_int 8)
9134                            (const_int 8))
9135           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9136                            (const_int 8)
9137                            (const_int 8))))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140   "xor{b}\t{%h2, %h0|%h0, %h2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9145 (define_insn "*xorqi_cc_1"
9146   [(set (reg FLAGS_REG)
9147         (compare
9148           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9149                   (match_operand:QI 2 "general_operand" "qim,qi"))
9150           (const_int 0)))
9151    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9152         (xor:QI (match_dup 1) (match_dup 2)))]
9153   "ix86_match_ccmode (insn, CCNOmode)
9154    && ix86_binary_operator_ok (XOR, QImode, operands)"
9155   "xor{b}\t{%2, %0|%0, %2}"
9156   [(set_attr "type" "alu")
9157    (set_attr "mode" "QI")])
9159 (define_insn "*xorqi_2_slp"
9160   [(set (reg FLAGS_REG)
9161         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9162                          (match_operand:QI 1 "general_operand" "qim,qi"))
9163                  (const_int 0)))
9164    (set (strict_low_part (match_dup 0))
9165         (xor:QI (match_dup 0) (match_dup 1)))]
9166   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9167    && ix86_match_ccmode (insn, CCNOmode)
9168    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9169   "xor{b}\t{%1, %0|%0, %1}"
9170   [(set_attr "type" "alu1")
9171    (set_attr "mode" "QI")])
9173 (define_insn "*xorqi_cc_2"
9174   [(set (reg FLAGS_REG)
9175         (compare
9176           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9177                   (match_operand:QI 2 "general_operand" "qim"))
9178           (const_int 0)))
9179    (clobber (match_scratch:QI 0 "=q"))]
9180   "ix86_match_ccmode (insn, CCNOmode)
9181    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9182   "xor{b}\t{%2, %0|%0, %2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "mode" "QI")])
9186 (define_insn "*xorqi_cc_ext_1"
9187   [(set (reg FLAGS_REG)
9188         (compare
9189           (xor:SI
9190             (zero_extract:SI
9191               (match_operand 1 "ext_register_operand" "0")
9192               (const_int 8)
9193               (const_int 8))
9194             (match_operand:QI 2 "general_operand" "qmn"))
9195           (const_int 0)))
9196    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9197                          (const_int 8)
9198                          (const_int 8))
9199         (xor:SI 
9200           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9201           (match_dup 2)))]
9202   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9203   "xor{b}\t{%2, %h0|%h0, %2}"
9204   [(set_attr "type" "alu")
9205    (set_attr "mode" "QI")])
9207 (define_insn "*xorqi_cc_ext_1_rex64"
9208   [(set (reg FLAGS_REG)
9209         (compare
9210           (xor:SI
9211             (zero_extract:SI
9212               (match_operand 1 "ext_register_operand" "0")
9213               (const_int 8)
9214               (const_int 8))
9215             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9216           (const_int 0)))
9217    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218                          (const_int 8)
9219                          (const_int 8))
9220         (xor:SI 
9221           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9222           (match_dup 2)))]
9223   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9224   "xor{b}\t{%2, %h0|%h0, %2}"
9225   [(set_attr "type" "alu")
9226    (set_attr "mode" "QI")])
9228 (define_expand "xorqi_cc_ext_1"
9229   [(parallel [
9230      (set (reg:CCNO FLAGS_REG)
9231           (compare:CCNO
9232             (xor:SI
9233               (zero_extract:SI
9234                 (match_operand 1 "ext_register_operand" "")
9235                 (const_int 8)
9236                 (const_int 8))
9237               (match_operand:QI 2 "general_operand" ""))
9238             (const_int 0)))
9239      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9240                            (const_int 8)
9241                            (const_int 8))
9242           (xor:SI 
9243             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9244             (match_dup 2)))])]
9245   ""
9246   "")
9248 (define_split
9249   [(set (match_operand 0 "register_operand" "")
9250         (xor (match_operand 1 "register_operand" "")
9251              (match_operand 2 "const_int_operand" "")))
9252    (clobber (reg:CC FLAGS_REG))]
9253    "reload_completed
9254     && QI_REG_P (operands[0])
9255     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9256     && !(INTVAL (operands[2]) & ~(255 << 8))
9257     && GET_MODE (operands[0]) != QImode"
9258   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9259                    (xor:SI (zero_extract:SI (match_dup 1)
9260                                             (const_int 8) (const_int 8))
9261                            (match_dup 2)))
9262               (clobber (reg:CC FLAGS_REG))])]
9263   "operands[0] = gen_lowpart (SImode, operands[0]);
9264    operands[1] = gen_lowpart (SImode, operands[1]);
9265    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9267 ;; Since XOR can be encoded with sign extended immediate, this is only
9268 ;; profitable when 7th bit is set.
9269 (define_split
9270   [(set (match_operand 0 "register_operand" "")
9271         (xor (match_operand 1 "general_operand" "")
9272              (match_operand 2 "const_int_operand" "")))
9273    (clobber (reg:CC FLAGS_REG))]
9274    "reload_completed
9275     && ANY_QI_REG_P (operands[0])
9276     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9277     && !(INTVAL (operands[2]) & ~255)
9278     && (INTVAL (operands[2]) & 128)
9279     && GET_MODE (operands[0]) != QImode"
9280   [(parallel [(set (strict_low_part (match_dup 0))
9281                    (xor:QI (match_dup 1)
9282                            (match_dup 2)))
9283               (clobber (reg:CC FLAGS_REG))])]
9284   "operands[0] = gen_lowpart (QImode, operands[0]);
9285    operands[1] = gen_lowpart (QImode, operands[1]);
9286    operands[2] = gen_lowpart (QImode, operands[2]);")
9288 ;; Negation instructions
9290 (define_expand "negti2"
9291   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9292                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9293               (clobber (reg:CC FLAGS_REG))])]
9294   "TARGET_64BIT"
9295   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9297 (define_insn "*negti2_1"
9298   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9299         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9300    (clobber (reg:CC FLAGS_REG))]
9301   "TARGET_64BIT
9302    && ix86_unary_operator_ok (NEG, TImode, operands)"
9303   "#")
9305 (define_split
9306   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9307         (neg:TI (match_operand:TI 1 "general_operand" "")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   "TARGET_64BIT && reload_completed"
9310   [(parallel
9311     [(set (reg:CCZ FLAGS_REG)
9312           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9313      (set (match_dup 0) (neg:DI (match_dup 2)))])
9314    (parallel
9315     [(set (match_dup 1)
9316           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9317                             (match_dup 3))
9318                    (const_int 0)))
9319      (clobber (reg:CC FLAGS_REG))])
9320    (parallel
9321     [(set (match_dup 1)
9322           (neg:DI (match_dup 1)))
9323      (clobber (reg:CC FLAGS_REG))])]
9324   "split_ti (operands+1, 1, operands+2, operands+3);
9325    split_ti (operands+0, 1, operands+0, operands+1);")
9327 (define_expand "negdi2"
9328   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9329                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9330               (clobber (reg:CC FLAGS_REG))])]
9331   ""
9332   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9334 (define_insn "*negdi2_1"
9335   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9336         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9337    (clobber (reg:CC FLAGS_REG))]
9338   "!TARGET_64BIT
9339    && ix86_unary_operator_ok (NEG, DImode, operands)"
9340   "#")
9342 (define_split
9343   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9344         (neg:DI (match_operand:DI 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:SI (match_dup 2)) (const_int 0)))
9350      (set (match_dup 0) (neg:SI (match_dup 2)))])
9351    (parallel
9352     [(set (match_dup 1)
9353           (plus:SI (plus:SI (ltu:SI (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:SI (match_dup 1)))
9360      (clobber (reg:CC FLAGS_REG))])]
9361   "split_di (operands+1, 1, operands+2, operands+3);
9362    split_di (operands+0, 1, operands+0, operands+1);")
9364 (define_insn "*negdi2_1_rex64"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9366         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9369   "neg{q}\t%0"
9370   [(set_attr "type" "negnot")
9371    (set_attr "mode" "DI")])
9373 ;; The problem with neg is that it does not perform (compare x 0),
9374 ;; it really performs (compare 0 x), which leaves us with the zero
9375 ;; flag being the only useful item.
9377 (define_insn "*negdi2_cmpz_rex64"
9378   [(set (reg:CCZ FLAGS_REG)
9379         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9380                      (const_int 0)))
9381    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9382         (neg:DI (match_dup 1)))]
9383   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9384   "neg{q}\t%0"
9385   [(set_attr "type" "negnot")
9386    (set_attr "mode" "DI")])
9389 (define_expand "negsi2"
9390   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9391                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9392               (clobber (reg:CC FLAGS_REG))])]
9393   ""
9394   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9396 (define_insn "*negsi2_1"
9397   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9398         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9399    (clobber (reg:CC FLAGS_REG))]
9400   "ix86_unary_operator_ok (NEG, SImode, operands)"
9401   "neg{l}\t%0"
9402   [(set_attr "type" "negnot")
9403    (set_attr "mode" "SI")])
9405 ;; Combine is quite creative about this pattern.
9406 (define_insn "*negsi2_1_zext"
9407   [(set (match_operand:DI 0 "register_operand" "=r")
9408         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9409                                         (const_int 32)))
9410                      (const_int 32)))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9413   "neg{l}\t%k0"
9414   [(set_attr "type" "negnot")
9415    (set_attr "mode" "SI")])
9417 ;; The problem with neg is that it does not perform (compare x 0),
9418 ;; it really performs (compare 0 x), which leaves us with the zero
9419 ;; flag being the only useful item.
9421 (define_insn "*negsi2_cmpz"
9422   [(set (reg:CCZ FLAGS_REG)
9423         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9424                      (const_int 0)))
9425    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9426         (neg:SI (match_dup 1)))]
9427   "ix86_unary_operator_ok (NEG, SImode, operands)"
9428   "neg{l}\t%0"
9429   [(set_attr "type" "negnot")
9430    (set_attr "mode" "SI")])
9432 (define_insn "*negsi2_cmpz_zext"
9433   [(set (reg:CCZ FLAGS_REG)
9434         (compare:CCZ (lshiftrt:DI
9435                        (neg:DI (ashift:DI
9436                                  (match_operand:DI 1 "register_operand" "0")
9437                                  (const_int 32)))
9438                        (const_int 32))
9439                      (const_int 0)))
9440    (set (match_operand:DI 0 "register_operand" "=r")
9441         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9442                                         (const_int 32)))
9443                      (const_int 32)))]
9444   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9445   "neg{l}\t%k0"
9446   [(set_attr "type" "negnot")
9447    (set_attr "mode" "SI")])
9449 (define_expand "neghi2"
9450   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9451                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9452               (clobber (reg:CC FLAGS_REG))])]
9453   "TARGET_HIMODE_MATH"
9454   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9456 (define_insn "*neghi2_1"
9457   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9458         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9459    (clobber (reg:CC FLAGS_REG))]
9460   "ix86_unary_operator_ok (NEG, HImode, operands)"
9461   "neg{w}\t%0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "HI")])
9465 (define_insn "*neghi2_cmpz"
9466   [(set (reg:CCZ FLAGS_REG)
9467         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9468                      (const_int 0)))
9469    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9470         (neg:HI (match_dup 1)))]
9471   "ix86_unary_operator_ok (NEG, HImode, operands)"
9472   "neg{w}\t%0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "HI")])
9476 (define_expand "negqi2"
9477   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9478                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9479               (clobber (reg:CC FLAGS_REG))])]
9480   "TARGET_QIMODE_MATH"
9481   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9483 (define_insn "*negqi2_1"
9484   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9485         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "ix86_unary_operator_ok (NEG, QImode, operands)"
9488   "neg{b}\t%0"
9489   [(set_attr "type" "negnot")
9490    (set_attr "mode" "QI")])
9492 (define_insn "*negqi2_cmpz"
9493   [(set (reg:CCZ FLAGS_REG)
9494         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9495                      (const_int 0)))
9496    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9497         (neg:QI (match_dup 1)))]
9498   "ix86_unary_operator_ok (NEG, QImode, operands)"
9499   "neg{b}\t%0"
9500   [(set_attr "type" "negnot")
9501    (set_attr "mode" "QI")])
9503 ;; Changing of sign for FP values is doable using integer unit too.
9505 (define_expand "negsf2"
9506   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9507         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9508   "TARGET_80387 || TARGET_SSE_MATH"
9509   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9511 (define_expand "abssf2"
9512   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9513         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9514   "TARGET_80387 || TARGET_SSE_MATH"
9515   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9517 (define_insn "*absnegsf2_mixed"
9518   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9519         (match_operator:SF 3 "absneg_operator"
9520           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9521    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9524    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9525   "#")
9527 (define_insn "*absnegsf2_sse"
9528   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9529         (match_operator:SF 3 "absneg_operator"
9530           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9531    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9532    (clobber (reg:CC FLAGS_REG))]
9533   "TARGET_SSE_MATH
9534    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9535   "#")
9537 (define_insn "*absnegsf2_i387"
9538   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9539         (match_operator:SF 3 "absneg_operator"
9540           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9541    (use (match_operand 2 "" ""))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "TARGET_80387 && !TARGET_SSE_MATH
9544    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9545   "#")
9547 (define_expand "copysignsf3"
9548   [(match_operand:SF 0 "register_operand" "")
9549    (match_operand:SF 1 "nonmemory_operand" "")
9550    (match_operand:SF 2 "register_operand" "")]
9551   "TARGET_SSE_MATH"
9553   ix86_expand_copysign (operands);
9554   DONE;
9557 (define_insn_and_split "copysignsf3_const"
9558   [(set (match_operand:SF 0 "register_operand"          "=x")
9559         (unspec:SF
9560           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9561            (match_operand:SF 2 "register_operand"       "0")
9562            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9563           UNSPEC_COPYSIGN))]
9564   "TARGET_SSE_MATH"
9565   "#"
9566   "&& reload_completed"
9567   [(const_int 0)]
9569   ix86_split_copysign_const (operands);
9570   DONE;
9573 (define_insn "copysignsf3_var"
9574   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9575         (unspec:SF
9576           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9577            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9578            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9579            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9580           UNSPEC_COPYSIGN))
9581    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9582   "TARGET_SSE_MATH"
9583   "#")
9585 (define_split
9586   [(set (match_operand:SF 0 "register_operand" "")
9587         (unspec:SF
9588           [(match_operand:SF 2 "register_operand" "")
9589            (match_operand:SF 3 "register_operand" "")
9590            (match_operand:V4SF 4 "" "")
9591            (match_operand:V4SF 5 "" "")]
9592           UNSPEC_COPYSIGN))
9593    (clobber (match_scratch:V4SF 1 ""))]
9594   "TARGET_SSE_MATH && reload_completed"
9595   [(const_int 0)]
9597   ix86_split_copysign_var (operands);
9598   DONE;
9601 (define_expand "negdf2"
9602   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9603         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9604   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9605   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9607 (define_expand "absdf2"
9608   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9609         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9610   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9611   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9613 (define_insn "*absnegdf2_mixed"
9614   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9615         (match_operator:DF 3 "absneg_operator"
9616           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9617    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9618    (clobber (reg:CC FLAGS_REG))]
9619   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9620    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9621   "#")
9623 (define_insn "*absnegdf2_sse"
9624   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9625         (match_operator:DF 3 "absneg_operator"
9626           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9627    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9628    (clobber (reg:CC FLAGS_REG))]
9629   "TARGET_SSE2 && TARGET_SSE_MATH
9630    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9631   "#")
9633 (define_insn "*absnegdf2_i387"
9634   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9635         (match_operator:DF 3 "absneg_operator"
9636           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9637    (use (match_operand 2 "" ""))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9640    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9641   "#")
9643 (define_expand "copysigndf3"
9644   [(match_operand:DF 0 "register_operand" "")
9645    (match_operand:DF 1 "nonmemory_operand" "")
9646    (match_operand:DF 2 "register_operand" "")]
9647   "TARGET_SSE2 && TARGET_SSE_MATH"
9649   ix86_expand_copysign (operands);
9650   DONE;
9653 (define_insn_and_split "copysigndf3_const"
9654   [(set (match_operand:DF 0 "register_operand"          "=x")
9655         (unspec:DF
9656           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9657            (match_operand:DF 2 "register_operand"       "0")
9658            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9659           UNSPEC_COPYSIGN))]
9660   "TARGET_SSE2 && TARGET_SSE_MATH"
9661   "#"
9662   "&& reload_completed"
9663   [(const_int 0)]
9665   ix86_split_copysign_const (operands);
9666   DONE;
9669 (define_insn "copysigndf3_var"
9670   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9671         (unspec:DF
9672           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9673            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9674            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9675            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9676           UNSPEC_COPYSIGN))
9677    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9678   "TARGET_SSE2 && TARGET_SSE_MATH"
9679   "#")
9681 (define_split
9682   [(set (match_operand:DF 0 "register_operand" "")
9683         (unspec:DF
9684           [(match_operand:DF 2 "register_operand" "")
9685            (match_operand:DF 3 "register_operand" "")
9686            (match_operand:V2DF 4 "" "")
9687            (match_operand:V2DF 5 "" "")]
9688           UNSPEC_COPYSIGN))
9689    (clobber (match_scratch:V2DF 1 ""))]
9690   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9691   [(const_int 0)]
9693   ix86_split_copysign_var (operands);
9694   DONE;
9697 (define_expand "negxf2"
9698   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9699         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9700   "TARGET_80387"
9701   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9703 (define_expand "absxf2"
9704   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9705         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9706   "TARGET_80387"
9707   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9709 (define_insn "*absnegxf2_i387"
9710   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9711         (match_operator:XF 3 "absneg_operator"
9712           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9713    (use (match_operand 2 "" ""))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "TARGET_80387
9716    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9717   "#")
9719 ;; Splitters for fp abs and neg.
9721 (define_split
9722   [(set (match_operand 0 "fp_register_operand" "")
9723         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9724    (use (match_operand 2 "" ""))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "reload_completed"
9727   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9729 (define_split
9730   [(set (match_operand 0 "register_operand" "")
9731         (match_operator 3 "absneg_operator"
9732           [(match_operand 1 "register_operand" "")]))
9733    (use (match_operand 2 "nonimmediate_operand" ""))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "reload_completed && SSE_REG_P (operands[0])"
9736   [(set (match_dup 0) (match_dup 3))]
9738   enum machine_mode mode = GET_MODE (operands[0]);
9739   enum machine_mode vmode = GET_MODE (operands[2]);
9740   rtx tmp;
9741   
9742   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9743   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9744   if (operands_match_p (operands[0], operands[2]))
9745     {
9746       tmp = operands[1];
9747       operands[1] = operands[2];
9748       operands[2] = tmp;
9749     }
9750   if (GET_CODE (operands[3]) == ABS)
9751     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9752   else
9753     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9754   operands[3] = tmp;
9757 (define_split
9758   [(set (match_operand:SF 0 "register_operand" "")
9759         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9760    (use (match_operand:V4SF 2 "" ""))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "reload_completed"
9763   [(parallel [(set (match_dup 0) (match_dup 1))
9764               (clobber (reg:CC FLAGS_REG))])]
9766   rtx tmp;
9767   operands[0] = gen_lowpart (SImode, operands[0]);
9768   if (GET_CODE (operands[1]) == ABS)
9769     {
9770       tmp = gen_int_mode (0x7fffffff, SImode);
9771       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9772     }
9773   else
9774     {
9775       tmp = gen_int_mode (0x80000000, SImode);
9776       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777     }
9778   operands[1] = tmp;
9781 (define_split
9782   [(set (match_operand:DF 0 "register_operand" "")
9783         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9784    (use (match_operand 2 "" ""))
9785    (clobber (reg:CC FLAGS_REG))]
9786   "reload_completed"
9787   [(parallel [(set (match_dup 0) (match_dup 1))
9788               (clobber (reg:CC FLAGS_REG))])]
9790   rtx tmp;
9791   if (TARGET_64BIT)
9792     {
9793       tmp = gen_lowpart (DImode, operands[0]);
9794       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9795       operands[0] = tmp;
9797       if (GET_CODE (operands[1]) == ABS)
9798         tmp = const0_rtx;
9799       else
9800         tmp = gen_rtx_NOT (DImode, tmp);
9801     }
9802   else
9803     {
9804       operands[0] = gen_highpart (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     }
9816   operands[1] = tmp;
9819 (define_split
9820   [(set (match_operand:XF 0 "register_operand" "")
9821         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9822    (use (match_operand 2 "" ""))
9823    (clobber (reg:CC FLAGS_REG))]
9824   "reload_completed"
9825   [(parallel [(set (match_dup 0) (match_dup 1))
9826               (clobber (reg:CC FLAGS_REG))])]
9828   rtx tmp;
9829   operands[0] = gen_rtx_REG (SImode,
9830                              true_regnum (operands[0])
9831                              + (TARGET_64BIT ? 1 : 2));
9832   if (GET_CODE (operands[1]) == ABS)
9833     {
9834       tmp = GEN_INT (0x7fff);
9835       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9836     }
9837   else
9838     {
9839       tmp = GEN_INT (0x8000);
9840       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9841     }
9842   operands[1] = tmp;
9845 (define_split
9846   [(set (match_operand 0 "memory_operand" "")
9847         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9848    (use (match_operand 2 "" ""))
9849    (clobber (reg:CC FLAGS_REG))]
9850   "reload_completed"
9851   [(parallel [(set (match_dup 0) (match_dup 1))
9852               (clobber (reg:CC FLAGS_REG))])]
9854   enum machine_mode mode = GET_MODE (operands[0]);
9855   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9856   rtx tmp;
9858   operands[0] = adjust_address (operands[0], QImode, size - 1);
9859   if (GET_CODE (operands[1]) == ABS)
9860     {
9861       tmp = gen_int_mode (0x7f, QImode);
9862       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9863     }
9864   else
9865     {
9866       tmp = gen_int_mode (0x80, QImode);
9867       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9868     }
9869   operands[1] = tmp;
9872 ;; Conditionalize these after reload. If they match before reload, we 
9873 ;; lose the clobber and ability to use integer instructions.
9875 (define_insn "*negsf2_1"
9876   [(set (match_operand:SF 0 "register_operand" "=f")
9877         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9878   "TARGET_80387 && reload_completed"
9879   "fchs"
9880   [(set_attr "type" "fsgn")
9881    (set_attr "mode" "SF")])
9883 (define_insn "*negdf2_1"
9884   [(set (match_operand:DF 0 "register_operand" "=f")
9885         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9886   "TARGET_80387 && reload_completed"
9887   "fchs"
9888   [(set_attr "type" "fsgn")
9889    (set_attr "mode" "DF")])
9891 (define_insn "*negxf2_1"
9892   [(set (match_operand:XF 0 "register_operand" "=f")
9893         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9894   "TARGET_80387 && reload_completed"
9895   "fchs"
9896   [(set_attr "type" "fsgn")
9897    (set_attr "mode" "XF")])
9899 (define_insn "*abssf2_1"
9900   [(set (match_operand:SF 0 "register_operand" "=f")
9901         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9902   "TARGET_80387 && reload_completed"
9903   "fabs"
9904   [(set_attr "type" "fsgn")
9905    (set_attr "mode" "SF")])
9907 (define_insn "*absdf2_1"
9908   [(set (match_operand:DF 0 "register_operand" "=f")
9909         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9910   "TARGET_80387 && reload_completed"
9911   "fabs"
9912   [(set_attr "type" "fsgn")
9913    (set_attr "mode" "DF")])
9915 (define_insn "*absxf2_1"
9916   [(set (match_operand:XF 0 "register_operand" "=f")
9917         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9918   "TARGET_80387 && reload_completed"
9919   "fabs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "DF")])
9923 (define_insn "*negextendsfdf2"
9924   [(set (match_operand:DF 0 "register_operand" "=f")
9925         (neg:DF (float_extend:DF
9926                   (match_operand:SF 1 "register_operand" "0"))))]
9927   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9928   "fchs"
9929   [(set_attr "type" "fsgn")
9930    (set_attr "mode" "DF")])
9932 (define_insn "*negextenddfxf2"
9933   [(set (match_operand:XF 0 "register_operand" "=f")
9934         (neg:XF (float_extend:XF
9935                   (match_operand:DF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9941 (define_insn "*negextendsfxf2"
9942   [(set (match_operand:XF 0 "register_operand" "=f")
9943         (neg:XF (float_extend:XF
9944                   (match_operand:SF 1 "register_operand" "0"))))]
9945   "TARGET_80387"
9946   "fchs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "XF")])
9950 (define_insn "*absextendsfdf2"
9951   [(set (match_operand:DF 0 "register_operand" "=f")
9952         (abs:DF (float_extend:DF
9953                   (match_operand:SF 1 "register_operand" "0"))))]
9954   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9955   "fabs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "DF")])
9959 (define_insn "*absextenddfxf2"
9960   [(set (match_operand:XF 0 "register_operand" "=f")
9961         (abs:XF (float_extend:XF
9962           (match_operand:DF 1 "register_operand" "0"))))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "XF")])
9968 (define_insn "*absextendsfxf2"
9969   [(set (match_operand:XF 0 "register_operand" "=f")
9970         (abs:XF (float_extend:XF
9971           (match_operand:SF 1 "register_operand" "0"))))]
9972   "TARGET_80387"
9973   "fabs"
9974   [(set_attr "type" "fsgn")
9975    (set_attr "mode" "XF")])
9977 ;; One complement instructions
9979 (define_expand "one_cmpldi2"
9980   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9981         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9982   "TARGET_64BIT"
9983   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9985 (define_insn "*one_cmpldi2_1_rex64"
9986   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9987         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9988   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9989   "not{q}\t%0"
9990   [(set_attr "type" "negnot")
9991    (set_attr "mode" "DI")])
9993 (define_insn "*one_cmpldi2_2_rex64"
9994   [(set (reg FLAGS_REG)
9995         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9996                  (const_int 0)))
9997    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9998         (not:DI (match_dup 1)))]
9999   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10000    && ix86_unary_operator_ok (NOT, DImode, operands)"
10001   "#"
10002   [(set_attr "type" "alu1")
10003    (set_attr "mode" "DI")])
10005 (define_split
10006   [(set (match_operand 0 "flags_reg_operand" "")
10007         (match_operator 2 "compare_operator"
10008           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10009            (const_int 0)]))
10010    (set (match_operand:DI 1 "nonimmediate_operand" "")
10011         (not:DI (match_dup 3)))]
10012   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10013   [(parallel [(set (match_dup 0)
10014                    (match_op_dup 2
10015                      [(xor:DI (match_dup 3) (const_int -1))
10016                       (const_int 0)]))
10017               (set (match_dup 1)
10018                    (xor:DI (match_dup 3) (const_int -1)))])]
10019   "")
10021 (define_expand "one_cmplsi2"
10022   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10023         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10024   ""
10025   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10027 (define_insn "*one_cmplsi2_1"
10028   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10029         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10030   "ix86_unary_operator_ok (NOT, SImode, operands)"
10031   "not{l}\t%0"
10032   [(set_attr "type" "negnot")
10033    (set_attr "mode" "SI")])
10035 ;; ??? Currently never generated - xor is used instead.
10036 (define_insn "*one_cmplsi2_1_zext"
10037   [(set (match_operand:DI 0 "register_operand" "=r")
10038         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10039   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10040   "not{l}\t%k0"
10041   [(set_attr "type" "negnot")
10042    (set_attr "mode" "SI")])
10044 (define_insn "*one_cmplsi2_2"
10045   [(set (reg FLAGS_REG)
10046         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10047                  (const_int 0)))
10048    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10049         (not:SI (match_dup 1)))]
10050   "ix86_match_ccmode (insn, CCNOmode)
10051    && ix86_unary_operator_ok (NOT, SImode, operands)"
10052   "#"
10053   [(set_attr "type" "alu1")
10054    (set_attr "mode" "SI")])
10056 (define_split
10057   [(set (match_operand 0 "flags_reg_operand" "")
10058         (match_operator 2 "compare_operator"
10059           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10060            (const_int 0)]))
10061    (set (match_operand:SI 1 "nonimmediate_operand" "")
10062         (not:SI (match_dup 3)))]
10063   "ix86_match_ccmode (insn, CCNOmode)"
10064   [(parallel [(set (match_dup 0)
10065                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10066                                     (const_int 0)]))
10067               (set (match_dup 1)
10068                    (xor:SI (match_dup 3) (const_int -1)))])]
10069   "")
10071 ;; ??? Currently never generated - xor is used instead.
10072 (define_insn "*one_cmplsi2_2_zext"
10073   [(set (reg FLAGS_REG)
10074         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10075                  (const_int 0)))
10076    (set (match_operand:DI 0 "register_operand" "=r")
10077         (zero_extend:DI (not:SI (match_dup 1))))]
10078   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10079    && ix86_unary_operator_ok (NOT, SImode, operands)"
10080   "#"
10081   [(set_attr "type" "alu1")
10082    (set_attr "mode" "SI")])
10084 (define_split
10085   [(set (match_operand 0 "flags_reg_operand" "")
10086         (match_operator 2 "compare_operator"
10087           [(not:SI (match_operand:SI 3 "register_operand" ""))
10088            (const_int 0)]))
10089    (set (match_operand:DI 1 "register_operand" "")
10090         (zero_extend:DI (not:SI (match_dup 3))))]
10091   "ix86_match_ccmode (insn, CCNOmode)"
10092   [(parallel [(set (match_dup 0)
10093                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10094                                     (const_int 0)]))
10095               (set (match_dup 1)
10096                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10097   "")
10099 (define_expand "one_cmplhi2"
10100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10101         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10102   "TARGET_HIMODE_MATH"
10103   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10105 (define_insn "*one_cmplhi2_1"
10106   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10107         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10108   "ix86_unary_operator_ok (NOT, HImode, operands)"
10109   "not{w}\t%0"
10110   [(set_attr "type" "negnot")
10111    (set_attr "mode" "HI")])
10113 (define_insn "*one_cmplhi2_2"
10114   [(set (reg FLAGS_REG)
10115         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10116                  (const_int 0)))
10117    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10118         (not:HI (match_dup 1)))]
10119   "ix86_match_ccmode (insn, CCNOmode)
10120    && ix86_unary_operator_ok (NEG, HImode, operands)"
10121   "#"
10122   [(set_attr "type" "alu1")
10123    (set_attr "mode" "HI")])
10125 (define_split
10126   [(set (match_operand 0 "flags_reg_operand" "")
10127         (match_operator 2 "compare_operator"
10128           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10129            (const_int 0)]))
10130    (set (match_operand:HI 1 "nonimmediate_operand" "")
10131         (not:HI (match_dup 3)))]
10132   "ix86_match_ccmode (insn, CCNOmode)"
10133   [(parallel [(set (match_dup 0)
10134                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10135                                     (const_int 0)]))
10136               (set (match_dup 1)
10137                    (xor:HI (match_dup 3) (const_int -1)))])]
10138   "")
10140 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10141 (define_expand "one_cmplqi2"
10142   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10143         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10144   "TARGET_QIMODE_MATH"
10145   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10147 (define_insn "*one_cmplqi2_1"
10148   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10149         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10150   "ix86_unary_operator_ok (NOT, QImode, operands)"
10151   "@
10152    not{b}\t%0
10153    not{l}\t%k0"
10154   [(set_attr "type" "negnot")
10155    (set_attr "mode" "QI,SI")])
10157 (define_insn "*one_cmplqi2_2"
10158   [(set (reg FLAGS_REG)
10159         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10160                  (const_int 0)))
10161    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10162         (not:QI (match_dup 1)))]
10163   "ix86_match_ccmode (insn, CCNOmode)
10164    && ix86_unary_operator_ok (NOT, QImode, operands)"
10165   "#"
10166   [(set_attr "type" "alu1")
10167    (set_attr "mode" "QI")])
10169 (define_split
10170   [(set (match_operand 0 "flags_reg_operand" "")
10171         (match_operator 2 "compare_operator"
10172           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10173            (const_int 0)]))
10174    (set (match_operand:QI 1 "nonimmediate_operand" "")
10175         (not:QI (match_dup 3)))]
10176   "ix86_match_ccmode (insn, CCNOmode)"
10177   [(parallel [(set (match_dup 0)
10178                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10179                                     (const_int 0)]))
10180               (set (match_dup 1)
10181                    (xor:QI (match_dup 3) (const_int -1)))])]
10182   "")
10184 ;; Arithmetic shift instructions
10186 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10187 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10188 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10189 ;; from the assembler input.
10191 ;; This instruction shifts the target reg/mem as usual, but instead of
10192 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10193 ;; is a left shift double, bits are taken from the high order bits of
10194 ;; reg, else if the insn is a shift right double, bits are taken from the
10195 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10196 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10198 ;; Since sh[lr]d does not change the `reg' operand, that is done
10199 ;; separately, making all shifts emit pairs of shift double and normal
10200 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10201 ;; support a 63 bit shift, each shift where the count is in a reg expands
10202 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10204 ;; If the shift count is a constant, we need never emit more than one
10205 ;; shift pair, instead using moves and sign extension for counts greater
10206 ;; than 31.
10208 (define_expand "ashlti3"
10209   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10210                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10211                               (match_operand:QI 2 "nonmemory_operand" "")))
10212               (clobber (reg:CC FLAGS_REG))])]
10213   "TARGET_64BIT"
10215   if (! immediate_operand (operands[2], QImode))
10216     {
10217       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10218       DONE;
10219     }
10220   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10221   DONE;
10224 (define_insn "ashlti3_1"
10225   [(set (match_operand:TI 0 "register_operand" "=r")
10226         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10227                    (match_operand:QI 2 "register_operand" "c")))
10228    (clobber (match_scratch:DI 3 "=&r"))
10229    (clobber (reg:CC FLAGS_REG))]
10230   "TARGET_64BIT"
10231   "#"
10232   [(set_attr "type" "multi")])
10234 (define_insn "*ashlti3_2"
10235   [(set (match_operand:TI 0 "register_operand" "=r")
10236         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10237                    (match_operand:QI 2 "immediate_operand" "O")))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "TARGET_64BIT"
10240   "#"
10241   [(set_attr "type" "multi")])
10243 (define_split
10244   [(set (match_operand:TI 0 "register_operand" "")
10245         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10246                    (match_operand:QI 2 "register_operand" "")))
10247    (clobber (match_scratch:DI 3 ""))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && reload_completed"
10250   [(const_int 0)]
10251   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10253 (define_split
10254   [(set (match_operand:TI 0 "register_operand" "")
10255         (ashift:TI (match_operand:TI 1 "register_operand" "")
10256                    (match_operand:QI 2 "immediate_operand" "")))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "TARGET_64BIT && reload_completed"
10259   [(const_int 0)]
10260   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10262 (define_insn "x86_64_shld"
10263   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10264         (ior:DI (ashift:DI (match_dup 0)
10265                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10266                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10267                   (minus:QI (const_int 64) (match_dup 2)))))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_64BIT"
10270   "@
10271    shld{q}\t{%2, %1, %0|%0, %1, %2}
10272    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10273   [(set_attr "type" "ishift")
10274    (set_attr "prefix_0f" "1")
10275    (set_attr "mode" "DI")
10276    (set_attr "athlon_decode" "vector")])
10278 (define_expand "x86_64_shift_adj"
10279   [(set (reg:CCZ FLAGS_REG)
10280         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10281                              (const_int 64))
10282                      (const_int 0)))
10283    (set (match_operand:DI 0 "register_operand" "")
10284         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10285                          (match_operand:DI 1 "register_operand" "")
10286                          (match_dup 0)))
10287    (set (match_dup 1)
10288         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10289                          (match_operand:DI 3 "register_operand" "r")
10290                          (match_dup 1)))]
10291   "TARGET_64BIT"
10292   "")
10294 (define_expand "ashldi3"
10295   [(set (match_operand:DI 0 "shiftdi_operand" "")
10296         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10297                    (match_operand:QI 2 "nonmemory_operand" "")))]
10298   ""
10299   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10301 (define_insn "*ashldi3_1_rex64"
10302   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10303         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10304                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10308   switch (get_attr_type (insn))
10309     {
10310     case TYPE_ALU:
10311       gcc_assert (operands[2] == const1_rtx);
10312       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10313       return "add{q}\t{%0, %0|%0, %0}";
10315     case TYPE_LEA:
10316       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10317       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10318       operands[1] = gen_rtx_MULT (DImode, operands[1],
10319                                   GEN_INT (1 << INTVAL (operands[2])));
10320       return "lea{q}\t{%a1, %0|%0, %a1}";
10322     default:
10323       if (REG_P (operands[2]))
10324         return "sal{q}\t{%b2, %0|%0, %b2}";
10325       else if (operands[2] == const1_rtx
10326                && (TARGET_SHIFT1 || optimize_size))
10327         return "sal{q}\t%0";
10328       else
10329         return "sal{q}\t{%2, %0|%0, %2}";
10330     }
10332   [(set (attr "type")
10333      (cond [(eq_attr "alternative" "1")
10334               (const_string "lea")
10335             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10336                           (const_int 0))
10337                       (match_operand 0 "register_operand" ""))
10338                  (match_operand 2 "const1_operand" ""))
10339               (const_string "alu")
10340            ]
10341            (const_string "ishift")))
10342    (set_attr "mode" "DI")])
10344 ;; Convert lea to the lea pattern to avoid flags dependency.
10345 (define_split
10346   [(set (match_operand:DI 0 "register_operand" "")
10347         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10348                    (match_operand:QI 2 "immediate_operand" "")))
10349    (clobber (reg:CC FLAGS_REG))]
10350   "TARGET_64BIT && reload_completed
10351    && true_regnum (operands[0]) != true_regnum (operands[1])"
10352   [(set (match_dup 0)
10353         (mult:DI (match_dup 1)
10354                  (match_dup 2)))]
10355   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10357 ;; This pattern can't accept a variable shift count, since shifts by
10358 ;; zero don't affect the flags.  We assume that shifts by constant
10359 ;; zero are optimized away.
10360 (define_insn "*ashldi3_cmp_rex64"
10361   [(set (reg FLAGS_REG)
10362         (compare
10363           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10364                      (match_operand:QI 2 "immediate_operand" "e"))
10365           (const_int 0)))
10366    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10367         (ashift:DI (match_dup 1) (match_dup 2)))]
10368   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10369    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10371   switch (get_attr_type (insn))
10372     {
10373     case TYPE_ALU:
10374       gcc_assert (operands[2] == const1_rtx);
10375       return "add{q}\t{%0, %0|%0, %0}";
10377     default:
10378       if (REG_P (operands[2]))
10379         return "sal{q}\t{%b2, %0|%0, %b2}";
10380       else if (operands[2] == const1_rtx
10381                && (TARGET_SHIFT1 || optimize_size))
10382         return "sal{q}\t%0";
10383       else
10384         return "sal{q}\t{%2, %0|%0, %2}";
10385     }
10387   [(set (attr "type")
10388      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10389                           (const_int 0))
10390                       (match_operand 0 "register_operand" ""))
10391                  (match_operand 2 "const1_operand" ""))
10392               (const_string "alu")
10393            ]
10394            (const_string "ishift")))
10395    (set_attr "mode" "DI")])
10397 (define_insn "*ashldi3_1"
10398   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10399         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10400                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10401    (clobber (reg:CC FLAGS_REG))]
10402   "!TARGET_64BIT"
10403   "#"
10404   [(set_attr "type" "multi")])
10406 ;; By default we don't ask for a scratch register, because when DImode
10407 ;; values are manipulated, registers are already at a premium.  But if
10408 ;; we have one handy, we won't turn it away.
10409 (define_peephole2
10410   [(match_scratch:SI 3 "r")
10411    (parallel [(set (match_operand:DI 0 "register_operand" "")
10412                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10413                               (match_operand:QI 2 "nonmemory_operand" "")))
10414               (clobber (reg:CC FLAGS_REG))])
10415    (match_dup 3)]
10416   "!TARGET_64BIT && TARGET_CMOVE"
10417   [(const_int 0)]
10418   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10420 (define_split
10421   [(set (match_operand:DI 0 "register_operand" "")
10422         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10423                    (match_operand:QI 2 "nonmemory_operand" "")))
10424    (clobber (reg:CC FLAGS_REG))]
10425   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10426                      ? flow2_completed : reload_completed)"
10427   [(const_int 0)]
10428   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10430 (define_insn "x86_shld_1"
10431   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10432         (ior:SI (ashift:SI (match_dup 0)
10433                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10434                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10435                   (minus:QI (const_int 32) (match_dup 2)))))
10436    (clobber (reg:CC FLAGS_REG))]
10437   ""
10438   "@
10439    shld{l}\t{%2, %1, %0|%0, %1, %2}
10440    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10441   [(set_attr "type" "ishift")
10442    (set_attr "prefix_0f" "1")
10443    (set_attr "mode" "SI")
10444    (set_attr "pent_pair" "np")
10445    (set_attr "athlon_decode" "vector")])
10447 (define_expand "x86_shift_adj_1"
10448   [(set (reg:CCZ FLAGS_REG)
10449         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10450                              (const_int 32))
10451                      (const_int 0)))
10452    (set (match_operand:SI 0 "register_operand" "")
10453         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10454                          (match_operand:SI 1 "register_operand" "")
10455                          (match_dup 0)))
10456    (set (match_dup 1)
10457         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10458                          (match_operand:SI 3 "register_operand" "r")
10459                          (match_dup 1)))]
10460   "TARGET_CMOVE"
10461   "")
10463 (define_expand "x86_shift_adj_2"
10464   [(use (match_operand:SI 0 "register_operand" ""))
10465    (use (match_operand:SI 1 "register_operand" ""))
10466    (use (match_operand:QI 2 "register_operand" ""))]
10467   ""
10469   rtx label = gen_label_rtx ();
10470   rtx tmp;
10472   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10474   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10475   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10476   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10477                               gen_rtx_LABEL_REF (VOIDmode, label),
10478                               pc_rtx);
10479   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10480   JUMP_LABEL (tmp) = label;
10482   emit_move_insn (operands[0], operands[1]);
10483   ix86_expand_clear (operands[1]);
10485   emit_label (label);
10486   LABEL_NUSES (label) = 1;
10488   DONE;
10491 (define_expand "ashlsi3"
10492   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10493         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10494                    (match_operand:QI 2 "nonmemory_operand" "")))
10495    (clobber (reg:CC FLAGS_REG))]
10496   ""
10497   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10499 (define_insn "*ashlsi3_1"
10500   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10501         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10502                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10503    (clobber (reg:CC FLAGS_REG))]
10504   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10506   switch (get_attr_type (insn))
10507     {
10508     case TYPE_ALU:
10509       gcc_assert (operands[2] == const1_rtx);
10510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10511       return "add{l}\t{%0, %0|%0, %0}";
10513     case TYPE_LEA:
10514       return "#";
10516     default:
10517       if (REG_P (operands[2]))
10518         return "sal{l}\t{%b2, %0|%0, %b2}";
10519       else if (operands[2] == const1_rtx
10520                && (TARGET_SHIFT1 || optimize_size))
10521         return "sal{l}\t%0";
10522       else
10523         return "sal{l}\t{%2, %0|%0, %2}";
10524     }
10526   [(set (attr "type")
10527      (cond [(eq_attr "alternative" "1")
10528               (const_string "lea")
10529             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10530                           (const_int 0))
10531                       (match_operand 0 "register_operand" ""))
10532                  (match_operand 2 "const1_operand" ""))
10533               (const_string "alu")
10534            ]
10535            (const_string "ishift")))
10536    (set_attr "mode" "SI")])
10538 ;; Convert lea to the lea pattern to avoid flags dependency.
10539 (define_split
10540   [(set (match_operand 0 "register_operand" "")
10541         (ashift (match_operand 1 "index_register_operand" "")
10542                 (match_operand:QI 2 "const_int_operand" "")))
10543    (clobber (reg:CC FLAGS_REG))]
10544   "reload_completed
10545    && true_regnum (operands[0]) != true_regnum (operands[1])
10546    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10547   [(const_int 0)]
10549   rtx pat;
10550   enum machine_mode mode = GET_MODE (operands[0]);
10552   if (GET_MODE_SIZE (mode) < 4)
10553     operands[0] = gen_lowpart (SImode, operands[0]);
10554   if (mode != Pmode)
10555     operands[1] = gen_lowpart (Pmode, operands[1]);
10556   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10558   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10559   if (Pmode != SImode)
10560     pat = gen_rtx_SUBREG (SImode, pat, 0);
10561   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10562   DONE;
10565 ;; Rare case of shifting RSP is handled by generating move and shift
10566 (define_split
10567   [(set (match_operand 0 "register_operand" "")
10568         (ashift (match_operand 1 "register_operand" "")
10569                 (match_operand:QI 2 "const_int_operand" "")))
10570    (clobber (reg:CC FLAGS_REG))]
10571   "reload_completed
10572    && true_regnum (operands[0]) != true_regnum (operands[1])"
10573   [(const_int 0)]
10575   rtx pat, clob;
10576   emit_move_insn (operands[1], operands[0]);
10577   pat = gen_rtx_SET (VOIDmode, operands[0],
10578                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10579                                      operands[0], operands[2]));
10580   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10581   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10582   DONE;
10585 (define_insn "*ashlsi3_1_zext"
10586   [(set (match_operand:DI 0 "register_operand" "=r,r")
10587         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10588                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10589    (clobber (reg:CC FLAGS_REG))]
10590   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10592   switch (get_attr_type (insn))
10593     {
10594     case TYPE_ALU:
10595       gcc_assert (operands[2] == const1_rtx);
10596       return "add{l}\t{%k0, %k0|%k0, %k0}";
10598     case TYPE_LEA:
10599       return "#";
10601     default:
10602       if (REG_P (operands[2]))
10603         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10604       else if (operands[2] == const1_rtx
10605                && (TARGET_SHIFT1 || optimize_size))
10606         return "sal{l}\t%k0";
10607       else
10608         return "sal{l}\t{%2, %k0|%k0, %2}";
10609     }
10611   [(set (attr "type")
10612      (cond [(eq_attr "alternative" "1")
10613               (const_string "lea")
10614             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615                      (const_int 0))
10616                  (match_operand 2 "const1_operand" ""))
10617               (const_string "alu")
10618            ]
10619            (const_string "ishift")))
10620    (set_attr "mode" "SI")])
10622 ;; Convert lea to the lea pattern to avoid flags dependency.
10623 (define_split
10624   [(set (match_operand:DI 0 "register_operand" "")
10625         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10626                                 (match_operand:QI 2 "const_int_operand" ""))))
10627    (clobber (reg:CC FLAGS_REG))]
10628   "TARGET_64BIT && reload_completed
10629    && true_regnum (operands[0]) != true_regnum (operands[1])"
10630   [(set (match_dup 0) (zero_extend:DI
10631                         (subreg:SI (mult:SI (match_dup 1)
10632                                             (match_dup 2)) 0)))]
10634   operands[1] = gen_lowpart (Pmode, operands[1]);
10635   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10638 ;; This pattern can't accept a variable shift count, since shifts by
10639 ;; zero don't affect the flags.  We assume that shifts by constant
10640 ;; zero are optimized away.
10641 (define_insn "*ashlsi3_cmp"
10642   [(set (reg FLAGS_REG)
10643         (compare
10644           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10645                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10646           (const_int 0)))
10647    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10648         (ashift:SI (match_dup 1) (match_dup 2)))]
10649   "ix86_match_ccmode (insn, CCGOCmode)
10650    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10652   switch (get_attr_type (insn))
10653     {
10654     case TYPE_ALU:
10655       gcc_assert (operands[2] == const1_rtx);
10656       return "add{l}\t{%0, %0|%0, %0}";
10658     default:
10659       if (REG_P (operands[2]))
10660         return "sal{l}\t{%b2, %0|%0, %b2}";
10661       else if (operands[2] == const1_rtx
10662                && (TARGET_SHIFT1 || optimize_size))
10663         return "sal{l}\t%0";
10664       else
10665         return "sal{l}\t{%2, %0|%0, %2}";
10666     }
10668   [(set (attr "type")
10669      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10670                           (const_int 0))
10671                       (match_operand 0 "register_operand" ""))
10672                  (match_operand 2 "const1_operand" ""))
10673               (const_string "alu")
10674            ]
10675            (const_string "ishift")))
10676    (set_attr "mode" "SI")])
10678 (define_insn "*ashlsi3_cmp_zext"
10679   [(set (reg FLAGS_REG)
10680         (compare
10681           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10682                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10683           (const_int 0)))
10684    (set (match_operand:DI 0 "register_operand" "=r")
10685         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10686   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10687    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10689   switch (get_attr_type (insn))
10690     {
10691     case TYPE_ALU:
10692       gcc_assert (operands[2] == const1_rtx);
10693       return "add{l}\t{%k0, %k0|%k0, %k0}";
10695     default:
10696       if (REG_P (operands[2]))
10697         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10698       else if (operands[2] == const1_rtx
10699                && (TARGET_SHIFT1 || optimize_size))
10700         return "sal{l}\t%k0";
10701       else
10702         return "sal{l}\t{%2, %k0|%k0, %2}";
10703     }
10705   [(set (attr "type")
10706      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707                      (const_int 0))
10708                  (match_operand 2 "const1_operand" ""))
10709               (const_string "alu")
10710            ]
10711            (const_string "ishift")))
10712    (set_attr "mode" "SI")])
10714 (define_expand "ashlhi3"
10715   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10716         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10717                    (match_operand:QI 2 "nonmemory_operand" "")))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "TARGET_HIMODE_MATH"
10720   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10722 (define_insn "*ashlhi3_1_lea"
10723   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10724         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10725                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10726    (clobber (reg:CC FLAGS_REG))]
10727   "!TARGET_PARTIAL_REG_STALL
10728    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10730   switch (get_attr_type (insn))
10731     {
10732     case TYPE_LEA:
10733       return "#";
10734     case TYPE_ALU:
10735       gcc_assert (operands[2] == const1_rtx);
10736       return "add{w}\t{%0, %0|%0, %0}";
10738     default:
10739       if (REG_P (operands[2]))
10740         return "sal{w}\t{%b2, %0|%0, %b2}";
10741       else if (operands[2] == const1_rtx
10742                && (TARGET_SHIFT1 || optimize_size))
10743         return "sal{w}\t%0";
10744       else
10745         return "sal{w}\t{%2, %0|%0, %2}";
10746     }
10748   [(set (attr "type")
10749      (cond [(eq_attr "alternative" "1")
10750               (const_string "lea")
10751             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10752                           (const_int 0))
10753                       (match_operand 0 "register_operand" ""))
10754                  (match_operand 2 "const1_operand" ""))
10755               (const_string "alu")
10756            ]
10757            (const_string "ishift")))
10758    (set_attr "mode" "HI,SI")])
10760 (define_insn "*ashlhi3_1"
10761   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10762         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10763                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10764    (clobber (reg:CC FLAGS_REG))]
10765   "TARGET_PARTIAL_REG_STALL
10766    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10768   switch (get_attr_type (insn))
10769     {
10770     case TYPE_ALU:
10771       gcc_assert (operands[2] == const1_rtx);
10772       return "add{w}\t{%0, %0|%0, %0}";
10774     default:
10775       if (REG_P (operands[2]))
10776         return "sal{w}\t{%b2, %0|%0, %b2}";
10777       else if (operands[2] == const1_rtx
10778                && (TARGET_SHIFT1 || optimize_size))
10779         return "sal{w}\t%0";
10780       else
10781         return "sal{w}\t{%2, %0|%0, %2}";
10782     }
10784   [(set (attr "type")
10785      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10786                           (const_int 0))
10787                       (match_operand 0 "register_operand" ""))
10788                  (match_operand 2 "const1_operand" ""))
10789               (const_string "alu")
10790            ]
10791            (const_string "ishift")))
10792    (set_attr "mode" "HI")])
10794 ;; This pattern can't accept a variable shift count, since shifts by
10795 ;; zero don't affect the flags.  We assume that shifts by constant
10796 ;; zero are optimized away.
10797 (define_insn "*ashlhi3_cmp"
10798   [(set (reg FLAGS_REG)
10799         (compare
10800           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10801                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10802           (const_int 0)))
10803    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10804         (ashift:HI (match_dup 1) (match_dup 2)))]
10805   "ix86_match_ccmode (insn, CCGOCmode)
10806    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10808   switch (get_attr_type (insn))
10809     {
10810     case TYPE_ALU:
10811       gcc_assert (operands[2] == const1_rtx);
10812       return "add{w}\t{%0, %0|%0, %0}";
10814     default:
10815       if (REG_P (operands[2]))
10816         return "sal{w}\t{%b2, %0|%0, %b2}";
10817       else if (operands[2] == const1_rtx
10818                && (TARGET_SHIFT1 || optimize_size))
10819         return "sal{w}\t%0";
10820       else
10821         return "sal{w}\t{%2, %0|%0, %2}";
10822     }
10824   [(set (attr "type")
10825      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10826                           (const_int 0))
10827                       (match_operand 0 "register_operand" ""))
10828                  (match_operand 2 "const1_operand" ""))
10829               (const_string "alu")
10830            ]
10831            (const_string "ishift")))
10832    (set_attr "mode" "HI")])
10834 (define_expand "ashlqi3"
10835   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10836         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10837                    (match_operand:QI 2 "nonmemory_operand" "")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "TARGET_QIMODE_MATH"
10840   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10842 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10844 (define_insn "*ashlqi3_1_lea"
10845   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10846         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10847                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10848    (clobber (reg:CC FLAGS_REG))]
10849   "!TARGET_PARTIAL_REG_STALL
10850    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10852   switch (get_attr_type (insn))
10853     {
10854     case TYPE_LEA:
10855       return "#";
10856     case TYPE_ALU:
10857       gcc_assert (operands[2] == const1_rtx);
10858       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10859         return "add{l}\t{%k0, %k0|%k0, %k0}";
10860       else
10861         return "add{b}\t{%0, %0|%0, %0}";
10863     default:
10864       if (REG_P (operands[2]))
10865         {
10866           if (get_attr_mode (insn) == MODE_SI)
10867             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10868           else
10869             return "sal{b}\t{%b2, %0|%0, %b2}";
10870         }
10871       else if (operands[2] == const1_rtx
10872                && (TARGET_SHIFT1 || optimize_size))
10873         {
10874           if (get_attr_mode (insn) == MODE_SI)
10875             return "sal{l}\t%0";
10876           else
10877             return "sal{b}\t%0";
10878         }
10879       else
10880         {
10881           if (get_attr_mode (insn) == MODE_SI)
10882             return "sal{l}\t{%2, %k0|%k0, %2}";
10883           else
10884             return "sal{b}\t{%2, %0|%0, %2}";
10885         }
10886     }
10888   [(set (attr "type")
10889      (cond [(eq_attr "alternative" "2")
10890               (const_string "lea")
10891             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10892                           (const_int 0))
10893                       (match_operand 0 "register_operand" ""))
10894                  (match_operand 2 "const1_operand" ""))
10895               (const_string "alu")
10896            ]
10897            (const_string "ishift")))
10898    (set_attr "mode" "QI,SI,SI")])
10900 (define_insn "*ashlqi3_1"
10901   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10902         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10903                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10904    (clobber (reg:CC FLAGS_REG))]
10905   "TARGET_PARTIAL_REG_STALL
10906    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10908   switch (get_attr_type (insn))
10909     {
10910     case TYPE_ALU:
10911       gcc_assert (operands[2] == const1_rtx);
10912       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10913         return "add{l}\t{%k0, %k0|%k0, %k0}";
10914       else
10915         return "add{b}\t{%0, %0|%0, %0}";
10917     default:
10918       if (REG_P (operands[2]))
10919         {
10920           if (get_attr_mode (insn) == MODE_SI)
10921             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10922           else
10923             return "sal{b}\t{%b2, %0|%0, %b2}";
10924         }
10925       else if (operands[2] == const1_rtx
10926                && (TARGET_SHIFT1 || optimize_size))
10927         {
10928           if (get_attr_mode (insn) == MODE_SI)
10929             return "sal{l}\t%0";
10930           else
10931             return "sal{b}\t%0";
10932         }
10933       else
10934         {
10935           if (get_attr_mode (insn) == MODE_SI)
10936             return "sal{l}\t{%2, %k0|%k0, %2}";
10937           else
10938             return "sal{b}\t{%2, %0|%0, %2}";
10939         }
10940     }
10942   [(set (attr "type")
10943      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944                           (const_int 0))
10945                       (match_operand 0 "register_operand" ""))
10946                  (match_operand 2 "const1_operand" ""))
10947               (const_string "alu")
10948            ]
10949            (const_string "ishift")))
10950    (set_attr "mode" "QI,SI")])
10952 ;; This pattern can't accept a variable shift count, since shifts by
10953 ;; zero don't affect the flags.  We assume that shifts by constant
10954 ;; zero are optimized away.
10955 (define_insn "*ashlqi3_cmp"
10956   [(set (reg FLAGS_REG)
10957         (compare
10958           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10959                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10960           (const_int 0)))
10961    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10962         (ashift:QI (match_dup 1) (match_dup 2)))]
10963   "ix86_match_ccmode (insn, CCGOCmode)
10964    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10966   switch (get_attr_type (insn))
10967     {
10968     case TYPE_ALU:
10969       gcc_assert (operands[2] == const1_rtx);
10970       return "add{b}\t{%0, %0|%0, %0}";
10972     default:
10973       if (REG_P (operands[2]))
10974         return "sal{b}\t{%b2, %0|%0, %b2}";
10975       else if (operands[2] == const1_rtx
10976                && (TARGET_SHIFT1 || optimize_size))
10977         return "sal{b}\t%0";
10978       else
10979         return "sal{b}\t{%2, %0|%0, %2}";
10980     }
10982   [(set (attr "type")
10983      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10984                           (const_int 0))
10985                       (match_operand 0 "register_operand" ""))
10986                  (match_operand 2 "const1_operand" ""))
10987               (const_string "alu")
10988            ]
10989            (const_string "ishift")))
10990    (set_attr "mode" "QI")])
10992 ;; See comment above `ashldi3' about how this works.
10994 (define_expand "ashrti3"
10995   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10996                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10997                                 (match_operand:QI 2 "nonmemory_operand" "")))
10998               (clobber (reg:CC FLAGS_REG))])]
10999   "TARGET_64BIT"
11001   if (! immediate_operand (operands[2], QImode))
11002     {
11003       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11004       DONE;
11005     }
11006   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11007   DONE;
11010 (define_insn "ashrti3_1"
11011   [(set (match_operand:TI 0 "register_operand" "=r")
11012         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11013                      (match_operand:QI 2 "register_operand" "c")))
11014    (clobber (match_scratch:DI 3 "=&r"))
11015    (clobber (reg:CC FLAGS_REG))]
11016   "TARGET_64BIT"
11017   "#"
11018   [(set_attr "type" "multi")])
11020 (define_insn "*ashrti3_2"
11021   [(set (match_operand:TI 0 "register_operand" "=r")
11022         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11023                      (match_operand:QI 2 "immediate_operand" "O")))
11024    (clobber (reg:CC FLAGS_REG))]
11025   "TARGET_64BIT"
11026   "#"
11027   [(set_attr "type" "multi")])
11029 (define_split
11030   [(set (match_operand:TI 0 "register_operand" "")
11031         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11032                      (match_operand:QI 2 "register_operand" "")))
11033    (clobber (match_scratch:DI 3 ""))
11034    (clobber (reg:CC FLAGS_REG))]
11035   "TARGET_64BIT && reload_completed"
11036   [(const_int 0)]
11037   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11039 (define_split
11040   [(set (match_operand:TI 0 "register_operand" "")
11041         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11042                      (match_operand:QI 2 "immediate_operand" "")))
11043    (clobber (reg:CC FLAGS_REG))]
11044   "TARGET_64BIT && reload_completed"
11045   [(const_int 0)]
11046   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11048 (define_insn "x86_64_shrd"
11049   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11050         (ior:DI (ashiftrt:DI (match_dup 0)
11051                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11052                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11053                   (minus:QI (const_int 64) (match_dup 2)))))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "TARGET_64BIT"
11056   "@
11057    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11058    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11059   [(set_attr "type" "ishift")
11060    (set_attr "prefix_0f" "1")
11061    (set_attr "mode" "DI")
11062    (set_attr "athlon_decode" "vector")])
11064 (define_expand "ashrdi3"
11065   [(set (match_operand:DI 0 "shiftdi_operand" "")
11066         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11067                      (match_operand:QI 2 "nonmemory_operand" "")))]
11068   ""
11069   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11071 (define_insn "*ashrdi3_63_rex64"
11072   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11073         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11074                      (match_operand:DI 2 "const_int_operand" "i,i")))
11075    (clobber (reg:CC FLAGS_REG))]
11076   "TARGET_64BIT && INTVAL (operands[2]) == 63
11077    && (TARGET_USE_CLTD || optimize_size)
11078    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11079   "@
11080    {cqto|cqo}
11081    sar{q}\t{%2, %0|%0, %2}"
11082   [(set_attr "type" "imovx,ishift")
11083    (set_attr "prefix_0f" "0,*")
11084    (set_attr "length_immediate" "0,*")
11085    (set_attr "modrm" "0,1")
11086    (set_attr "mode" "DI")])
11088 (define_insn "*ashrdi3_1_one_bit_rex64"
11089   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11090         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11091                      (match_operand:QI 2 "const1_operand" "")))
11092    (clobber (reg:CC FLAGS_REG))]
11093   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11094    && (TARGET_SHIFT1 || optimize_size)"
11095   "sar{q}\t%0"
11096   [(set_attr "type" "ishift")
11097    (set (attr "length") 
11098      (if_then_else (match_operand:DI 0 "register_operand" "") 
11099         (const_string "2")
11100         (const_string "*")))])
11102 (define_insn "*ashrdi3_1_rex64"
11103   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11104         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11105                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11108   "@
11109    sar{q}\t{%2, %0|%0, %2}
11110    sar{q}\t{%b2, %0|%0, %b2}"
11111   [(set_attr "type" "ishift")
11112    (set_attr "mode" "DI")])
11114 ;; This pattern can't accept a variable shift count, since shifts by
11115 ;; zero don't affect the flags.  We assume that shifts by constant
11116 ;; zero are optimized away.
11117 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11118   [(set (reg FLAGS_REG)
11119         (compare
11120           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121                        (match_operand:QI 2 "const1_operand" ""))
11122           (const_int 0)))
11123    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11124         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11125   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11126    && (TARGET_SHIFT1 || optimize_size)
11127    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11128   "sar{q}\t%0"
11129   [(set_attr "type" "ishift")
11130    (set (attr "length") 
11131      (if_then_else (match_operand:DI 0 "register_operand" "") 
11132         (const_string "2")
11133         (const_string "*")))])
11135 ;; This pattern can't accept a variable shift count, since shifts by
11136 ;; zero don't affect the flags.  We assume that shifts by constant
11137 ;; zero are optimized away.
11138 (define_insn "*ashrdi3_cmp_rex64"
11139   [(set (reg FLAGS_REG)
11140         (compare
11141           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11142                        (match_operand:QI 2 "const_int_operand" "n"))
11143           (const_int 0)))
11144    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11145         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11146   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11147    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11148   "sar{q}\t{%2, %0|%0, %2}"
11149   [(set_attr "type" "ishift")
11150    (set_attr "mode" "DI")])
11152 (define_insn "*ashrdi3_1"
11153   [(set (match_operand:DI 0 "register_operand" "=r")
11154         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11155                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11156    (clobber (reg:CC FLAGS_REG))]
11157   "!TARGET_64BIT"
11158   "#"
11159   [(set_attr "type" "multi")])
11161 ;; By default we don't ask for a scratch register, because when DImode
11162 ;; values are manipulated, registers are already at a premium.  But if
11163 ;; we have one handy, we won't turn it away.
11164 (define_peephole2
11165   [(match_scratch:SI 3 "r")
11166    (parallel [(set (match_operand:DI 0 "register_operand" "")
11167                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11168                                 (match_operand:QI 2 "nonmemory_operand" "")))
11169               (clobber (reg:CC FLAGS_REG))])
11170    (match_dup 3)]
11171   "!TARGET_64BIT && TARGET_CMOVE"
11172   [(const_int 0)]
11173   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11175 (define_split
11176   [(set (match_operand:DI 0 "register_operand" "")
11177         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11178                      (match_operand:QI 2 "nonmemory_operand" "")))
11179    (clobber (reg:CC FLAGS_REG))]
11180   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11181                      ? flow2_completed : reload_completed)"
11182   [(const_int 0)]
11183   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11185 (define_insn "x86_shrd_1"
11186   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11187         (ior:SI (ashiftrt:SI (match_dup 0)
11188                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11189                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11190                   (minus:QI (const_int 32) (match_dup 2)))))
11191    (clobber (reg:CC FLAGS_REG))]
11192   ""
11193   "@
11194    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11195    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11196   [(set_attr "type" "ishift")
11197    (set_attr "prefix_0f" "1")
11198    (set_attr "pent_pair" "np")
11199    (set_attr "mode" "SI")])
11201 (define_expand "x86_shift_adj_3"
11202   [(use (match_operand:SI 0 "register_operand" ""))
11203    (use (match_operand:SI 1 "register_operand" ""))
11204    (use (match_operand:QI 2 "register_operand" ""))]
11205   ""
11207   rtx label = gen_label_rtx ();
11208   rtx tmp;
11210   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11212   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11213   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11214   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11215                               gen_rtx_LABEL_REF (VOIDmode, label),
11216                               pc_rtx);
11217   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11218   JUMP_LABEL (tmp) = label;
11220   emit_move_insn (operands[0], operands[1]);
11221   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11223   emit_label (label);
11224   LABEL_NUSES (label) = 1;
11226   DONE;
11229 (define_insn "ashrsi3_31"
11230   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11231         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11232                      (match_operand:SI 2 "const_int_operand" "i,i")))
11233    (clobber (reg:CC FLAGS_REG))]
11234   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11235    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11236   "@
11237    {cltd|cdq}
11238    sar{l}\t{%2, %0|%0, %2}"
11239   [(set_attr "type" "imovx,ishift")
11240    (set_attr "prefix_0f" "0,*")
11241    (set_attr "length_immediate" "0,*")
11242    (set_attr "modrm" "0,1")
11243    (set_attr "mode" "SI")])
11245 (define_insn "*ashrsi3_31_zext"
11246   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11247         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11248                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11249    (clobber (reg:CC FLAGS_REG))]
11250   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11251    && INTVAL (operands[2]) == 31
11252    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11253   "@
11254    {cltd|cdq}
11255    sar{l}\t{%2, %k0|%k0, %2}"
11256   [(set_attr "type" "imovx,ishift")
11257    (set_attr "prefix_0f" "0,*")
11258    (set_attr "length_immediate" "0,*")
11259    (set_attr "modrm" "0,1")
11260    (set_attr "mode" "SI")])
11262 (define_expand "ashrsi3"
11263   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11264         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11265                      (match_operand:QI 2 "nonmemory_operand" "")))
11266    (clobber (reg:CC FLAGS_REG))]
11267   ""
11268   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11270 (define_insn "*ashrsi3_1_one_bit"
11271   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11272         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11273                      (match_operand:QI 2 "const1_operand" "")))
11274    (clobber (reg:CC FLAGS_REG))]
11275   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11276    && (TARGET_SHIFT1 || optimize_size)"
11277   "sar{l}\t%0"
11278   [(set_attr "type" "ishift")
11279    (set (attr "length") 
11280      (if_then_else (match_operand:SI 0 "register_operand" "") 
11281         (const_string "2")
11282         (const_string "*")))])
11284 (define_insn "*ashrsi3_1_one_bit_zext"
11285   [(set (match_operand:DI 0 "register_operand" "=r")
11286         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11287                                      (match_operand:QI 2 "const1_operand" ""))))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11290    && (TARGET_SHIFT1 || optimize_size)"
11291   "sar{l}\t%k0"
11292   [(set_attr "type" "ishift")
11293    (set_attr "length" "2")])
11295 (define_insn "*ashrsi3_1"
11296   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11297         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11298                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11299    (clobber (reg:CC FLAGS_REG))]
11300   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11301   "@
11302    sar{l}\t{%2, %0|%0, %2}
11303    sar{l}\t{%b2, %0|%0, %b2}"
11304   [(set_attr "type" "ishift")
11305    (set_attr "mode" "SI")])
11307 (define_insn "*ashrsi3_1_zext"
11308   [(set (match_operand:DI 0 "register_operand" "=r,r")
11309         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11310                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11313   "@
11314    sar{l}\t{%2, %k0|%k0, %2}
11315    sar{l}\t{%b2, %k0|%k0, %b2}"
11316   [(set_attr "type" "ishift")
11317    (set_attr "mode" "SI")])
11319 ;; This pattern can't accept a variable shift count, since shifts by
11320 ;; zero don't affect the flags.  We assume that shifts by constant
11321 ;; zero are optimized away.
11322 (define_insn "*ashrsi3_one_bit_cmp"
11323   [(set (reg FLAGS_REG)
11324         (compare
11325           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11326                        (match_operand:QI 2 "const1_operand" ""))
11327           (const_int 0)))
11328    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11329         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11330   "ix86_match_ccmode (insn, CCGOCmode)
11331    && (TARGET_SHIFT1 || optimize_size)
11332    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11333   "sar{l}\t%0"
11334   [(set_attr "type" "ishift")
11335    (set (attr "length") 
11336      (if_then_else (match_operand:SI 0 "register_operand" "") 
11337         (const_string "2")
11338         (const_string "*")))])
11340 (define_insn "*ashrsi3_one_bit_cmp_zext"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11344                        (match_operand:QI 2 "const1_operand" ""))
11345           (const_int 0)))
11346    (set (match_operand:DI 0 "register_operand" "=r")
11347         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11348   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11349    && (TARGET_SHIFT1 || optimize_size)
11350    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11351   "sar{l}\t%k0"
11352   [(set_attr "type" "ishift")
11353    (set_attr "length" "2")])
11355 ;; This pattern can't accept a variable shift count, since shifts by
11356 ;; zero don't affect the flags.  We assume that shifts by constant
11357 ;; zero are optimized away.
11358 (define_insn "*ashrsi3_cmp"
11359   [(set (reg FLAGS_REG)
11360         (compare
11361           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11363           (const_int 0)))
11364    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11365         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11366   "ix86_match_ccmode (insn, CCGOCmode)
11367    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11368   "sar{l}\t{%2, %0|%0, %2}"
11369   [(set_attr "type" "ishift")
11370    (set_attr "mode" "SI")])
11372 (define_insn "*ashrsi3_cmp_zext"
11373   [(set (reg FLAGS_REG)
11374         (compare
11375           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11376                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11377           (const_int 0)))
11378    (set (match_operand:DI 0 "register_operand" "=r")
11379         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11380   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11381    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11382   "sar{l}\t{%2, %k0|%k0, %2}"
11383   [(set_attr "type" "ishift")
11384    (set_attr "mode" "SI")])
11386 (define_expand "ashrhi3"
11387   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11388         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11389                      (match_operand:QI 2 "nonmemory_operand" "")))
11390    (clobber (reg:CC FLAGS_REG))]
11391   "TARGET_HIMODE_MATH"
11392   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11394 (define_insn "*ashrhi3_1_one_bit"
11395   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11396         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11397                      (match_operand:QI 2 "const1_operand" "")))
11398    (clobber (reg:CC FLAGS_REG))]
11399   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11400    && (TARGET_SHIFT1 || optimize_size)"
11401   "sar{w}\t%0"
11402   [(set_attr "type" "ishift")
11403    (set (attr "length") 
11404      (if_then_else (match_operand 0 "register_operand" "") 
11405         (const_string "2")
11406         (const_string "*")))])
11408 (define_insn "*ashrhi3_1"
11409   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11410         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11411                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11414   "@
11415    sar{w}\t{%2, %0|%0, %2}
11416    sar{w}\t{%b2, %0|%0, %b2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "HI")])
11420 ;; This pattern can't accept a variable shift count, since shifts by
11421 ;; zero don't affect the flags.  We assume that shifts by constant
11422 ;; zero are optimized away.
11423 (define_insn "*ashrhi3_one_bit_cmp"
11424   [(set (reg FLAGS_REG)
11425         (compare
11426           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427                        (match_operand:QI 2 "const1_operand" ""))
11428           (const_int 0)))
11429    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11430         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11431   "ix86_match_ccmode (insn, CCGOCmode)
11432    && (TARGET_SHIFT1 || optimize_size)
11433    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11434   "sar{w}\t%0"
11435   [(set_attr "type" "ishift")
11436    (set (attr "length") 
11437      (if_then_else (match_operand 0 "register_operand" "") 
11438         (const_string "2")
11439         (const_string "*")))])
11441 ;; This pattern can't accept a variable shift count, since shifts by
11442 ;; zero don't affect the flags.  We assume that shifts by constant
11443 ;; zero are optimized away.
11444 (define_insn "*ashrhi3_cmp"
11445   [(set (reg FLAGS_REG)
11446         (compare
11447           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11448                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11449           (const_int 0)))
11450    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11451         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11452   "ix86_match_ccmode (insn, CCGOCmode)
11453    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11454   "sar{w}\t{%2, %0|%0, %2}"
11455   [(set_attr "type" "ishift")
11456    (set_attr "mode" "HI")])
11458 (define_expand "ashrqi3"
11459   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11460         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11461                      (match_operand:QI 2 "nonmemory_operand" "")))
11462    (clobber (reg:CC FLAGS_REG))]
11463   "TARGET_QIMODE_MATH"
11464   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11466 (define_insn "*ashrqi3_1_one_bit"
11467   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11468         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11469                      (match_operand:QI 2 "const1_operand" "")))
11470    (clobber (reg:CC FLAGS_REG))]
11471   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11472    && (TARGET_SHIFT1 || optimize_size)"
11473   "sar{b}\t%0"
11474   [(set_attr "type" "ishift")
11475    (set (attr "length") 
11476      (if_then_else (match_operand 0 "register_operand" "") 
11477         (const_string "2")
11478         (const_string "*")))])
11480 (define_insn "*ashrqi3_1_one_bit_slp"
11481   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11482         (ashiftrt:QI (match_dup 0)
11483                      (match_operand:QI 1 "const1_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11486    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11487    && (TARGET_SHIFT1 || optimize_size)"
11488   "sar{b}\t%0"
11489   [(set_attr "type" "ishift1")
11490    (set (attr "length") 
11491      (if_then_else (match_operand 0 "register_operand" "") 
11492         (const_string "2")
11493         (const_string "*")))])
11495 (define_insn "*ashrqi3_1"
11496   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11497         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11498                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11499    (clobber (reg:CC FLAGS_REG))]
11500   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11501   "@
11502    sar{b}\t{%2, %0|%0, %2}
11503    sar{b}\t{%b2, %0|%0, %b2}"
11504   [(set_attr "type" "ishift")
11505    (set_attr "mode" "QI")])
11507 (define_insn "*ashrqi3_1_slp"
11508   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11509         (ashiftrt:QI (match_dup 0)
11510                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11513    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11514   "@
11515    sar{b}\t{%1, %0|%0, %1}
11516    sar{b}\t{%b1, %0|%0, %b1}"
11517   [(set_attr "type" "ishift1")
11518    (set_attr "mode" "QI")])
11520 ;; This pattern can't accept a variable shift count, since shifts by
11521 ;; zero don't affect the flags.  We assume that shifts by constant
11522 ;; zero are optimized away.
11523 (define_insn "*ashrqi3_one_bit_cmp"
11524   [(set (reg FLAGS_REG)
11525         (compare
11526           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11527                        (match_operand:QI 2 "const1_operand" "I"))
11528           (const_int 0)))
11529    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11530         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11531   "ix86_match_ccmode (insn, CCGOCmode)
11532    && (TARGET_SHIFT1 || optimize_size)
11533    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11534   "sar{b}\t%0"
11535   [(set_attr "type" "ishift")
11536    (set (attr "length") 
11537      (if_then_else (match_operand 0 "register_operand" "") 
11538         (const_string "2")
11539         (const_string "*")))])
11541 ;; This pattern can't accept a variable shift count, since shifts by
11542 ;; zero don't affect the flags.  We assume that shifts by constant
11543 ;; zero are optimized away.
11544 (define_insn "*ashrqi3_cmp"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11548                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11549           (const_int 0)))
11550    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11551         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11552   "ix86_match_ccmode (insn, CCGOCmode)
11553    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11554   "sar{b}\t{%2, %0|%0, %2}"
11555   [(set_attr "type" "ishift")
11556    (set_attr "mode" "QI")])
11558 ;; Logical shift instructions
11560 ;; See comment above `ashldi3' about how this works.
11562 (define_expand "lshrti3"
11563   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11564                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11565                                 (match_operand:QI 2 "nonmemory_operand" "")))
11566               (clobber (reg:CC FLAGS_REG))])]
11567   "TARGET_64BIT"
11569   if (! immediate_operand (operands[2], QImode))
11570     {
11571       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11572       DONE;
11573     }
11574   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11575   DONE;
11578 (define_insn "lshrti3_1"
11579   [(set (match_operand:TI 0 "register_operand" "=r")
11580         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11581                      (match_operand:QI 2 "register_operand" "c")))
11582    (clobber (match_scratch:DI 3 "=&r"))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_64BIT"
11585   "#"
11586   [(set_attr "type" "multi")])
11588 (define_insn "*lshrti3_2"
11589   [(set (match_operand:TI 0 "register_operand" "=r")
11590         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11591                      (match_operand:QI 2 "immediate_operand" "O")))
11592    (clobber (reg:CC FLAGS_REG))]
11593   "TARGET_64BIT"
11594   "#"
11595   [(set_attr "type" "multi")])
11597 (define_split 
11598   [(set (match_operand:TI 0 "register_operand" "")
11599         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11600                      (match_operand:QI 2 "register_operand" "")))
11601    (clobber (match_scratch:DI 3 ""))
11602    (clobber (reg:CC FLAGS_REG))]
11603   "TARGET_64BIT && reload_completed"
11604   [(const_int 0)]
11605   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11607 (define_split 
11608   [(set (match_operand:TI 0 "register_operand" "")
11609         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11610                      (match_operand:QI 2 "immediate_operand" "")))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "TARGET_64BIT && reload_completed"
11613   [(const_int 0)]
11614   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11616 (define_expand "lshrdi3"
11617   [(set (match_operand:DI 0 "shiftdi_operand" "")
11618         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11619                      (match_operand:QI 2 "nonmemory_operand" "")))]
11620   ""
11621   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11623 (define_insn "*lshrdi3_1_one_bit_rex64"
11624   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11625         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11626                      (match_operand:QI 2 "const1_operand" "")))
11627    (clobber (reg:CC FLAGS_REG))]
11628   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11629    && (TARGET_SHIFT1 || optimize_size)"
11630   "shr{q}\t%0"
11631   [(set_attr "type" "ishift")
11632    (set (attr "length") 
11633      (if_then_else (match_operand:DI 0 "register_operand" "") 
11634         (const_string "2")
11635         (const_string "*")))])
11637 (define_insn "*lshrdi3_1_rex64"
11638   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11639         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11640                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11643   "@
11644    shr{q}\t{%2, %0|%0, %2}
11645    shr{q}\t{%b2, %0|%0, %b2}"
11646   [(set_attr "type" "ishift")
11647    (set_attr "mode" "DI")])
11649 ;; This pattern can't accept a variable shift count, since shifts by
11650 ;; zero don't affect the flags.  We assume that shifts by constant
11651 ;; zero are optimized away.
11652 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11653   [(set (reg FLAGS_REG)
11654         (compare
11655           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656                        (match_operand:QI 2 "const1_operand" ""))
11657           (const_int 0)))
11658    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11659         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11661    && (TARGET_SHIFT1 || optimize_size)
11662    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11663   "shr{q}\t%0"
11664   [(set_attr "type" "ishift")
11665    (set (attr "length") 
11666      (if_then_else (match_operand:DI 0 "register_operand" "") 
11667         (const_string "2")
11668         (const_string "*")))])
11670 ;; This pattern can't accept a variable shift count, since shifts by
11671 ;; zero don't affect the flags.  We assume that shifts by constant
11672 ;; zero are optimized away.
11673 (define_insn "*lshrdi3_cmp_rex64"
11674   [(set (reg FLAGS_REG)
11675         (compare
11676           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11677                        (match_operand:QI 2 "const_int_operand" "e"))
11678           (const_int 0)))
11679    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11680         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11681   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11682    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11683   "shr{q}\t{%2, %0|%0, %2}"
11684   [(set_attr "type" "ishift")
11685    (set_attr "mode" "DI")])
11687 (define_insn "*lshrdi3_1"
11688   [(set (match_operand:DI 0 "register_operand" "=r")
11689         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11690                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11691    (clobber (reg:CC FLAGS_REG))]
11692   "!TARGET_64BIT"
11693   "#"
11694   [(set_attr "type" "multi")])
11696 ;; By default we don't ask for a scratch register, because when DImode
11697 ;; values are manipulated, registers are already at a premium.  But if
11698 ;; we have one handy, we won't turn it away.
11699 (define_peephole2
11700   [(match_scratch:SI 3 "r")
11701    (parallel [(set (match_operand:DI 0 "register_operand" "")
11702                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11703                                 (match_operand:QI 2 "nonmemory_operand" "")))
11704               (clobber (reg:CC FLAGS_REG))])
11705    (match_dup 3)]
11706   "!TARGET_64BIT && TARGET_CMOVE"
11707   [(const_int 0)]
11708   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11710 (define_split 
11711   [(set (match_operand:DI 0 "register_operand" "")
11712         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11713                      (match_operand:QI 2 "nonmemory_operand" "")))
11714    (clobber (reg:CC FLAGS_REG))]
11715   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11716                      ? flow2_completed : reload_completed)"
11717   [(const_int 0)]
11718   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11720 (define_expand "lshrsi3"
11721   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11722         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11723                      (match_operand:QI 2 "nonmemory_operand" "")))
11724    (clobber (reg:CC FLAGS_REG))]
11725   ""
11726   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11728 (define_insn "*lshrsi3_1_one_bit"
11729   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11730         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11731                      (match_operand:QI 2 "const1_operand" "")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11734    && (TARGET_SHIFT1 || optimize_size)"
11735   "shr{l}\t%0"
11736   [(set_attr "type" "ishift")
11737    (set (attr "length") 
11738      (if_then_else (match_operand:SI 0 "register_operand" "") 
11739         (const_string "2")
11740         (const_string "*")))])
11742 (define_insn "*lshrsi3_1_one_bit_zext"
11743   [(set (match_operand:DI 0 "register_operand" "=r")
11744         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11745                      (match_operand:QI 2 "const1_operand" "")))
11746    (clobber (reg:CC FLAGS_REG))]
11747   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11748    && (TARGET_SHIFT1 || optimize_size)"
11749   "shr{l}\t%k0"
11750   [(set_attr "type" "ishift")
11751    (set_attr "length" "2")])
11753 (define_insn "*lshrsi3_1"
11754   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11755         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11756                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11757    (clobber (reg:CC FLAGS_REG))]
11758   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11759   "@
11760    shr{l}\t{%2, %0|%0, %2}
11761    shr{l}\t{%b2, %0|%0, %b2}"
11762   [(set_attr "type" "ishift")
11763    (set_attr "mode" "SI")])
11765 (define_insn "*lshrsi3_1_zext"
11766   [(set (match_operand:DI 0 "register_operand" "=r,r")
11767         (zero_extend:DI
11768           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11769                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11772   "@
11773    shr{l}\t{%2, %k0|%k0, %2}
11774    shr{l}\t{%b2, %k0|%k0, %b2}"
11775   [(set_attr "type" "ishift")
11776    (set_attr "mode" "SI")])
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags.  We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*lshrsi3_one_bit_cmp"
11782   [(set (reg FLAGS_REG)
11783         (compare
11784           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11785                        (match_operand:QI 2 "const1_operand" ""))
11786           (const_int 0)))
11787    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11788         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11789   "ix86_match_ccmode (insn, CCGOCmode)
11790    && (TARGET_SHIFT1 || optimize_size)
11791    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11792   "shr{l}\t%0"
11793   [(set_attr "type" "ishift")
11794    (set (attr "length") 
11795      (if_then_else (match_operand:SI 0 "register_operand" "") 
11796         (const_string "2")
11797         (const_string "*")))])
11799 (define_insn "*lshrsi3_cmp_one_bit_zext"
11800   [(set (reg FLAGS_REG)
11801         (compare
11802           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11803                        (match_operand:QI 2 "const1_operand" ""))
11804           (const_int 0)))
11805    (set (match_operand:DI 0 "register_operand" "=r")
11806         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11807   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11808    && (TARGET_SHIFT1 || optimize_size)
11809    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11810   "shr{l}\t%k0"
11811   [(set_attr "type" "ishift")
11812    (set_attr "length" "2")])
11814 ;; This pattern can't accept a variable shift count, since shifts by
11815 ;; zero don't affect the flags.  We assume that shifts by constant
11816 ;; zero are optimized away.
11817 (define_insn "*lshrsi3_cmp"
11818   [(set (reg FLAGS_REG)
11819         (compare
11820           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11821                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11822           (const_int 0)))
11823    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11824         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11825   "ix86_match_ccmode (insn, CCGOCmode)
11826    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11827   "shr{l}\t{%2, %0|%0, %2}"
11828   [(set_attr "type" "ishift")
11829    (set_attr "mode" "SI")])
11831 (define_insn "*lshrsi3_cmp_zext"
11832   [(set (reg FLAGS_REG)
11833         (compare
11834           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11835                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836           (const_int 0)))
11837    (set (match_operand:DI 0 "register_operand" "=r")
11838         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11839   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11840    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11841   "shr{l}\t{%2, %k0|%k0, %2}"
11842   [(set_attr "type" "ishift")
11843    (set_attr "mode" "SI")])
11845 (define_expand "lshrhi3"
11846   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11847         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11848                      (match_operand:QI 2 "nonmemory_operand" "")))
11849    (clobber (reg:CC FLAGS_REG))]
11850   "TARGET_HIMODE_MATH"
11851   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11853 (define_insn "*lshrhi3_1_one_bit"
11854   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11855         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11856                      (match_operand:QI 2 "const1_operand" "")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11859    && (TARGET_SHIFT1 || optimize_size)"
11860   "shr{w}\t%0"
11861   [(set_attr "type" "ishift")
11862    (set (attr "length") 
11863      (if_then_else (match_operand 0 "register_operand" "") 
11864         (const_string "2")
11865         (const_string "*")))])
11867 (define_insn "*lshrhi3_1"
11868   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11869         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11870                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11871    (clobber (reg:CC FLAGS_REG))]
11872   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873   "@
11874    shr{w}\t{%2, %0|%0, %2}
11875    shr{w}\t{%b2, %0|%0, %b2}"
11876   [(set_attr "type" "ishift")
11877    (set_attr "mode" "HI")])
11879 ;; This pattern can't accept a variable shift count, since shifts by
11880 ;; zero don't affect the flags.  We assume that shifts by constant
11881 ;; zero are optimized away.
11882 (define_insn "*lshrhi3_one_bit_cmp"
11883   [(set (reg FLAGS_REG)
11884         (compare
11885           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886                        (match_operand:QI 2 "const1_operand" ""))
11887           (const_int 0)))
11888    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11889         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11890   "ix86_match_ccmode (insn, CCGOCmode)
11891    && (TARGET_SHIFT1 || optimize_size)
11892    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11893   "shr{w}\t%0"
11894   [(set_attr "type" "ishift")
11895    (set (attr "length") 
11896      (if_then_else (match_operand:SI 0 "register_operand" "") 
11897         (const_string "2")
11898         (const_string "*")))])
11900 ;; This pattern can't accept a variable shift count, since shifts by
11901 ;; zero don't affect the flags.  We assume that shifts by constant
11902 ;; zero are optimized away.
11903 (define_insn "*lshrhi3_cmp"
11904   [(set (reg FLAGS_REG)
11905         (compare
11906           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11907                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908           (const_int 0)))
11909    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11910         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11911   "ix86_match_ccmode (insn, CCGOCmode)
11912    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11913   "shr{w}\t{%2, %0|%0, %2}"
11914   [(set_attr "type" "ishift")
11915    (set_attr "mode" "HI")])
11917 (define_expand "lshrqi3"
11918   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11919         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11920                      (match_operand:QI 2 "nonmemory_operand" "")))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "TARGET_QIMODE_MATH"
11923   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11925 (define_insn "*lshrqi3_1_one_bit"
11926   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11927         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11928                      (match_operand:QI 2 "const1_operand" "")))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11931    && (TARGET_SHIFT1 || optimize_size)"
11932   "shr{b}\t%0"
11933   [(set_attr "type" "ishift")
11934    (set (attr "length") 
11935      (if_then_else (match_operand 0 "register_operand" "") 
11936         (const_string "2")
11937         (const_string "*")))])
11939 (define_insn "*lshrqi3_1_one_bit_slp"
11940   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11941         (lshiftrt:QI (match_dup 0)
11942                      (match_operand:QI 1 "const1_operand" "")))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11945    && (TARGET_SHIFT1 || optimize_size)"
11946   "shr{b}\t%0"
11947   [(set_attr "type" "ishift1")
11948    (set (attr "length") 
11949      (if_then_else (match_operand 0 "register_operand" "") 
11950         (const_string "2")
11951         (const_string "*")))])
11953 (define_insn "*lshrqi3_1"
11954   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11955         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11956                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11959   "@
11960    shr{b}\t{%2, %0|%0, %2}
11961    shr{b}\t{%b2, %0|%0, %b2}"
11962   [(set_attr "type" "ishift")
11963    (set_attr "mode" "QI")])
11965 (define_insn "*lshrqi3_1_slp"
11966   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11967         (lshiftrt:QI (match_dup 0)
11968                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11971    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11972   "@
11973    shr{b}\t{%1, %0|%0, %1}
11974    shr{b}\t{%b1, %0|%0, %b1}"
11975   [(set_attr "type" "ishift1")
11976    (set_attr "mode" "QI")])
11978 ;; This pattern can't accept a variable shift count, since shifts by
11979 ;; zero don't affect the flags.  We assume that shifts by constant
11980 ;; zero are optimized away.
11981 (define_insn "*lshrqi2_one_bit_cmp"
11982   [(set (reg FLAGS_REG)
11983         (compare
11984           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11985                        (match_operand:QI 2 "const1_operand" ""))
11986           (const_int 0)))
11987    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11988         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11989   "ix86_match_ccmode (insn, CCGOCmode)
11990    && (TARGET_SHIFT1 || optimize_size)
11991    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11992   "shr{b}\t%0"
11993   [(set_attr "type" "ishift")
11994    (set (attr "length") 
11995      (if_then_else (match_operand:SI 0 "register_operand" "") 
11996         (const_string "2")
11997         (const_string "*")))])
11999 ;; This pattern can't accept a variable shift count, since shifts by
12000 ;; zero don't affect the flags.  We assume that shifts by constant
12001 ;; zero are optimized away.
12002 (define_insn "*lshrqi2_cmp"
12003   [(set (reg FLAGS_REG)
12004         (compare
12005           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12006                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12007           (const_int 0)))
12008    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12009         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12010   "ix86_match_ccmode (insn, CCGOCmode)
12011    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12012   "shr{b}\t{%2, %0|%0, %2}"
12013   [(set_attr "type" "ishift")
12014    (set_attr "mode" "QI")])
12016 ;; Rotate instructions
12018 (define_expand "rotldi3"
12019   [(set (match_operand:DI 0 "shiftdi_operand" "")
12020         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12021                    (match_operand:QI 2 "nonmemory_operand" "")))
12022    (clobber (reg:CC FLAGS_REG))]
12023  ""
12025   if (TARGET_64BIT)
12026     {
12027       ix86_expand_binary_operator (ROTATE, DImode, operands);
12028       DONE;
12029     }
12030   if (!const_1_to_31_operand (operands[2], VOIDmode))
12031     FAIL;
12032   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12033   DONE;
12036 ;; Implement rotation using two double-precision shift instructions
12037 ;; and a scratch register.   
12038 (define_insn_and_split "ix86_rotldi3"
12039  [(set (match_operand:DI 0 "register_operand" "=r")
12040        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12041                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12042   (clobber (reg:CC FLAGS_REG))
12043   (clobber (match_scratch:SI 3 "=&r"))]
12044  "!TARGET_64BIT"
12045  "" 
12046  "&& reload_completed"
12047  [(set (match_dup 3) (match_dup 4))
12048   (parallel
12049    [(set (match_dup 4)
12050          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12051                  (lshiftrt:SI (match_dup 5)
12052                               (minus:QI (const_int 32) (match_dup 2)))))
12053     (clobber (reg:CC FLAGS_REG))])
12054   (parallel
12055    [(set (match_dup 5)
12056          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12057                  (lshiftrt:SI (match_dup 3)
12058                               (minus:QI (const_int 32) (match_dup 2)))))
12059     (clobber (reg:CC FLAGS_REG))])]
12060  "split_di (operands, 1, operands + 4, operands + 5);")
12062 (define_insn "*rotlsi3_1_one_bit_rex64"
12063   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12064         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12065                    (match_operand:QI 2 "const1_operand" "")))
12066    (clobber (reg:CC FLAGS_REG))]
12067   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12068    && (TARGET_SHIFT1 || optimize_size)"
12069   "rol{q}\t%0"
12070   [(set_attr "type" "rotate")
12071    (set (attr "length") 
12072      (if_then_else (match_operand:DI 0 "register_operand" "") 
12073         (const_string "2")
12074         (const_string "*")))])
12076 (define_insn "*rotldi3_1_rex64"
12077   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12078         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12079                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12080    (clobber (reg:CC FLAGS_REG))]
12081   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12082   "@
12083    rol{q}\t{%2, %0|%0, %2}
12084    rol{q}\t{%b2, %0|%0, %b2}"
12085   [(set_attr "type" "rotate")
12086    (set_attr "mode" "DI")])
12088 (define_expand "rotlsi3"
12089   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12090         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12091                    (match_operand:QI 2 "nonmemory_operand" "")))
12092    (clobber (reg:CC FLAGS_REG))]
12093   ""
12094   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12096 (define_insn "*rotlsi3_1_one_bit"
12097   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12098         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12099                    (match_operand:QI 2 "const1_operand" "")))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12102    && (TARGET_SHIFT1 || optimize_size)"
12103   "rol{l}\t%0"
12104   [(set_attr "type" "rotate")
12105    (set (attr "length") 
12106      (if_then_else (match_operand:SI 0 "register_operand" "") 
12107         (const_string "2")
12108         (const_string "*")))])
12110 (define_insn "*rotlsi3_1_one_bit_zext"
12111   [(set (match_operand:DI 0 "register_operand" "=r")
12112         (zero_extend:DI
12113           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12114                      (match_operand:QI 2 "const1_operand" ""))))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12117    && (TARGET_SHIFT1 || optimize_size)"
12118   "rol{l}\t%k0"
12119   [(set_attr "type" "rotate")
12120    (set_attr "length" "2")])
12122 (define_insn "*rotlsi3_1"
12123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12124         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12125                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12128   "@
12129    rol{l}\t{%2, %0|%0, %2}
12130    rol{l}\t{%b2, %0|%0, %b2}"
12131   [(set_attr "type" "rotate")
12132    (set_attr "mode" "SI")])
12134 (define_insn "*rotlsi3_1_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=r,r")
12136         (zero_extend:DI
12137           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12138                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12141   "@
12142    rol{l}\t{%2, %k0|%k0, %2}
12143    rol{l}\t{%b2, %k0|%k0, %b2}"
12144   [(set_attr "type" "rotate")
12145    (set_attr "mode" "SI")])
12147 (define_expand "rotlhi3"
12148   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12149         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12150                    (match_operand:QI 2 "nonmemory_operand" "")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "TARGET_HIMODE_MATH"
12153   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12155 (define_insn "*rotlhi3_1_one_bit"
12156   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12157         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12158                    (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "rol{w}\t%0"
12163   [(set_attr "type" "rotate")
12164    (set (attr "length") 
12165      (if_then_else (match_operand 0 "register_operand" "") 
12166         (const_string "2")
12167         (const_string "*")))])
12169 (define_insn "*rotlhi3_1"
12170   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12171         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12172                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12175   "@
12176    rol{w}\t{%2, %0|%0, %2}
12177    rol{w}\t{%b2, %0|%0, %b2}"
12178   [(set_attr "type" "rotate")
12179    (set_attr "mode" "HI")])
12181 (define_expand "rotlqi3"
12182   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12183         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12184                    (match_operand:QI 2 "nonmemory_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "TARGET_QIMODE_MATH"
12187   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12189 (define_insn "*rotlqi3_1_one_bit_slp"
12190   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12191         (rotate:QI (match_dup 0)
12192                    (match_operand:QI 1 "const1_operand" "")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12195    && (TARGET_SHIFT1 || optimize_size)"
12196   "rol{b}\t%0"
12197   [(set_attr "type" "rotate1")
12198    (set (attr "length") 
12199      (if_then_else (match_operand 0 "register_operand" "") 
12200         (const_string "2")
12201         (const_string "*")))])
12203 (define_insn "*rotlqi3_1_one_bit"
12204   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12205         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12206                    (match_operand:QI 2 "const1_operand" "")))
12207    (clobber (reg:CC FLAGS_REG))]
12208   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12209    && (TARGET_SHIFT1 || optimize_size)"
12210   "rol{b}\t%0"
12211   [(set_attr "type" "rotate")
12212    (set (attr "length") 
12213      (if_then_else (match_operand 0 "register_operand" "") 
12214         (const_string "2")
12215         (const_string "*")))])
12217 (define_insn "*rotlqi3_1_slp"
12218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12219         (rotate:QI (match_dup 0)
12220                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12221    (clobber (reg:CC FLAGS_REG))]
12222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12223    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12224   "@
12225    rol{b}\t{%1, %0|%0, %1}
12226    rol{b}\t{%b1, %0|%0, %b1}"
12227   [(set_attr "type" "rotate1")
12228    (set_attr "mode" "QI")])
12230 (define_insn "*rotlqi3_1"
12231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12232         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12233                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12234    (clobber (reg:CC FLAGS_REG))]
12235   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12236   "@
12237    rol{b}\t{%2, %0|%0, %2}
12238    rol{b}\t{%b2, %0|%0, %b2}"
12239   [(set_attr "type" "rotate")
12240    (set_attr "mode" "QI")])
12242 (define_expand "rotrdi3"
12243   [(set (match_operand:DI 0 "shiftdi_operand" "")
12244         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12245                    (match_operand:QI 2 "nonmemory_operand" "")))
12246    (clobber (reg:CC FLAGS_REG))]
12247  ""
12249   if (TARGET_64BIT)
12250     {
12251       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12252       DONE;
12253     }
12254   if (!const_1_to_31_operand (operands[2], VOIDmode))
12255     FAIL;
12256   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12257   DONE;
12259   
12260 ;; Implement rotation using two double-precision shift instructions
12261 ;; and a scratch register.   
12262 (define_insn_and_split "ix86_rotrdi3"
12263  [(set (match_operand:DI 0 "register_operand" "=r")
12264        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12265                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12266   (clobber (reg:CC FLAGS_REG))
12267   (clobber (match_scratch:SI 3 "=&r"))]
12268  "!TARGET_64BIT"
12269  ""
12270  "&& reload_completed"
12271  [(set (match_dup 3) (match_dup 4))
12272   (parallel
12273    [(set (match_dup 4)
12274          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12275                  (ashift:SI (match_dup 5)
12276                             (minus:QI (const_int 32) (match_dup 2)))))
12277     (clobber (reg:CC FLAGS_REG))])
12278   (parallel
12279    [(set (match_dup 5)
12280          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12281                  (ashift:SI (match_dup 3)
12282                             (minus:QI (const_int 32) (match_dup 2)))))
12283     (clobber (reg:CC FLAGS_REG))])]
12284  "split_di (operands, 1, operands + 4, operands + 5);")
12286 (define_insn "*rotrdi3_1_one_bit_rex64"
12287   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12288         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12289                      (match_operand:QI 2 "const1_operand" "")))
12290    (clobber (reg:CC FLAGS_REG))]
12291   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12292    && (TARGET_SHIFT1 || optimize_size)"
12293   "ror{q}\t%0"
12294   [(set_attr "type" "rotate")
12295    (set (attr "length") 
12296      (if_then_else (match_operand:DI 0 "register_operand" "") 
12297         (const_string "2")
12298         (const_string "*")))])
12300 (define_insn "*rotrdi3_1_rex64"
12301   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12302         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12303                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12306   "@
12307    ror{q}\t{%2, %0|%0, %2}
12308    ror{q}\t{%b2, %0|%0, %b2}"
12309   [(set_attr "type" "rotate")
12310    (set_attr "mode" "DI")])
12312 (define_expand "rotrsi3"
12313   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12314         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12315                      (match_operand:QI 2 "nonmemory_operand" "")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   ""
12318   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12320 (define_insn "*rotrsi3_1_one_bit"
12321   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12322         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12323                      (match_operand:QI 2 "const1_operand" "")))
12324    (clobber (reg:CC FLAGS_REG))]
12325   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12326    && (TARGET_SHIFT1 || optimize_size)"
12327   "ror{l}\t%0"
12328   [(set_attr "type" "rotate")
12329    (set (attr "length") 
12330      (if_then_else (match_operand:SI 0 "register_operand" "") 
12331         (const_string "2")
12332         (const_string "*")))])
12334 (define_insn "*rotrsi3_1_one_bit_zext"
12335   [(set (match_operand:DI 0 "register_operand" "=r")
12336         (zero_extend:DI
12337           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12338                        (match_operand:QI 2 "const1_operand" ""))))
12339    (clobber (reg:CC FLAGS_REG))]
12340   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12341    && (TARGET_SHIFT1 || optimize_size)"
12342   "ror{l}\t%k0"
12343   [(set_attr "type" "rotate")
12344    (set (attr "length") 
12345      (if_then_else (match_operand:SI 0 "register_operand" "") 
12346         (const_string "2")
12347         (const_string "*")))])
12349 (define_insn "*rotrsi3_1"
12350   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12351         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12352                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12355   "@
12356    ror{l}\t{%2, %0|%0, %2}
12357    ror{l}\t{%b2, %0|%0, %b2}"
12358   [(set_attr "type" "rotate")
12359    (set_attr "mode" "SI")])
12361 (define_insn "*rotrsi3_1_zext"
12362   [(set (match_operand:DI 0 "register_operand" "=r,r")
12363         (zero_extend:DI
12364           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12365                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12368   "@
12369    ror{l}\t{%2, %k0|%k0, %2}
12370    ror{l}\t{%b2, %k0|%k0, %b2}"
12371   [(set_attr "type" "rotate")
12372    (set_attr "mode" "SI")])
12374 (define_expand "rotrhi3"
12375   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12376         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12377                      (match_operand:QI 2 "nonmemory_operand" "")))
12378    (clobber (reg:CC FLAGS_REG))]
12379   "TARGET_HIMODE_MATH"
12380   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12382 (define_insn "*rotrhi3_one_bit"
12383   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12384         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12385                      (match_operand:QI 2 "const1_operand" "")))
12386    (clobber (reg:CC FLAGS_REG))]
12387   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12388    && (TARGET_SHIFT1 || optimize_size)"
12389   "ror{w}\t%0"
12390   [(set_attr "type" "rotate")
12391    (set (attr "length") 
12392      (if_then_else (match_operand 0 "register_operand" "") 
12393         (const_string "2")
12394         (const_string "*")))])
12396 (define_insn "*rotrhi3"
12397   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12398         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12399                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12400    (clobber (reg:CC FLAGS_REG))]
12401   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12402   "@
12403    ror{w}\t{%2, %0|%0, %2}
12404    ror{w}\t{%b2, %0|%0, %b2}"
12405   [(set_attr "type" "rotate")
12406    (set_attr "mode" "HI")])
12408 (define_expand "rotrqi3"
12409   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12410         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12411                      (match_operand:QI 2 "nonmemory_operand" "")))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "TARGET_QIMODE_MATH"
12414   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12416 (define_insn "*rotrqi3_1_one_bit"
12417   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12418         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12419                      (match_operand:QI 2 "const1_operand" "")))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12422    && (TARGET_SHIFT1 || optimize_size)"
12423   "ror{b}\t%0"
12424   [(set_attr "type" "rotate")
12425    (set (attr "length") 
12426      (if_then_else (match_operand 0 "register_operand" "") 
12427         (const_string "2")
12428         (const_string "*")))])
12430 (define_insn "*rotrqi3_1_one_bit_slp"
12431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12432         (rotatert:QI (match_dup 0)
12433                      (match_operand:QI 1 "const1_operand" "")))
12434    (clobber (reg:CC FLAGS_REG))]
12435   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12436    && (TARGET_SHIFT1 || optimize_size)"
12437   "ror{b}\t%0"
12438   [(set_attr "type" "rotate1")
12439    (set (attr "length") 
12440      (if_then_else (match_operand 0 "register_operand" "") 
12441         (const_string "2")
12442         (const_string "*")))])
12444 (define_insn "*rotrqi3_1"
12445   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12446         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12447                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12450   "@
12451    ror{b}\t{%2, %0|%0, %2}
12452    ror{b}\t{%b2, %0|%0, %b2}"
12453   [(set_attr "type" "rotate")
12454    (set_attr "mode" "QI")])
12456 (define_insn "*rotrqi3_1_slp"
12457   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12458         (rotatert:QI (match_dup 0)
12459                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12462    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12463   "@
12464    ror{b}\t{%1, %0|%0, %1}
12465    ror{b}\t{%b1, %0|%0, %b1}"
12466   [(set_attr "type" "rotate1")
12467    (set_attr "mode" "QI")])
12469 ;; Bit set / bit test instructions
12471 (define_expand "extv"
12472   [(set (match_operand:SI 0 "register_operand" "")
12473         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12474                          (match_operand:SI 2 "immediate_operand" "")
12475                          (match_operand:SI 3 "immediate_operand" "")))]
12476   ""
12478   /* Handle extractions from %ah et al.  */
12479   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12480     FAIL;
12482   /* From mips.md: extract_bit_field doesn't verify that our source
12483      matches the predicate, so check it again here.  */
12484   if (! ext_register_operand (operands[1], VOIDmode))
12485     FAIL;
12488 (define_expand "extzv"
12489   [(set (match_operand:SI 0 "register_operand" "")
12490         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12491                          (match_operand:SI 2 "immediate_operand" "")
12492                          (match_operand:SI 3 "immediate_operand" "")))]
12493   ""
12495   /* Handle extractions from %ah et al.  */
12496   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12497     FAIL;
12499   /* From mips.md: extract_bit_field doesn't verify that our source
12500      matches the predicate, so check it again here.  */
12501   if (! ext_register_operand (operands[1], VOIDmode))
12502     FAIL;
12505 (define_expand "insv"
12506   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12507                       (match_operand 1 "immediate_operand" "")
12508                       (match_operand 2 "immediate_operand" ""))
12509         (match_operand 3 "register_operand" ""))]
12510   ""
12512   /* Handle extractions from %ah et al.  */
12513   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12514     FAIL;
12516   /* From mips.md: insert_bit_field doesn't verify that our source
12517      matches the predicate, so check it again here.  */
12518   if (! ext_register_operand (operands[0], VOIDmode))
12519     FAIL;
12521   if (TARGET_64BIT)
12522     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12523   else
12524     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12526   DONE;
12529 ;; %%% bts, btr, btc, bt.
12530 ;; In general these instructions are *slow* when applied to memory,
12531 ;; since they enforce atomic operation.  When applied to registers,
12532 ;; it depends on the cpu implementation.  They're never faster than
12533 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12534 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12535 ;; within the instruction itself, so operating on bits in the high
12536 ;; 32-bits of a register becomes easier.
12538 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12539 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12540 ;; negdf respectively, so they can never be disabled entirely.
12542 (define_insn "*btsq"
12543   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12544                          (const_int 1)
12545                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12546         (const_int 1))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12549   "bts{q} %1,%0"
12550   [(set_attr "type" "alu1")])
12552 (define_insn "*btrq"
12553   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12554                          (const_int 1)
12555                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12556         (const_int 0))
12557    (clobber (reg:CC FLAGS_REG))]
12558   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12559   "btr{q} %1,%0"
12560   [(set_attr "type" "alu1")])
12562 (define_insn "*btcq"
12563   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12564                          (const_int 1)
12565                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12566         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12569   "btc{q} %1,%0"
12570   [(set_attr "type" "alu1")])
12572 ;; Allow Nocona to avoid these instructions if a register is available.
12574 (define_peephole2
12575   [(match_scratch:DI 2 "r")
12576    (parallel [(set (zero_extract:DI
12577                      (match_operand:DI 0 "register_operand" "")
12578                      (const_int 1)
12579                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12580                    (const_int 1))
12581               (clobber (reg:CC FLAGS_REG))])]
12582   "TARGET_64BIT && !TARGET_USE_BT"
12583   [(const_int 0)]
12585   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12586   rtx op1;
12588   if (HOST_BITS_PER_WIDE_INT >= 64)
12589     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12590   else if (i < HOST_BITS_PER_WIDE_INT)
12591     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12592   else
12593     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12595   op1 = immed_double_const (lo, hi, DImode);
12596   if (i >= 31)
12597     {
12598       emit_move_insn (operands[2], op1);
12599       op1 = operands[2];
12600     }
12602   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12603   DONE;
12606 (define_peephole2
12607   [(match_scratch:DI 2 "r")
12608    (parallel [(set (zero_extract:DI
12609                      (match_operand:DI 0 "register_operand" "")
12610                      (const_int 1)
12611                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12612                    (const_int 0))
12613               (clobber (reg:CC FLAGS_REG))])]
12614   "TARGET_64BIT && !TARGET_USE_BT"
12615   [(const_int 0)]
12617   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12618   rtx op1;
12620   if (HOST_BITS_PER_WIDE_INT >= 64)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else if (i < HOST_BITS_PER_WIDE_INT)
12623     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12624   else
12625     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12627   op1 = immed_double_const (~lo, ~hi, DImode);
12628   if (i >= 32)
12629     {
12630       emit_move_insn (operands[2], op1);
12631       op1 = operands[2];
12632     }
12634   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12635   DONE;
12638 (define_peephole2
12639   [(match_scratch:DI 2 "r")
12640    (parallel [(set (zero_extract:DI
12641                      (match_operand:DI 0 "register_operand" "")
12642                      (const_int 1)
12643                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12644               (not:DI (zero_extract:DI
12645                         (match_dup 0) (const_int 1) (match_dup 1))))
12646               (clobber (reg:CC FLAGS_REG))])]
12647   "TARGET_64BIT && !TARGET_USE_BT"
12648   [(const_int 0)]
12650   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12651   rtx op1;
12653   if (HOST_BITS_PER_WIDE_INT >= 64)
12654     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12655   else if (i < HOST_BITS_PER_WIDE_INT)
12656     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12657   else
12658     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12660   op1 = immed_double_const (lo, hi, DImode);
12661   if (i >= 31)
12662     {
12663       emit_move_insn (operands[2], op1);
12664       op1 = operands[2];
12665     }
12667   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12668   DONE;
12671 ;; Store-flag instructions.
12673 ;; For all sCOND expanders, also expand the compare or test insn that
12674 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12676 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12677 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12678 ;; way, which can later delete the movzx if only QImode is needed.
12680 (define_expand "seq"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   ""
12684   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12686 (define_expand "sne"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   ""
12690   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12692 (define_expand "sgt"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   ""
12696   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12698 (define_expand "sgtu"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   ""
12702   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12704 (define_expand "slt"
12705   [(set (match_operand:QI 0 "register_operand" "")
12706         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707   ""
12708   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12710 (define_expand "sltu"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12716 (define_expand "sge"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12722 (define_expand "sgeu"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12728 (define_expand "sle"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   ""
12732   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12734 (define_expand "sleu"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   ""
12738   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12740 (define_expand "sunordered"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   "TARGET_80387 || TARGET_SSE"
12744   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12746 (define_expand "sordered"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   "TARGET_80387"
12750   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12752 (define_expand "suneq"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   "TARGET_80387 || TARGET_SSE"
12756   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12758 (define_expand "sunge"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   "TARGET_80387 || TARGET_SSE"
12762   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12764 (define_expand "sungt"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   "TARGET_80387 || TARGET_SSE"
12768   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12770 (define_expand "sunle"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12776 (define_expand "sunlt"
12777   [(set (match_operand:QI 0 "register_operand" "")
12778         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779   "TARGET_80387 || TARGET_SSE"
12780   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12782 (define_expand "sltgt"
12783   [(set (match_operand:QI 0 "register_operand" "")
12784         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785   "TARGET_80387 || TARGET_SSE"
12786   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12788 (define_insn "*setcc_1"
12789   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790         (match_operator:QI 1 "ix86_comparison_operator"
12791           [(reg FLAGS_REG) (const_int 0)]))]
12792   ""
12793   "set%C1\t%0"
12794   [(set_attr "type" "setcc")
12795    (set_attr "mode" "QI")])
12797 (define_insn "*setcc_2"
12798   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12799         (match_operator:QI 1 "ix86_comparison_operator"
12800           [(reg FLAGS_REG) (const_int 0)]))]
12801   ""
12802   "set%C1\t%0"
12803   [(set_attr "type" "setcc")
12804    (set_attr "mode" "QI")])
12806 ;; In general it is not safe to assume too much about CCmode registers,
12807 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12808 ;; conditions this is safe on x86, so help combine not create
12810 ;;      seta    %al
12811 ;;      testb   %al, %al
12812 ;;      sete    %al
12814 (define_split 
12815   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12816         (ne:QI (match_operator 1 "ix86_comparison_operator"
12817                  [(reg FLAGS_REG) (const_int 0)])
12818             (const_int 0)))]
12819   ""
12820   [(set (match_dup 0) (match_dup 1))]
12822   PUT_MODE (operands[1], QImode);
12825 (define_split 
12826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12827         (ne:QI (match_operator 1 "ix86_comparison_operator"
12828                  [(reg FLAGS_REG) (const_int 0)])
12829             (const_int 0)))]
12830   ""
12831   [(set (match_dup 0) (match_dup 1))]
12833   PUT_MODE (operands[1], QImode);
12836 (define_split 
12837   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12838         (eq:QI (match_operator 1 "ix86_comparison_operator"
12839                  [(reg FLAGS_REG) (const_int 0)])
12840             (const_int 0)))]
12841   ""
12842   [(set (match_dup 0) (match_dup 1))]
12844   rtx new_op1 = copy_rtx (operands[1]);
12845   operands[1] = new_op1;
12846   PUT_MODE (new_op1, QImode);
12847   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12848                                              GET_MODE (XEXP (new_op1, 0))));
12850   /* Make sure that (a) the CCmode we have for the flags is strong
12851      enough for the reversed compare or (b) we have a valid FP compare.  */
12852   if (! ix86_comparison_operator (new_op1, VOIDmode))
12853     FAIL;
12856 (define_split 
12857   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12858         (eq:QI (match_operator 1 "ix86_comparison_operator"
12859                  [(reg FLAGS_REG) (const_int 0)])
12860             (const_int 0)))]
12861   ""
12862   [(set (match_dup 0) (match_dup 1))]
12864   rtx new_op1 = copy_rtx (operands[1]);
12865   operands[1] = new_op1;
12866   PUT_MODE (new_op1, QImode);
12867   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12868                                              GET_MODE (XEXP (new_op1, 0))));
12870   /* Make sure that (a) the CCmode we have for the flags is strong
12871      enough for the reversed compare or (b) we have a valid FP compare.  */
12872   if (! ix86_comparison_operator (new_op1, VOIDmode))
12873     FAIL;
12876 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12877 ;; subsequent logical operations are used to imitate conditional moves.
12878 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12879 ;; it directly.
12881 (define_insn "*sse_setccsf"
12882   [(set (match_operand:SF 0 "register_operand" "=x")
12883         (match_operator:SF 1 "sse_comparison_operator"
12884           [(match_operand:SF 2 "register_operand" "0")
12885            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12886   "TARGET_SSE"
12887   "cmp%D1ss\t{%3, %0|%0, %3}"
12888   [(set_attr "type" "ssecmp")
12889    (set_attr "mode" "SF")])
12891 (define_insn "*sse_setccdf"
12892   [(set (match_operand:DF 0 "register_operand" "=Y")
12893         (match_operator:DF 1 "sse_comparison_operator"
12894           [(match_operand:DF 2 "register_operand" "0")
12895            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12896   "TARGET_SSE2"
12897   "cmp%D1sd\t{%3, %0|%0, %3}"
12898   [(set_attr "type" "ssecmp")
12899    (set_attr "mode" "DF")])
12901 ;; Basic conditional jump instructions.
12902 ;; We ignore the overflow flag for signed branch instructions.
12904 ;; For all bCOND expanders, also expand the compare or test insn that
12905 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12907 (define_expand "beq"
12908   [(set (pc)
12909         (if_then_else (match_dup 1)
12910                       (label_ref (match_operand 0 "" ""))
12911                       (pc)))]
12912   ""
12913   "ix86_expand_branch (EQ, operands[0]); DONE;")
12915 (define_expand "bne"
12916   [(set (pc)
12917         (if_then_else (match_dup 1)
12918                       (label_ref (match_operand 0 "" ""))
12919                       (pc)))]
12920   ""
12921   "ix86_expand_branch (NE, operands[0]); DONE;")
12923 (define_expand "bgt"
12924   [(set (pc)
12925         (if_then_else (match_dup 1)
12926                       (label_ref (match_operand 0 "" ""))
12927                       (pc)))]
12928   ""
12929   "ix86_expand_branch (GT, operands[0]); DONE;")
12931 (define_expand "bgtu"
12932   [(set (pc)
12933         (if_then_else (match_dup 1)
12934                       (label_ref (match_operand 0 "" ""))
12935                       (pc)))]
12936   ""
12937   "ix86_expand_branch (GTU, operands[0]); DONE;")
12939 (define_expand "blt"
12940   [(set (pc)
12941         (if_then_else (match_dup 1)
12942                       (label_ref (match_operand 0 "" ""))
12943                       (pc)))]
12944   ""
12945   "ix86_expand_branch (LT, operands[0]); DONE;")
12947 (define_expand "bltu"
12948   [(set (pc)
12949         (if_then_else (match_dup 1)
12950                       (label_ref (match_operand 0 "" ""))
12951                       (pc)))]
12952   ""
12953   "ix86_expand_branch (LTU, operands[0]); DONE;")
12955 (define_expand "bge"
12956   [(set (pc)
12957         (if_then_else (match_dup 1)
12958                       (label_ref (match_operand 0 "" ""))
12959                       (pc)))]
12960   ""
12961   "ix86_expand_branch (GE, operands[0]); DONE;")
12963 (define_expand "bgeu"
12964   [(set (pc)
12965         (if_then_else (match_dup 1)
12966                       (label_ref (match_operand 0 "" ""))
12967                       (pc)))]
12968   ""
12969   "ix86_expand_branch (GEU, operands[0]); DONE;")
12971 (define_expand "ble"
12972   [(set (pc)
12973         (if_then_else (match_dup 1)
12974                       (label_ref (match_operand 0 "" ""))
12975                       (pc)))]
12976   ""
12977   "ix86_expand_branch (LE, operands[0]); DONE;")
12979 (define_expand "bleu"
12980   [(set (pc)
12981         (if_then_else (match_dup 1)
12982                       (label_ref (match_operand 0 "" ""))
12983                       (pc)))]
12984   ""
12985   "ix86_expand_branch (LEU, operands[0]); DONE;")
12987 (define_expand "bunordered"
12988   [(set (pc)
12989         (if_then_else (match_dup 1)
12990                       (label_ref (match_operand 0 "" ""))
12991                       (pc)))]
12992   "TARGET_80387 || TARGET_SSE_MATH"
12993   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12995 (define_expand "bordered"
12996   [(set (pc)
12997         (if_then_else (match_dup 1)
12998                       (label_ref (match_operand 0 "" ""))
12999                       (pc)))]
13000   "TARGET_80387 || TARGET_SSE_MATH"
13001   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13003 (define_expand "buneq"
13004   [(set (pc)
13005         (if_then_else (match_dup 1)
13006                       (label_ref (match_operand 0 "" ""))
13007                       (pc)))]
13008   "TARGET_80387 || TARGET_SSE_MATH"
13009   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13011 (define_expand "bunge"
13012   [(set (pc)
13013         (if_then_else (match_dup 1)
13014                       (label_ref (match_operand 0 "" ""))
13015                       (pc)))]
13016   "TARGET_80387 || TARGET_SSE_MATH"
13017   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13019 (define_expand "bungt"
13020   [(set (pc)
13021         (if_then_else (match_dup 1)
13022                       (label_ref (match_operand 0 "" ""))
13023                       (pc)))]
13024   "TARGET_80387 || TARGET_SSE_MATH"
13025   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13027 (define_expand "bunle"
13028   [(set (pc)
13029         (if_then_else (match_dup 1)
13030                       (label_ref (match_operand 0 "" ""))
13031                       (pc)))]
13032   "TARGET_80387 || TARGET_SSE_MATH"
13033   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13035 (define_expand "bunlt"
13036   [(set (pc)
13037         (if_then_else (match_dup 1)
13038                       (label_ref (match_operand 0 "" ""))
13039                       (pc)))]
13040   "TARGET_80387 || TARGET_SSE_MATH"
13041   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13043 (define_expand "bltgt"
13044   [(set (pc)
13045         (if_then_else (match_dup 1)
13046                       (label_ref (match_operand 0 "" ""))
13047                       (pc)))]
13048   "TARGET_80387 || TARGET_SSE_MATH"
13049   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13051 (define_insn "*jcc_1"
13052   [(set (pc)
13053         (if_then_else (match_operator 1 "ix86_comparison_operator"
13054                                       [(reg FLAGS_REG) (const_int 0)])
13055                       (label_ref (match_operand 0 "" ""))
13056                       (pc)))]
13057   ""
13058   "%+j%C1\t%l0"
13059   [(set_attr "type" "ibr")
13060    (set_attr "modrm" "0")
13061    (set (attr "length")
13062            (if_then_else (and (ge (minus (match_dup 0) (pc))
13063                                   (const_int -126))
13064                               (lt (minus (match_dup 0) (pc))
13065                                   (const_int 128)))
13066              (const_int 2)
13067              (const_int 6)))])
13069 (define_insn "*jcc_2"
13070   [(set (pc)
13071         (if_then_else (match_operator 1 "ix86_comparison_operator"
13072                                       [(reg FLAGS_REG) (const_int 0)])
13073                       (pc)
13074                       (label_ref (match_operand 0 "" ""))))]
13075   ""
13076   "%+j%c1\t%l0"
13077   [(set_attr "type" "ibr")
13078    (set_attr "modrm" "0")
13079    (set (attr "length")
13080            (if_then_else (and (ge (minus (match_dup 0) (pc))
13081                                   (const_int -126))
13082                               (lt (minus (match_dup 0) (pc))
13083                                   (const_int 128)))
13084              (const_int 2)
13085              (const_int 6)))])
13087 ;; In general it is not safe to assume too much about CCmode registers,
13088 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13089 ;; conditions this is safe on x86, so help combine not create
13091 ;;      seta    %al
13092 ;;      testb   %al, %al
13093 ;;      je      Lfoo
13095 (define_split 
13096   [(set (pc)
13097         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13098                                       [(reg FLAGS_REG) (const_int 0)])
13099                           (const_int 0))
13100                       (label_ref (match_operand 1 "" ""))
13101                       (pc)))]
13102   ""
13103   [(set (pc)
13104         (if_then_else (match_dup 0)
13105                       (label_ref (match_dup 1))
13106                       (pc)))]
13108   PUT_MODE (operands[0], VOIDmode);
13110   
13111 (define_split 
13112   [(set (pc)
13113         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13114                                       [(reg FLAGS_REG) (const_int 0)])
13115                           (const_int 0))
13116                       (label_ref (match_operand 1 "" ""))
13117                       (pc)))]
13118   ""
13119   [(set (pc)
13120         (if_then_else (match_dup 0)
13121                       (label_ref (match_dup 1))
13122                       (pc)))]
13124   rtx new_op0 = copy_rtx (operands[0]);
13125   operands[0] = new_op0;
13126   PUT_MODE (new_op0, VOIDmode);
13127   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13128                                              GET_MODE (XEXP (new_op0, 0))));
13130   /* Make sure that (a) the CCmode we have for the flags is strong
13131      enough for the reversed compare or (b) we have a valid FP compare.  */
13132   if (! ix86_comparison_operator (new_op0, VOIDmode))
13133     FAIL;
13136 ;; Define combination compare-and-branch fp compare instructions to use
13137 ;; during early optimization.  Splitting the operation apart early makes
13138 ;; for bad code when we want to reverse the operation.
13140 (define_insn "*fp_jcc_1_mixed"
13141   [(set (pc)
13142         (if_then_else (match_operator 0 "comparison_operator"
13143                         [(match_operand 1 "register_operand" "f#x,x#f")
13144                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13145           (label_ref (match_operand 3 "" ""))
13146           (pc)))
13147    (clobber (reg:CCFP FPSR_REG))
13148    (clobber (reg:CCFP FLAGS_REG))]
13149   "TARGET_MIX_SSE_I387
13150    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13151    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13152    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13153   "#")
13155 (define_insn "*fp_jcc_1_sse"
13156   [(set (pc)
13157         (if_then_else (match_operator 0 "comparison_operator"
13158                         [(match_operand 1 "register_operand" "x")
13159                          (match_operand 2 "nonimmediate_operand" "xm")])
13160           (label_ref (match_operand 3 "" ""))
13161           (pc)))
13162    (clobber (reg:CCFP FPSR_REG))
13163    (clobber (reg:CCFP FLAGS_REG))]
13164   "TARGET_SSE_MATH
13165    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13166    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13167    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13168   "#")
13170 (define_insn "*fp_jcc_1_387"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "f")
13174                          (match_operand 2 "register_operand" "f")])
13175           (label_ref (match_operand 3 "" ""))
13176           (pc)))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "TARGET_CMOVE && TARGET_80387
13180    && FLOAT_MODE_P (GET_MODE (operands[1]))
13181    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13183   "#")
13185 (define_insn "*fp_jcc_2_mixed"
13186   [(set (pc)
13187         (if_then_else (match_operator 0 "comparison_operator"
13188                         [(match_operand 1 "register_operand" "f#x,x#f")
13189                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13190           (pc)
13191           (label_ref (match_operand 3 "" ""))))
13192    (clobber (reg:CCFP FPSR_REG))
13193    (clobber (reg:CCFP FLAGS_REG))]
13194   "TARGET_MIX_SSE_I387
13195    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13200 (define_insn "*fp_jcc_2_sse"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "x")
13204                          (match_operand 2 "nonimmediate_operand" "xm")])
13205           (pc)
13206           (label_ref (match_operand 3 "" ""))))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))]
13209   "TARGET_SSE_MATH
13210    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13211    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213   "#")
13215 (define_insn "*fp_jcc_2_387"
13216   [(set (pc)
13217         (if_then_else (match_operator 0 "comparison_operator"
13218                         [(match_operand 1 "register_operand" "f")
13219                          (match_operand 2 "register_operand" "f")])
13220           (pc)
13221           (label_ref (match_operand 3 "" ""))))
13222    (clobber (reg:CCFP FPSR_REG))
13223    (clobber (reg:CCFP FLAGS_REG))]
13224   "TARGET_CMOVE && TARGET_80387
13225    && FLOAT_MODE_P (GET_MODE (operands[1]))
13226    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228   "#")
13230 (define_insn "*fp_jcc_3_387"
13231   [(set (pc)
13232         (if_then_else (match_operator 0 "comparison_operator"
13233                         [(match_operand 1 "register_operand" "f")
13234                          (match_operand 2 "nonimmediate_operand" "fm")])
13235           (label_ref (match_operand 3 "" ""))
13236           (pc)))
13237    (clobber (reg:CCFP FPSR_REG))
13238    (clobber (reg:CCFP FLAGS_REG))
13239    (clobber (match_scratch:HI 4 "=a"))]
13240   "TARGET_80387
13241    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13242    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13243    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13244    && SELECT_CC_MODE (GET_CODE (operands[0]),
13245                       operands[1], operands[2]) == CCFPmode
13246    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13247   "#")
13249 (define_insn "*fp_jcc_4_387"
13250   [(set (pc)
13251         (if_then_else (match_operator 0 "comparison_operator"
13252                         [(match_operand 1 "register_operand" "f")
13253                          (match_operand 2 "nonimmediate_operand" "fm")])
13254           (pc)
13255           (label_ref (match_operand 3 "" ""))))
13256    (clobber (reg:CCFP FPSR_REG))
13257    (clobber (reg:CCFP FLAGS_REG))
13258    (clobber (match_scratch:HI 4 "=a"))]
13259   "TARGET_80387
13260    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13261    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13262    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13263    && SELECT_CC_MODE (GET_CODE (operands[0]),
13264                       operands[1], operands[2]) == CCFPmode
13265    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13266   "#")
13268 (define_insn "*fp_jcc_5_387"
13269   [(set (pc)
13270         (if_then_else (match_operator 0 "comparison_operator"
13271                         [(match_operand 1 "register_operand" "f")
13272                          (match_operand 2 "register_operand" "f")])
13273           (label_ref (match_operand 3 "" ""))
13274           (pc)))
13275    (clobber (reg:CCFP FPSR_REG))
13276    (clobber (reg:CCFP FLAGS_REG))
13277    (clobber (match_scratch:HI 4 "=a"))]
13278   "TARGET_80387
13279    && FLOAT_MODE_P (GET_MODE (operands[1]))
13280    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13281    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13282   "#")
13284 (define_insn "*fp_jcc_6_387"
13285   [(set (pc)
13286         (if_then_else (match_operator 0 "comparison_operator"
13287                         [(match_operand 1 "register_operand" "f")
13288                          (match_operand 2 "register_operand" "f")])
13289           (pc)
13290           (label_ref (match_operand 3 "" ""))))
13291    (clobber (reg:CCFP FPSR_REG))
13292    (clobber (reg:CCFP FLAGS_REG))
13293    (clobber (match_scratch:HI 4 "=a"))]
13294   "TARGET_80387
13295    && FLOAT_MODE_P (GET_MODE (operands[1]))
13296    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13297    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13298   "#")
13300 (define_insn "*fp_jcc_7_387"
13301   [(set (pc)
13302         (if_then_else (match_operator 0 "comparison_operator"
13303                         [(match_operand 1 "register_operand" "f")
13304                          (match_operand 2 "const0_operand" "X")])
13305           (label_ref (match_operand 3 "" ""))
13306           (pc)))
13307    (clobber (reg:CCFP FPSR_REG))
13308    (clobber (reg:CCFP FLAGS_REG))
13309    (clobber (match_scratch:HI 4 "=a"))]
13310   "TARGET_80387
13311    && FLOAT_MODE_P (GET_MODE (operands[1]))
13312    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13313    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13314    && SELECT_CC_MODE (GET_CODE (operands[0]),
13315                       operands[1], operands[2]) == CCFPmode
13316    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13317   "#")
13319 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13320 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13321 ;; with a precedence over other operators and is always put in the first
13322 ;; place. Swap condition and operands to match ficom instruction.
13324 (define_insn "*fp_jcc_8<mode>_387"
13325   [(set (pc)
13326         (if_then_else (match_operator 0 "comparison_operator"
13327                         [(match_operator 1 "float_operator"
13328                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13329                            (match_operand 3 "register_operand" "f,f")])
13330           (label_ref (match_operand 4 "" ""))
13331           (pc)))
13332    (clobber (reg:CCFP FPSR_REG))
13333    (clobber (reg:CCFP FLAGS_REG))
13334    (clobber (match_scratch:HI 5 "=a,a"))]
13335   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13336    && FLOAT_MODE_P (GET_MODE (operands[3]))
13337    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13338    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13339    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13340    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13341   "#")
13343 (define_split
13344   [(set (pc)
13345         (if_then_else (match_operator 0 "comparison_operator"
13346                         [(match_operand 1 "register_operand" "")
13347                          (match_operand 2 "nonimmediate_operand" "")])
13348           (match_operand 3 "" "")
13349           (match_operand 4 "" "")))
13350    (clobber (reg:CCFP FPSR_REG))
13351    (clobber (reg:CCFP FLAGS_REG))]
13352   "reload_completed"
13353   [(const_int 0)]
13355   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13356                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13357   DONE;
13360 (define_split
13361   [(set (pc)
13362         (if_then_else (match_operator 0 "comparison_operator"
13363                         [(match_operand 1 "register_operand" "")
13364                          (match_operand 2 "general_operand" "")])
13365           (match_operand 3 "" "")
13366           (match_operand 4 "" "")))
13367    (clobber (reg:CCFP FPSR_REG))
13368    (clobber (reg:CCFP FLAGS_REG))
13369    (clobber (match_scratch:HI 5 "=a"))]
13370   "reload_completed"
13371   [(const_int 0)]
13373   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13374                         operands[3], operands[4], operands[5], NULL_RTX);
13375   DONE;
13378 (define_split
13379   [(set (pc)
13380         (if_then_else (match_operator 0 "comparison_operator"
13381                         [(match_operator 1 "float_operator"
13382                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13383                            (match_operand 3 "register_operand" "")])
13384           (match_operand 4 "" "")
13385           (match_operand 5 "" "")))
13386    (clobber (reg:CCFP FPSR_REG))
13387    (clobber (reg:CCFP FLAGS_REG))
13388    (clobber (match_scratch:HI 6 "=a"))]
13389   "reload_completed"
13390   [(const_int 0)]
13392   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13393   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13394                         operands[3], operands[7],
13395                         operands[4], operands[5], operands[6], NULL_RTX);
13396   DONE;
13399 ;; %%% Kill this when reload knows how to do it.
13400 (define_split
13401   [(set (pc)
13402         (if_then_else (match_operator 0 "comparison_operator"
13403                         [(match_operator 1 "float_operator"
13404                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13405                            (match_operand 3 "register_operand" "")])
13406           (match_operand 4 "" "")
13407           (match_operand 5 "" "")))
13408    (clobber (reg:CCFP FPSR_REG))
13409    (clobber (reg:CCFP FLAGS_REG))
13410    (clobber (match_scratch:HI 6 "=a"))]
13411   "reload_completed"
13412   [(const_int 0)]
13414   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13415   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13416   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13417                         operands[3], operands[7],
13418                         operands[4], operands[5], operands[6], operands[2]);
13419   DONE;
13422 ;; Unconditional and other jump instructions
13424 (define_insn "jump"
13425   [(set (pc)
13426         (label_ref (match_operand 0 "" "")))]
13427   ""
13428   "jmp\t%l0"
13429   [(set_attr "type" "ibr")
13430    (set (attr "length")
13431            (if_then_else (and (ge (minus (match_dup 0) (pc))
13432                                   (const_int -126))
13433                               (lt (minus (match_dup 0) (pc))
13434                                   (const_int 128)))
13435              (const_int 2)
13436              (const_int 5)))
13437    (set_attr "modrm" "0")])
13439 (define_expand "indirect_jump"
13440   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13441   ""
13442   "")
13444 (define_insn "*indirect_jump"
13445   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13446   "!TARGET_64BIT"
13447   "jmp\t%A0"
13448   [(set_attr "type" "ibr")
13449    (set_attr "length_immediate" "0")])
13451 (define_insn "*indirect_jump_rtx64"
13452   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13453   "TARGET_64BIT"
13454   "jmp\t%A0"
13455   [(set_attr "type" "ibr")
13456    (set_attr "length_immediate" "0")])
13458 (define_expand "tablejump"
13459   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13460               (use (label_ref (match_operand 1 "" "")))])]
13461   ""
13463   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13464      relative.  Convert the relative address to an absolute address.  */
13465   if (flag_pic)
13466     {
13467       rtx op0, op1;
13468       enum rtx_code code;
13470       if (TARGET_64BIT)
13471         {
13472           code = PLUS;
13473           op0 = operands[0];
13474           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13475         }
13476       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13477         {
13478           code = PLUS;
13479           op0 = operands[0];
13480           op1 = pic_offset_table_rtx;
13481         }
13482       else
13483         {
13484           code = MINUS;
13485           op0 = pic_offset_table_rtx;
13486           op1 = operands[0];
13487         }
13489       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13490                                          OPTAB_DIRECT);
13491     }
13494 (define_insn "*tablejump_1"
13495   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13496    (use (label_ref (match_operand 1 "" "")))]
13497   "!TARGET_64BIT"
13498   "jmp\t%A0"
13499   [(set_attr "type" "ibr")
13500    (set_attr "length_immediate" "0")])
13502 (define_insn "*tablejump_1_rtx64"
13503   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13504    (use (label_ref (match_operand 1 "" "")))]
13505   "TARGET_64BIT"
13506   "jmp\t%A0"
13507   [(set_attr "type" "ibr")
13508    (set_attr "length_immediate" "0")])
13510 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13512 (define_peephole2
13513   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13514    (set (match_operand:QI 1 "register_operand" "")
13515         (match_operator:QI 2 "ix86_comparison_operator"
13516           [(reg FLAGS_REG) (const_int 0)]))
13517    (set (match_operand 3 "q_regs_operand" "")
13518         (zero_extend (match_dup 1)))]
13519   "(peep2_reg_dead_p (3, operands[1])
13520     || operands_match_p (operands[1], operands[3]))
13521    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13522   [(set (match_dup 4) (match_dup 0))
13523    (set (strict_low_part (match_dup 5))
13524         (match_dup 2))]
13526   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13527   operands[5] = gen_lowpart (QImode, operands[3]);
13528   ix86_expand_clear (operands[3]);
13531 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13533 (define_peephole2
13534   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13535    (set (match_operand:QI 1 "register_operand" "")
13536         (match_operator:QI 2 "ix86_comparison_operator"
13537           [(reg FLAGS_REG) (const_int 0)]))
13538    (parallel [(set (match_operand 3 "q_regs_operand" "")
13539                    (zero_extend (match_dup 1)))
13540               (clobber (reg:CC FLAGS_REG))])]
13541   "(peep2_reg_dead_p (3, operands[1])
13542     || operands_match_p (operands[1], operands[3]))
13543    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13544   [(set (match_dup 4) (match_dup 0))
13545    (set (strict_low_part (match_dup 5))
13546         (match_dup 2))]
13548   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13549   operands[5] = gen_lowpart (QImode, operands[3]);
13550   ix86_expand_clear (operands[3]);
13553 ;; Call instructions.
13555 ;; The predicates normally associated with named expanders are not properly
13556 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13557 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13559 ;; Call subroutine returning no value.
13561 (define_expand "call_pop"
13562   [(parallel [(call (match_operand:QI 0 "" "")
13563                     (match_operand:SI 1 "" ""))
13564               (set (reg:SI SP_REG)
13565                    (plus:SI (reg:SI SP_REG)
13566                             (match_operand:SI 3 "" "")))])]
13567   "!TARGET_64BIT"
13569   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13570   DONE;
13573 (define_insn "*call_pop_0"
13574   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13575          (match_operand:SI 1 "" ""))
13576    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13577                             (match_operand:SI 2 "immediate_operand" "")))]
13578   "!TARGET_64BIT"
13580   if (SIBLING_CALL_P (insn))
13581     return "jmp\t%P0";
13582   else
13583     return "call\t%P0";
13585   [(set_attr "type" "call")])
13586   
13587 (define_insn "*call_pop_1"
13588   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13589          (match_operand:SI 1 "" ""))
13590    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13591                             (match_operand:SI 2 "immediate_operand" "i")))]
13592   "!TARGET_64BIT"
13594   if (constant_call_address_operand (operands[0], Pmode))
13595     {
13596       if (SIBLING_CALL_P (insn))
13597         return "jmp\t%P0";
13598       else
13599         return "call\t%P0";
13600     }
13601   if (SIBLING_CALL_P (insn))
13602     return "jmp\t%A0";
13603   else
13604     return "call\t%A0";
13606   [(set_attr "type" "call")])
13608 (define_expand "call"
13609   [(call (match_operand:QI 0 "" "")
13610          (match_operand 1 "" ""))
13611    (use (match_operand 2 "" ""))]
13612   ""
13614   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13615   DONE;
13618 (define_expand "sibcall"
13619   [(call (match_operand:QI 0 "" "")
13620          (match_operand 1 "" ""))
13621    (use (match_operand 2 "" ""))]
13622   ""
13624   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13625   DONE;
13628 (define_insn "*call_0"
13629   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13630          (match_operand 1 "" ""))]
13631   ""
13633   if (SIBLING_CALL_P (insn))
13634     return "jmp\t%P0";
13635   else
13636     return "call\t%P0";
13638   [(set_attr "type" "call")])
13640 (define_insn "*call_1"
13641   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13642          (match_operand 1 "" ""))]
13643   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13645   if (constant_call_address_operand (operands[0], Pmode))
13646     return "call\t%P0";
13647   return "call\t%A0";
13649   [(set_attr "type" "call")])
13651 (define_insn "*sibcall_1"
13652   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13653          (match_operand 1 "" ""))]
13654   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13656   if (constant_call_address_operand (operands[0], Pmode))
13657     return "jmp\t%P0";
13658   return "jmp\t%A0";
13660   [(set_attr "type" "call")])
13662 (define_insn "*call_1_rex64"
13663   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13664          (match_operand 1 "" ""))]
13665   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13667   if (constant_call_address_operand (operands[0], Pmode))
13668     return "call\t%P0";
13669   return "call\t%A0";
13671   [(set_attr "type" "call")])
13673 (define_insn "*sibcall_1_rex64"
13674   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13675          (match_operand 1 "" ""))]
13676   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13677   "jmp\t%P0"
13678   [(set_attr "type" "call")])
13680 (define_insn "*sibcall_1_rex64_v"
13681   [(call (mem:QI (reg:DI 40))
13682          (match_operand 0 "" ""))]
13683   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13684   "jmp\t*%%r11"
13685   [(set_attr "type" "call")])
13688 ;; Call subroutine, returning value in operand 0
13690 (define_expand "call_value_pop"
13691   [(parallel [(set (match_operand 0 "" "")
13692                    (call (match_operand:QI 1 "" "")
13693                          (match_operand:SI 2 "" "")))
13694               (set (reg:SI SP_REG)
13695                    (plus:SI (reg:SI SP_REG)
13696                             (match_operand:SI 4 "" "")))])]
13697   "!TARGET_64BIT"
13699   ix86_expand_call (operands[0], operands[1], operands[2],
13700                     operands[3], operands[4], 0);
13701   DONE;
13704 (define_expand "call_value"
13705   [(set (match_operand 0 "" "")
13706         (call (match_operand:QI 1 "" "")
13707               (match_operand:SI 2 "" "")))
13708    (use (match_operand:SI 3 "" ""))]
13709   ;; Operand 2 not used on the i386.
13710   ""
13712   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13713   DONE;
13716 (define_expand "sibcall_value"
13717   [(set (match_operand 0 "" "")
13718         (call (match_operand:QI 1 "" "")
13719               (match_operand:SI 2 "" "")))
13720    (use (match_operand:SI 3 "" ""))]
13721   ;; Operand 2 not used on the i386.
13722   ""
13724   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13725   DONE;
13728 ;; Call subroutine returning any type.
13730 (define_expand "untyped_call"
13731   [(parallel [(call (match_operand 0 "" "")
13732                     (const_int 0))
13733               (match_operand 1 "" "")
13734               (match_operand 2 "" "")])]
13735   ""
13737   int i;
13739   /* In order to give reg-stack an easier job in validating two
13740      coprocessor registers as containing a possible return value,
13741      simply pretend the untyped call returns a complex long double
13742      value.  */
13744   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13745                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13746                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13747                     NULL, 0);
13749   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13750     {
13751       rtx set = XVECEXP (operands[2], 0, i);
13752       emit_move_insn (SET_DEST (set), SET_SRC (set));
13753     }
13755   /* The optimizer does not know that the call sets the function value
13756      registers we stored in the result block.  We avoid problems by
13757      claiming that all hard registers are used and clobbered at this
13758      point.  */
13759   emit_insn (gen_blockage (const0_rtx));
13761   DONE;
13764 ;; Prologue and epilogue instructions
13766 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13767 ;; all of memory.  This blocks insns from being moved across this point.
13769 (define_insn "blockage"
13770   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13771   ""
13772   ""
13773   [(set_attr "length" "0")])
13775 ;; Insn emitted into the body of a function to return from a function.
13776 ;; This is only done if the function's epilogue is known to be simple.
13777 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13779 (define_expand "return"
13780   [(return)]
13781   "ix86_can_use_return_insn_p ()"
13783   if (current_function_pops_args)
13784     {
13785       rtx popc = GEN_INT (current_function_pops_args);
13786       emit_jump_insn (gen_return_pop_internal (popc));
13787       DONE;
13788     }
13791 (define_insn "return_internal"
13792   [(return)]
13793   "reload_completed"
13794   "ret"
13795   [(set_attr "length" "1")
13796    (set_attr "length_immediate" "0")
13797    (set_attr "modrm" "0")])
13799 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13800 ;; instruction Athlon and K8 have.
13802 (define_insn "return_internal_long"
13803   [(return)
13804    (unspec [(const_int 0)] UNSPEC_REP)]
13805   "reload_completed"
13806   "rep {;} ret"
13807   [(set_attr "length" "1")
13808    (set_attr "length_immediate" "0")
13809    (set_attr "prefix_rep" "1")
13810    (set_attr "modrm" "0")])
13812 (define_insn "return_pop_internal"
13813   [(return)
13814    (use (match_operand:SI 0 "const_int_operand" ""))]
13815   "reload_completed"
13816   "ret\t%0"
13817   [(set_attr "length" "3")
13818    (set_attr "length_immediate" "2")
13819    (set_attr "modrm" "0")])
13821 (define_insn "return_indirect_internal"
13822   [(return)
13823    (use (match_operand:SI 0 "register_operand" "r"))]
13824   "reload_completed"
13825   "jmp\t%A0"
13826   [(set_attr "type" "ibr")
13827    (set_attr "length_immediate" "0")])
13829 (define_insn "nop"
13830   [(const_int 0)]
13831   ""
13832   "nop"
13833   [(set_attr "length" "1")
13834    (set_attr "length_immediate" "0")
13835    (set_attr "modrm" "0")])
13837 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13838 ;; branch prediction penalty for the third jump in a 16-byte
13839 ;; block on K8.
13841 (define_insn "align"
13842   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13843   ""
13845 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13846   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13847 #else
13848   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13849      The align insn is used to avoid 3 jump instructions in the row to improve
13850      branch prediction and the benefits hardly outweight the cost of extra 8
13851      nops on the average inserted by full alignment pseudo operation.  */
13852 #endif
13853   return "";
13855   [(set_attr "length" "16")])
13857 (define_expand "prologue"
13858   [(const_int 1)]
13859   ""
13860   "ix86_expand_prologue (); DONE;")
13862 (define_insn "set_got"
13863   [(set (match_operand:SI 0 "register_operand" "=r")
13864         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13865    (clobber (reg:CC FLAGS_REG))]
13866   "!TARGET_64BIT"
13867   { return output_set_got (operands[0]); }
13868   [(set_attr "type" "multi")
13869    (set_attr "length" "12")])
13871 (define_insn "set_got_rex64"
13872   [(set (match_operand:DI 0 "register_operand" "=r")
13873         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13874   "TARGET_64BIT"
13875   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13876   [(set_attr "type" "lea")
13877    (set_attr "length" "6")])
13879 (define_expand "epilogue"
13880   [(const_int 1)]
13881   ""
13882   "ix86_expand_epilogue (1); DONE;")
13884 (define_expand "sibcall_epilogue"
13885   [(const_int 1)]
13886   ""
13887   "ix86_expand_epilogue (0); DONE;")
13889 (define_expand "eh_return"
13890   [(use (match_operand 0 "register_operand" ""))]
13891   ""
13893   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13895   /* Tricky bit: we write the address of the handler to which we will
13896      be returning into someone else's stack frame, one word below the
13897      stack address we wish to restore.  */
13898   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13899   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13900   tmp = gen_rtx_MEM (Pmode, tmp);
13901   emit_move_insn (tmp, ra);
13903   if (Pmode == SImode)
13904     emit_jump_insn (gen_eh_return_si (sa));
13905   else
13906     emit_jump_insn (gen_eh_return_di (sa));
13907   emit_barrier ();
13908   DONE;
13911 (define_insn_and_split "eh_return_si"
13912   [(set (pc) 
13913         (unspec [(match_operand:SI 0 "register_operand" "c")]
13914                  UNSPEC_EH_RETURN))]
13915   "!TARGET_64BIT"
13916   "#"
13917   "reload_completed"
13918   [(const_int 1)]
13919   "ix86_expand_epilogue (2); DONE;")
13921 (define_insn_and_split "eh_return_di"
13922   [(set (pc) 
13923         (unspec [(match_operand:DI 0 "register_operand" "c")]
13924                  UNSPEC_EH_RETURN))]
13925   "TARGET_64BIT"
13926   "#"
13927   "reload_completed"
13928   [(const_int 1)]
13929   "ix86_expand_epilogue (2); DONE;")
13931 (define_insn "leave"
13932   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13933    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13934    (clobber (mem:BLK (scratch)))]
13935   "!TARGET_64BIT"
13936   "leave"
13937   [(set_attr "type" "leave")])
13939 (define_insn "leave_rex64"
13940   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13941    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13942    (clobber (mem:BLK (scratch)))]
13943   "TARGET_64BIT"
13944   "leave"
13945   [(set_attr "type" "leave")])
13947 (define_expand "ffssi2"
13948   [(parallel
13949      [(set (match_operand:SI 0 "register_operand" "") 
13950            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13951       (clobber (match_scratch:SI 2 ""))
13952       (clobber (reg:CC FLAGS_REG))])]
13953   ""
13954   "")
13956 (define_insn_and_split "*ffs_cmove"
13957   [(set (match_operand:SI 0 "register_operand" "=r") 
13958         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13959    (clobber (match_scratch:SI 2 "=&r"))
13960    (clobber (reg:CC FLAGS_REG))]
13961   "TARGET_CMOVE"
13962   "#"
13963   "&& reload_completed"
13964   [(set (match_dup 2) (const_int -1))
13965    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13966               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13967    (set (match_dup 0) (if_then_else:SI
13968                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13969                         (match_dup 2)
13970                         (match_dup 0)))
13971    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13972               (clobber (reg:CC FLAGS_REG))])]
13973   "")
13975 (define_insn_and_split "*ffs_no_cmove"
13976   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13977         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13978    (clobber (match_scratch:SI 2 "=&q"))
13979    (clobber (reg:CC FLAGS_REG))]
13980   ""
13981   "#"
13982   "reload_completed"
13983   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13984               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13985    (set (strict_low_part (match_dup 3))
13986         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13987    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13988               (clobber (reg:CC FLAGS_REG))])
13989    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13990               (clobber (reg:CC FLAGS_REG))])
13991    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13992               (clobber (reg:CC FLAGS_REG))])]
13994   operands[3] = gen_lowpart (QImode, operands[2]);
13995   ix86_expand_clear (operands[2]);
13998 (define_insn "*ffssi_1"
13999   [(set (reg:CCZ FLAGS_REG)
14000         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14001                      (const_int 0)))
14002    (set (match_operand:SI 0 "register_operand" "=r")
14003         (ctz:SI (match_dup 1)))]
14004   ""
14005   "bsf{l}\t{%1, %0|%0, %1}"
14006   [(set_attr "prefix_0f" "1")])
14008 (define_expand "ffsdi2"
14009   [(parallel
14010      [(set (match_operand:DI 0 "register_operand" "") 
14011            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14012       (clobber (match_scratch:DI 2 ""))
14013       (clobber (reg:CC FLAGS_REG))])]
14014   "TARGET_64BIT && TARGET_CMOVE"
14015   "")
14017 (define_insn_and_split "*ffs_rex64"
14018   [(set (match_operand:DI 0 "register_operand" "=r") 
14019         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14020    (clobber (match_scratch:DI 2 "=&r"))
14021    (clobber (reg:CC FLAGS_REG))]
14022   "TARGET_64BIT && TARGET_CMOVE"
14023   "#"
14024   "&& reload_completed"
14025   [(set (match_dup 2) (const_int -1))
14026    (parallel [(set (reg:CCZ FLAGS_REG)
14027                    (compare:CCZ (match_dup 1) (const_int 0)))
14028               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14029    (set (match_dup 0) (if_then_else:DI
14030                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14031                         (match_dup 2)
14032                         (match_dup 0)))
14033    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14034               (clobber (reg:CC FLAGS_REG))])]
14035   "")
14037 (define_insn "*ffsdi_1"
14038   [(set (reg:CCZ FLAGS_REG)
14039         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14040                      (const_int 0)))
14041    (set (match_operand:DI 0 "register_operand" "=r")
14042         (ctz:DI (match_dup 1)))]
14043   "TARGET_64BIT"
14044   "bsf{q}\t{%1, %0|%0, %1}"
14045   [(set_attr "prefix_0f" "1")])
14047 (define_insn "ctzsi2"
14048   [(set (match_operand:SI 0 "register_operand" "=r")
14049         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14050    (clobber (reg:CC FLAGS_REG))]
14051   ""
14052   "bsf{l}\t{%1, %0|%0, %1}"
14053   [(set_attr "prefix_0f" "1")])
14055 (define_insn "ctzdi2"
14056   [(set (match_operand:DI 0 "register_operand" "=r")
14057         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14058    (clobber (reg:CC FLAGS_REG))]
14059   "TARGET_64BIT"
14060   "bsf{q}\t{%1, %0|%0, %1}"
14061   [(set_attr "prefix_0f" "1")])
14063 (define_expand "clzsi2"
14064   [(parallel
14065      [(set (match_operand:SI 0 "register_operand" "")
14066            (minus:SI (const_int 31)
14067                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14068       (clobber (reg:CC FLAGS_REG))])
14069    (parallel
14070      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14071       (clobber (reg:CC FLAGS_REG))])]
14072   ""
14073   "")
14075 (define_insn "*bsr"
14076   [(set (match_operand:SI 0 "register_operand" "=r")
14077         (minus:SI (const_int 31)
14078                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14079    (clobber (reg:CC FLAGS_REG))]
14080   ""
14081   "bsr{l}\t{%1, %0|%0, %1}"
14082   [(set_attr "prefix_0f" "1")])
14084 (define_expand "clzdi2"
14085   [(parallel
14086      [(set (match_operand:DI 0 "register_operand" "")
14087            (minus:DI (const_int 63)
14088                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14089       (clobber (reg:CC FLAGS_REG))])
14090    (parallel
14091      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14092       (clobber (reg:CC FLAGS_REG))])]
14093   "TARGET_64BIT"
14094   "")
14096 (define_insn "*bsr_rex64"
14097   [(set (match_operand:DI 0 "register_operand" "=r")
14098         (minus:DI (const_int 63)
14099                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14100    (clobber (reg:CC FLAGS_REG))]
14101   "TARGET_64BIT"
14102   "bsr{q}\t{%1, %0|%0, %1}"
14103   [(set_attr "prefix_0f" "1")])
14105 ;; Thread-local storage patterns for ELF.
14107 ;; Note that these code sequences must appear exactly as shown
14108 ;; in order to allow linker relaxation.
14110 (define_insn "*tls_global_dynamic_32_gnu"
14111   [(set (match_operand:SI 0 "register_operand" "=a")
14112         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14113                     (match_operand:SI 2 "tls_symbolic_operand" "")
14114                     (match_operand:SI 3 "call_insn_operand" "")]
14115                     UNSPEC_TLS_GD))
14116    (clobber (match_scratch:SI 4 "=d"))
14117    (clobber (match_scratch:SI 5 "=c"))
14118    (clobber (reg:CC FLAGS_REG))]
14119   "!TARGET_64BIT && TARGET_GNU_TLS"
14120   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14121   [(set_attr "type" "multi")
14122    (set_attr "length" "12")])
14124 (define_insn "*tls_global_dynamic_32_sun"
14125   [(set (match_operand:SI 0 "register_operand" "=a")
14126         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14127                     (match_operand:SI 2 "tls_symbolic_operand" "")
14128                     (match_operand:SI 3 "call_insn_operand" "")]
14129                     UNSPEC_TLS_GD))
14130    (clobber (match_scratch:SI 4 "=d"))
14131    (clobber (match_scratch:SI 5 "=c"))
14132    (clobber (reg:CC FLAGS_REG))]
14133   "!TARGET_64BIT && TARGET_SUN_TLS"
14134   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14135         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14136   [(set_attr "type" "multi")
14137    (set_attr "length" "14")])
14139 (define_expand "tls_global_dynamic_32"
14140   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14141                    (unspec:SI
14142                     [(match_dup 2)
14143                      (match_operand:SI 1 "tls_symbolic_operand" "")
14144                      (match_dup 3)]
14145                     UNSPEC_TLS_GD))
14146               (clobber (match_scratch:SI 4 ""))
14147               (clobber (match_scratch:SI 5 ""))
14148               (clobber (reg:CC FLAGS_REG))])]
14149   ""
14151   if (flag_pic)
14152     operands[2] = pic_offset_table_rtx;
14153   else
14154     {
14155       operands[2] = gen_reg_rtx (Pmode);
14156       emit_insn (gen_set_got (operands[2]));
14157     }
14158   operands[3] = ix86_tls_get_addr ();
14161 (define_insn "*tls_global_dynamic_64"
14162   [(set (match_operand:DI 0 "register_operand" "=a")
14163         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14164                  (match_operand:DI 3 "" "")))
14165    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14166               UNSPEC_TLS_GD)]
14167   "TARGET_64BIT"
14168   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14169   [(set_attr "type" "multi")
14170    (set_attr "length" "16")])
14172 (define_expand "tls_global_dynamic_64"
14173   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14174                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14175               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14176                          UNSPEC_TLS_GD)])]
14177   ""
14179   operands[2] = ix86_tls_get_addr ();
14182 (define_insn "*tls_local_dynamic_base_32_gnu"
14183   [(set (match_operand:SI 0 "register_operand" "=a")
14184         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14185                     (match_operand:SI 2 "call_insn_operand" "")]
14186                    UNSPEC_TLS_LD_BASE))
14187    (clobber (match_scratch:SI 3 "=d"))
14188    (clobber (match_scratch:SI 4 "=c"))
14189    (clobber (reg:CC FLAGS_REG))]
14190   "!TARGET_64BIT && TARGET_GNU_TLS"
14191   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14192   [(set_attr "type" "multi")
14193    (set_attr "length" "11")])
14195 (define_insn "*tls_local_dynamic_base_32_sun"
14196   [(set (match_operand:SI 0 "register_operand" "=a")
14197         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14198                     (match_operand:SI 2 "call_insn_operand" "")]
14199                    UNSPEC_TLS_LD_BASE))
14200    (clobber (match_scratch:SI 3 "=d"))
14201    (clobber (match_scratch:SI 4 "=c"))
14202    (clobber (reg:CC FLAGS_REG))]
14203   "!TARGET_64BIT && TARGET_SUN_TLS"
14204   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14205         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14206   [(set_attr "type" "multi")
14207    (set_attr "length" "13")])
14209 (define_expand "tls_local_dynamic_base_32"
14210   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14211                    (unspec:SI [(match_dup 1) (match_dup 2)]
14212                               UNSPEC_TLS_LD_BASE))
14213               (clobber (match_scratch:SI 3 ""))
14214               (clobber (match_scratch:SI 4 ""))
14215               (clobber (reg:CC FLAGS_REG))])]
14216   ""
14218   if (flag_pic)
14219     operands[1] = pic_offset_table_rtx;
14220   else
14221     {
14222       operands[1] = gen_reg_rtx (Pmode);
14223       emit_insn (gen_set_got (operands[1]));
14224     }
14225   operands[2] = ix86_tls_get_addr ();
14228 (define_insn "*tls_local_dynamic_base_64"
14229   [(set (match_operand:DI 0 "register_operand" "=a")
14230         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14231                  (match_operand:DI 2 "" "")))
14232    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14233   "TARGET_64BIT"
14234   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14235   [(set_attr "type" "multi")
14236    (set_attr "length" "12")])
14238 (define_expand "tls_local_dynamic_base_64"
14239   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14240                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14241               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14242   ""
14244   operands[1] = ix86_tls_get_addr ();
14247 ;; Local dynamic of a single variable is a lose.  Show combine how
14248 ;; to convert that back to global dynamic.
14250 (define_insn_and_split "*tls_local_dynamic_32_once"
14251   [(set (match_operand:SI 0 "register_operand" "=a")
14252         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14253                              (match_operand:SI 2 "call_insn_operand" "")]
14254                             UNSPEC_TLS_LD_BASE)
14255                  (const:SI (unspec:SI
14256                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14257                             UNSPEC_DTPOFF))))
14258    (clobber (match_scratch:SI 4 "=d"))
14259    (clobber (match_scratch:SI 5 "=c"))
14260    (clobber (reg:CC FLAGS_REG))]
14261   ""
14262   "#"
14263   ""
14264   [(parallel [(set (match_dup 0)
14265                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14266                               UNSPEC_TLS_GD))
14267               (clobber (match_dup 4))
14268               (clobber (match_dup 5))
14269               (clobber (reg:CC FLAGS_REG))])]
14270   "")
14272 ;; Load and add the thread base pointer from %gs:0.
14274 (define_insn "*load_tp_si"
14275   [(set (match_operand:SI 0 "register_operand" "=r")
14276         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14277   "!TARGET_64BIT"
14278   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14279   [(set_attr "type" "imov")
14280    (set_attr "modrm" "0")
14281    (set_attr "length" "7")
14282    (set_attr "memory" "load")
14283    (set_attr "imm_disp" "false")])
14285 (define_insn "*add_tp_si"
14286   [(set (match_operand:SI 0 "register_operand" "=r")
14287         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14288                  (match_operand:SI 1 "register_operand" "0")))
14289    (clobber (reg:CC FLAGS_REG))]
14290   "!TARGET_64BIT"
14291   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14292   [(set_attr "type" "alu")
14293    (set_attr "modrm" "0")
14294    (set_attr "length" "7")
14295    (set_attr "memory" "load")
14296    (set_attr "imm_disp" "false")])
14298 (define_insn "*load_tp_di"
14299   [(set (match_operand:DI 0 "register_operand" "=r")
14300         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14301   "TARGET_64BIT"
14302   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14303   [(set_attr "type" "imov")
14304    (set_attr "modrm" "0")
14305    (set_attr "length" "7")
14306    (set_attr "memory" "load")
14307    (set_attr "imm_disp" "false")])
14309 (define_insn "*add_tp_di"
14310   [(set (match_operand:DI 0 "register_operand" "=r")
14311         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14312                  (match_operand:DI 1 "register_operand" "0")))
14313    (clobber (reg:CC FLAGS_REG))]
14314   "TARGET_64BIT"
14315   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14316   [(set_attr "type" "alu")
14317    (set_attr "modrm" "0")
14318    (set_attr "length" "7")
14319    (set_attr "memory" "load")
14320    (set_attr "imm_disp" "false")])
14322 ;; These patterns match the binary 387 instructions for addM3, subM3,
14323 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14324 ;; SFmode.  The first is the normal insn, the second the same insn but
14325 ;; with one operand a conversion, and the third the same insn but with
14326 ;; the other operand a conversion.  The conversion may be SFmode or
14327 ;; SImode if the target mode DFmode, but only SImode if the target mode
14328 ;; is SFmode.
14330 ;; Gcc is slightly more smart about handling normal two address instructions
14331 ;; so use special patterns for add and mull.
14333 (define_insn "*fop_sf_comm_mixed"
14334   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14335         (match_operator:SF 3 "binary_fp_operator"
14336                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14337                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14338   "TARGET_MIX_SSE_I387
14339    && COMMUTATIVE_ARITH_P (operands[3])
14340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14341   "* return output_387_binary_op (insn, operands);"
14342   [(set (attr "type") 
14343         (if_then_else (eq_attr "alternative" "1")
14344            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14345               (const_string "ssemul")
14346               (const_string "sseadd"))
14347            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14348               (const_string "fmul")
14349               (const_string "fop"))))
14350    (set_attr "mode" "SF")])
14352 (define_insn "*fop_sf_comm_sse"
14353   [(set (match_operand:SF 0 "register_operand" "=x")
14354         (match_operator:SF 3 "binary_fp_operator"
14355                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14356                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14357   "TARGET_SSE_MATH
14358    && COMMUTATIVE_ARITH_P (operands[3])
14359    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14360   "* return output_387_binary_op (insn, operands);"
14361   [(set (attr "type") 
14362         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14363            (const_string "ssemul")
14364            (const_string "sseadd")))
14365    (set_attr "mode" "SF")])
14367 (define_insn "*fop_sf_comm_i387"
14368   [(set (match_operand:SF 0 "register_operand" "=f")
14369         (match_operator:SF 3 "binary_fp_operator"
14370                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14371                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14372   "TARGET_80387
14373    && COMMUTATIVE_ARITH_P (operands[3])
14374    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14375   "* return output_387_binary_op (insn, operands);"
14376   [(set (attr "type") 
14377         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14378            (const_string "fmul")
14379            (const_string "fop")))
14380    (set_attr "mode" "SF")])
14382 (define_insn "*fop_sf_1_mixed"
14383   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14384         (match_operator:SF 3 "binary_fp_operator"
14385                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14386                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14387   "TARGET_MIX_SSE_I387
14388    && !COMMUTATIVE_ARITH_P (operands[3])
14389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14390   "* return output_387_binary_op (insn, operands);"
14391   [(set (attr "type") 
14392         (cond [(and (eq_attr "alternative" "2")
14393                     (match_operand:SF 3 "mult_operator" ""))
14394                  (const_string "ssemul")
14395                (and (eq_attr "alternative" "2")
14396                     (match_operand:SF 3 "div_operator" ""))
14397                  (const_string "ssediv")
14398                (eq_attr "alternative" "2")
14399                  (const_string "sseadd")
14400                (match_operand:SF 3 "mult_operator" "") 
14401                  (const_string "fmul")
14402                (match_operand:SF 3 "div_operator" "") 
14403                  (const_string "fdiv")
14404               ]
14405               (const_string "fop")))
14406    (set_attr "mode" "SF")])
14408 (define_insn "*fop_sf_1_sse"
14409   [(set (match_operand:SF 0 "register_operand" "=x")
14410         (match_operator:SF 3 "binary_fp_operator"
14411                         [(match_operand:SF 1 "register_operand" "0")
14412                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14413   "TARGET_SSE_MATH
14414    && !COMMUTATIVE_ARITH_P (operands[3])"
14415   "* return output_387_binary_op (insn, operands);"
14416   [(set (attr "type") 
14417         (cond [(match_operand:SF 3 "mult_operator" "")
14418                  (const_string "ssemul")
14419                (match_operand:SF 3 "div_operator" "")
14420                  (const_string "ssediv")
14421               ]
14422               (const_string "sseadd")))
14423    (set_attr "mode" "SF")])
14425 ;; This pattern is not fully shadowed by the pattern above.
14426 (define_insn "*fop_sf_1_i387"
14427   [(set (match_operand:SF 0 "register_operand" "=f,f")
14428         (match_operator:SF 3 "binary_fp_operator"
14429                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14430                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14431   "TARGET_80387 && !TARGET_SSE_MATH
14432    && !COMMUTATIVE_ARITH_P (operands[3])
14433    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434   "* return output_387_binary_op (insn, operands);"
14435   [(set (attr "type") 
14436         (cond [(match_operand:SF 3 "mult_operator" "") 
14437                  (const_string "fmul")
14438                (match_operand:SF 3 "div_operator" "") 
14439                  (const_string "fdiv")
14440               ]
14441               (const_string "fop")))
14442    (set_attr "mode" "SF")])
14444 ;; ??? Add SSE splitters for these!
14445 (define_insn "*fop_sf_2<mode>_i387"
14446   [(set (match_operand:SF 0 "register_operand" "=f,f")
14447         (match_operator:SF 3 "binary_fp_operator"
14448           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14449            (match_operand:SF 2 "register_operand" "0,0")]))]
14450   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14451   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14452   [(set (attr "type") 
14453         (cond [(match_operand:SF 3 "mult_operator" "") 
14454                  (const_string "fmul")
14455                (match_operand:SF 3 "div_operator" "") 
14456                  (const_string "fdiv")
14457               ]
14458               (const_string "fop")))
14459    (set_attr "fp_int_src" "true")
14460    (set_attr "mode" "<MODE>")])
14462 (define_insn "*fop_sf_3<mode>_i387"
14463   [(set (match_operand:SF 0 "register_operand" "=f,f")
14464         (match_operator:SF 3 "binary_fp_operator"
14465           [(match_operand:SF 1 "register_operand" "0,0")
14466            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14467   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14468   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14469   [(set (attr "type") 
14470         (cond [(match_operand:SF 3 "mult_operator" "") 
14471                  (const_string "fmul")
14472                (match_operand:SF 3 "div_operator" "") 
14473                  (const_string "fdiv")
14474               ]
14475               (const_string "fop")))
14476    (set_attr "fp_int_src" "true")
14477    (set_attr "mode" "<MODE>")])
14479 (define_insn "*fop_df_comm_mixed"
14480   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14481         (match_operator:DF 3 "binary_fp_operator"
14482                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14483                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14484   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14485    && COMMUTATIVE_ARITH_P (operands[3])
14486    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14487   "* return output_387_binary_op (insn, operands);"
14488   [(set (attr "type") 
14489         (if_then_else (eq_attr "alternative" "1")
14490            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14491               (const_string "ssemul")
14492               (const_string "sseadd"))
14493            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14494               (const_string "fmul")
14495               (const_string "fop"))))
14496    (set_attr "mode" "DF")])
14498 (define_insn "*fop_df_comm_sse"
14499   [(set (match_operand:DF 0 "register_operand" "=Y")
14500         (match_operator:DF 3 "binary_fp_operator"
14501                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14502                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14503   "TARGET_SSE2 && TARGET_SSE_MATH
14504    && COMMUTATIVE_ARITH_P (operands[3])
14505    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14506   "* return output_387_binary_op (insn, operands);"
14507   [(set (attr "type") 
14508         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14509            (const_string "ssemul")
14510            (const_string "sseadd")))
14511    (set_attr "mode" "DF")])
14513 (define_insn "*fop_df_comm_i387"
14514   [(set (match_operand:DF 0 "register_operand" "=f")
14515         (match_operator:DF 3 "binary_fp_operator"
14516                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14517                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14518   "TARGET_80387
14519    && COMMUTATIVE_ARITH_P (operands[3])
14520    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14521   "* return output_387_binary_op (insn, operands);"
14522   [(set (attr "type") 
14523         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14524            (const_string "fmul")
14525            (const_string "fop")))
14526    (set_attr "mode" "DF")])
14528 (define_insn "*fop_df_1_mixed"
14529   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14530         (match_operator:DF 3 "binary_fp_operator"
14531                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14532                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14533   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14534    && !COMMUTATIVE_ARITH_P (operands[3])
14535    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14536   "* return output_387_binary_op (insn, operands);"
14537   [(set (attr "type") 
14538         (cond [(and (eq_attr "alternative" "2")
14539                     (match_operand:SF 3 "mult_operator" ""))
14540                  (const_string "ssemul")
14541                (and (eq_attr "alternative" "2")
14542                     (match_operand:SF 3 "div_operator" ""))
14543                  (const_string "ssediv")
14544                (eq_attr "alternative" "2")
14545                  (const_string "sseadd")
14546                (match_operand:DF 3 "mult_operator" "") 
14547                  (const_string "fmul")
14548                (match_operand:DF 3 "div_operator" "") 
14549                  (const_string "fdiv")
14550               ]
14551               (const_string "fop")))
14552    (set_attr "mode" "DF")])
14554 (define_insn "*fop_df_1_sse"
14555   [(set (match_operand:DF 0 "register_operand" "=Y")
14556         (match_operator:DF 3 "binary_fp_operator"
14557                         [(match_operand:DF 1 "register_operand" "0")
14558                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14559   "TARGET_SSE2 && TARGET_SSE_MATH
14560    && !COMMUTATIVE_ARITH_P (operands[3])"
14561   "* return output_387_binary_op (insn, operands);"
14562   [(set_attr "mode" "DF")
14563    (set (attr "type") 
14564         (cond [(match_operand:SF 3 "mult_operator" "")
14565                  (const_string "ssemul")
14566                (match_operand:SF 3 "div_operator" "")
14567                  (const_string "ssediv")
14568               ]
14569               (const_string "sseadd")))])
14571 ;; This pattern is not fully shadowed by the pattern above.
14572 (define_insn "*fop_df_1_i387"
14573   [(set (match_operand:DF 0 "register_operand" "=f,f")
14574         (match_operator:DF 3 "binary_fp_operator"
14575                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14576                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14577   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14578    && !COMMUTATIVE_ARITH_P (operands[3])
14579    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14580   "* return output_387_binary_op (insn, operands);"
14581   [(set (attr "type") 
14582         (cond [(match_operand:DF 3 "mult_operator" "") 
14583                  (const_string "fmul")
14584                (match_operand:DF 3 "div_operator" "")
14585                  (const_string "fdiv")
14586               ]
14587               (const_string "fop")))
14588    (set_attr "mode" "DF")])
14590 ;; ??? Add SSE splitters for these!
14591 (define_insn "*fop_df_2<mode>_i387"
14592   [(set (match_operand:DF 0 "register_operand" "=f,f")
14593         (match_operator:DF 3 "binary_fp_operator"
14594            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14595             (match_operand:DF 2 "register_operand" "0,0")]))]
14596   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14597    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14598   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14599   [(set (attr "type") 
14600         (cond [(match_operand:DF 3 "mult_operator" "") 
14601                  (const_string "fmul")
14602                (match_operand:DF 3 "div_operator" "") 
14603                  (const_string "fdiv")
14604               ]
14605               (const_string "fop")))
14606    (set_attr "fp_int_src" "true")
14607    (set_attr "mode" "<MODE>")])
14609 (define_insn "*fop_df_3<mode>_i387"
14610   [(set (match_operand:DF 0 "register_operand" "=f,f")
14611         (match_operator:DF 3 "binary_fp_operator"
14612            [(match_operand:DF 1 "register_operand" "0,0")
14613             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14614   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14615    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14616   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14617   [(set (attr "type") 
14618         (cond [(match_operand:DF 3 "mult_operator" "") 
14619                  (const_string "fmul")
14620                (match_operand:DF 3 "div_operator" "") 
14621                  (const_string "fdiv")
14622               ]
14623               (const_string "fop")))
14624    (set_attr "fp_int_src" "true")
14625    (set_attr "mode" "<MODE>")])
14627 (define_insn "*fop_df_4_i387"
14628   [(set (match_operand:DF 0 "register_operand" "=f,f")
14629         (match_operator:DF 3 "binary_fp_operator"
14630            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14631             (match_operand:DF 2 "register_operand" "0,f")]))]
14632   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14633    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14634   "* return output_387_binary_op (insn, operands);"
14635   [(set (attr "type") 
14636         (cond [(match_operand:DF 3 "mult_operator" "") 
14637                  (const_string "fmul")
14638                (match_operand:DF 3 "div_operator" "") 
14639                  (const_string "fdiv")
14640               ]
14641               (const_string "fop")))
14642    (set_attr "mode" "SF")])
14644 (define_insn "*fop_df_5_i387"
14645   [(set (match_operand:DF 0 "register_operand" "=f,f")
14646         (match_operator:DF 3 "binary_fp_operator"
14647           [(match_operand:DF 1 "register_operand" "0,f")
14648            (float_extend:DF
14649             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14650   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14651   "* return output_387_binary_op (insn, operands);"
14652   [(set (attr "type") 
14653         (cond [(match_operand:DF 3 "mult_operator" "") 
14654                  (const_string "fmul")
14655                (match_operand:DF 3 "div_operator" "") 
14656                  (const_string "fdiv")
14657               ]
14658               (const_string "fop")))
14659    (set_attr "mode" "SF")])
14661 (define_insn "*fop_df_6_i387"
14662   [(set (match_operand:DF 0 "register_operand" "=f,f")
14663         (match_operator:DF 3 "binary_fp_operator"
14664           [(float_extend:DF
14665             (match_operand:SF 1 "register_operand" "0,f"))
14666            (float_extend:DF
14667             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14668   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14669   "* return output_387_binary_op (insn, operands);"
14670   [(set (attr "type") 
14671         (cond [(match_operand:DF 3 "mult_operator" "") 
14672                  (const_string "fmul")
14673                (match_operand:DF 3 "div_operator" "") 
14674                  (const_string "fdiv")
14675               ]
14676               (const_string "fop")))
14677    (set_attr "mode" "SF")])
14679 (define_insn "*fop_xf_comm_i387"
14680   [(set (match_operand:XF 0 "register_operand" "=f")
14681         (match_operator:XF 3 "binary_fp_operator"
14682                         [(match_operand:XF 1 "register_operand" "%0")
14683                          (match_operand:XF 2 "register_operand" "f")]))]
14684   "TARGET_80387
14685    && COMMUTATIVE_ARITH_P (operands[3])"
14686   "* return output_387_binary_op (insn, operands);"
14687   [(set (attr "type") 
14688         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14689            (const_string "fmul")
14690            (const_string "fop")))
14691    (set_attr "mode" "XF")])
14693 (define_insn "*fop_xf_1_i387"
14694   [(set (match_operand:XF 0 "register_operand" "=f,f")
14695         (match_operator:XF 3 "binary_fp_operator"
14696                         [(match_operand:XF 1 "register_operand" "0,f")
14697                          (match_operand:XF 2 "register_operand" "f,0")]))]
14698   "TARGET_80387
14699    && !COMMUTATIVE_ARITH_P (operands[3])"
14700   "* return output_387_binary_op (insn, operands);"
14701   [(set (attr "type") 
14702         (cond [(match_operand:XF 3 "mult_operator" "") 
14703                  (const_string "fmul")
14704                (match_operand:XF 3 "div_operator" "") 
14705                  (const_string "fdiv")
14706               ]
14707               (const_string "fop")))
14708    (set_attr "mode" "XF")])
14710 (define_insn "*fop_xf_2<mode>_i387"
14711   [(set (match_operand:XF 0 "register_operand" "=f,f")
14712         (match_operator:XF 3 "binary_fp_operator"
14713            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14714             (match_operand:XF 2 "register_operand" "0,0")]))]
14715   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14716   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14717   [(set (attr "type") 
14718         (cond [(match_operand:XF 3 "mult_operator" "") 
14719                  (const_string "fmul")
14720                (match_operand:XF 3 "div_operator" "") 
14721                  (const_string "fdiv")
14722               ]
14723               (const_string "fop")))
14724    (set_attr "fp_int_src" "true")
14725    (set_attr "mode" "<MODE>")])
14727 (define_insn "*fop_xf_3<mode>_i387"
14728   [(set (match_operand:XF 0 "register_operand" "=f,f")
14729         (match_operator:XF 3 "binary_fp_operator"
14730           [(match_operand:XF 1 "register_operand" "0,0")
14731            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14732   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14733   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14734   [(set (attr "type") 
14735         (cond [(match_operand:XF 3 "mult_operator" "") 
14736                  (const_string "fmul")
14737                (match_operand:XF 3 "div_operator" "") 
14738                  (const_string "fdiv")
14739               ]
14740               (const_string "fop")))
14741    (set_attr "fp_int_src" "true")
14742    (set_attr "mode" "<MODE>")])
14744 (define_insn "*fop_xf_4_i387"
14745   [(set (match_operand:XF 0 "register_operand" "=f,f")
14746         (match_operator:XF 3 "binary_fp_operator"
14747            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14748             (match_operand:XF 2 "register_operand" "0,f")]))]
14749   "TARGET_80387"
14750   "* return output_387_binary_op (insn, operands);"
14751   [(set (attr "type") 
14752         (cond [(match_operand:XF 3 "mult_operator" "") 
14753                  (const_string "fmul")
14754                (match_operand:XF 3 "div_operator" "") 
14755                  (const_string "fdiv")
14756               ]
14757               (const_string "fop")))
14758    (set_attr "mode" "SF")])
14760 (define_insn "*fop_xf_5_i387"
14761   [(set (match_operand:XF 0 "register_operand" "=f,f")
14762         (match_operator:XF 3 "binary_fp_operator"
14763           [(match_operand:XF 1 "register_operand" "0,f")
14764            (float_extend:XF
14765             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14766   "TARGET_80387"
14767   "* return output_387_binary_op (insn, operands);"
14768   [(set (attr "type") 
14769         (cond [(match_operand:XF 3 "mult_operator" "") 
14770                  (const_string "fmul")
14771                (match_operand:XF 3 "div_operator" "") 
14772                  (const_string "fdiv")
14773               ]
14774               (const_string "fop")))
14775    (set_attr "mode" "SF")])
14777 (define_insn "*fop_xf_6_i387"
14778   [(set (match_operand:XF 0 "register_operand" "=f,f")
14779         (match_operator:XF 3 "binary_fp_operator"
14780           [(float_extend:XF
14781             (match_operand 1 "register_operand" "0,f"))
14782            (float_extend:XF
14783             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14784   "TARGET_80387"
14785   "* return output_387_binary_op (insn, operands);"
14786   [(set (attr "type") 
14787         (cond [(match_operand:XF 3 "mult_operator" "") 
14788                  (const_string "fmul")
14789                (match_operand:XF 3 "div_operator" "") 
14790                  (const_string "fdiv")
14791               ]
14792               (const_string "fop")))
14793    (set_attr "mode" "SF")])
14795 (define_split
14796   [(set (match_operand 0 "register_operand" "")
14797         (match_operator 3 "binary_fp_operator"
14798            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14799             (match_operand 2 "register_operand" "")]))]
14800   "TARGET_80387 && reload_completed
14801    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14802   [(const_int 0)]
14804   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14805   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14806   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14807                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14808                                           GET_MODE (operands[3]),
14809                                           operands[4],
14810                                           operands[2])));
14811   ix86_free_from_memory (GET_MODE (operands[1]));
14812   DONE;
14815 (define_split
14816   [(set (match_operand 0 "register_operand" "")
14817         (match_operator 3 "binary_fp_operator"
14818            [(match_operand 1 "register_operand" "")
14819             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14820   "TARGET_80387 && reload_completed
14821    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14822   [(const_int 0)]
14824   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14825   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14826   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14827                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14828                                           GET_MODE (operands[3]),
14829                                           operands[1],
14830                                           operands[4])));
14831   ix86_free_from_memory (GET_MODE (operands[2]));
14832   DONE;
14835 ;; FPU special functions.
14837 (define_expand "sqrtsf2"
14838   [(set (match_operand:SF 0 "register_operand" "")
14839         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14840   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14842   if (!TARGET_SSE_MATH)
14843     operands[1] = force_reg (SFmode, operands[1]);
14846 (define_insn "*sqrtsf2_mixed"
14847   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14848         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14849   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14850   "@
14851    fsqrt
14852    sqrtss\t{%1, %0|%0, %1}"
14853   [(set_attr "type" "fpspc,sse")
14854    (set_attr "mode" "SF,SF")
14855    (set_attr "athlon_decode" "direct,*")])
14857 (define_insn "*sqrtsf2_sse"
14858   [(set (match_operand:SF 0 "register_operand" "=x")
14859         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14860   "TARGET_SSE_MATH"
14861   "sqrtss\t{%1, %0|%0, %1}"
14862   [(set_attr "type" "sse")
14863    (set_attr "mode" "SF")
14864    (set_attr "athlon_decode" "*")])
14866 (define_insn "*sqrtsf2_i387"
14867   [(set (match_operand:SF 0 "register_operand" "=f")
14868         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14869   "TARGET_USE_FANCY_MATH_387"
14870   "fsqrt"
14871   [(set_attr "type" "fpspc")
14872    (set_attr "mode" "SF")
14873    (set_attr "athlon_decode" "direct")])
14875 (define_expand "sqrtdf2"
14876   [(set (match_operand:DF 0 "register_operand" "")
14877         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14878   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14880   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14881     operands[1] = force_reg (DFmode, operands[1]);
14884 (define_insn "*sqrtdf2_mixed"
14885   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14886         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14887   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14888   "@
14889    fsqrt
14890    sqrtsd\t{%1, %0|%0, %1}"
14891   [(set_attr "type" "fpspc,sse")
14892    (set_attr "mode" "DF,DF")
14893    (set_attr "athlon_decode" "direct,*")])
14895 (define_insn "*sqrtdf2_sse"
14896   [(set (match_operand:DF 0 "register_operand" "=Y")
14897         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14898   "TARGET_SSE2 && TARGET_SSE_MATH"
14899   "sqrtsd\t{%1, %0|%0, %1}"
14900   [(set_attr "type" "sse")
14901    (set_attr "mode" "DF")
14902    (set_attr "athlon_decode" "*")])
14904 (define_insn "*sqrtdf2_i387"
14905   [(set (match_operand:DF 0 "register_operand" "=f")
14906         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14907   "TARGET_USE_FANCY_MATH_387"
14908   "fsqrt"
14909   [(set_attr "type" "fpspc")
14910    (set_attr "mode" "DF")
14911    (set_attr "athlon_decode" "direct")])
14913 (define_insn "*sqrtextendsfdf2_i387"
14914   [(set (match_operand:DF 0 "register_operand" "=f")
14915         (sqrt:DF (float_extend:DF
14916                   (match_operand:SF 1 "register_operand" "0"))))]
14917   "TARGET_USE_FANCY_MATH_387
14918    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14919   "fsqrt"
14920   [(set_attr "type" "fpspc")
14921    (set_attr "mode" "DF")
14922    (set_attr "athlon_decode" "direct")])
14924 (define_insn "sqrtxf2"
14925   [(set (match_operand:XF 0 "register_operand" "=f")
14926         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14927   "TARGET_USE_FANCY_MATH_387 
14928    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14929   "fsqrt"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "mode" "XF")
14932    (set_attr "athlon_decode" "direct")])
14934 (define_insn "*sqrtextendsfxf2_i387"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (sqrt:XF (float_extend:XF
14937                   (match_operand:SF 1 "register_operand" "0"))))]
14938   "TARGET_USE_FANCY_MATH_387"
14939   "fsqrt"
14940   [(set_attr "type" "fpspc")
14941    (set_attr "mode" "XF")
14942    (set_attr "athlon_decode" "direct")])
14944 (define_insn "*sqrtextenddfxf2_i387"
14945   [(set (match_operand:XF 0 "register_operand" "=f")
14946         (sqrt:XF (float_extend:XF
14947                   (match_operand:DF 1 "register_operand" "0"))))]
14948   "TARGET_USE_FANCY_MATH_387"
14949   "fsqrt"
14950   [(set_attr "type" "fpspc")
14951    (set_attr "mode" "XF")
14952    (set_attr "athlon_decode" "direct")])
14954 (define_insn "fpremxf4"
14955   [(set (match_operand:XF 0 "register_operand" "=f")
14956         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14957                     (match_operand:XF 3 "register_operand" "1")]
14958                    UNSPEC_FPREM_F))
14959    (set (match_operand:XF 1 "register_operand" "=u")
14960         (unspec:XF [(match_dup 2) (match_dup 3)]
14961                    UNSPEC_FPREM_U))
14962    (set (reg:CCFP FPSR_REG)
14963         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14964   "TARGET_USE_FANCY_MATH_387
14965    && flag_unsafe_math_optimizations"
14966   "fprem"
14967   [(set_attr "type" "fpspc")
14968    (set_attr "mode" "XF")])
14970 (define_expand "fmodsf3"
14971   [(use (match_operand:SF 0 "register_operand" ""))
14972    (use (match_operand:SF 1 "register_operand" ""))
14973    (use (match_operand:SF 2 "register_operand" ""))]
14974   "TARGET_USE_FANCY_MATH_387
14975    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14976    && flag_unsafe_math_optimizations"
14978   rtx label = gen_label_rtx ();
14980   rtx op1 = gen_reg_rtx (XFmode);
14981   rtx op2 = gen_reg_rtx (XFmode);
14983   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14984   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14986   emit_label (label);
14988   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14989   ix86_emit_fp_unordered_jump (label);
14991   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14992   DONE;
14995 (define_expand "fmoddf3"
14996   [(use (match_operand:DF 0 "register_operand" ""))
14997    (use (match_operand:DF 1 "register_operand" ""))
14998    (use (match_operand:DF 2 "register_operand" ""))]
14999   "TARGET_USE_FANCY_MATH_387
15000    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15001    && flag_unsafe_math_optimizations"
15003   rtx label = gen_label_rtx ();
15005   rtx op1 = gen_reg_rtx (XFmode);
15006   rtx op2 = gen_reg_rtx (XFmode);
15008   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15009   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15011   emit_label (label);
15013   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15014   ix86_emit_fp_unordered_jump (label);
15016   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15017   DONE;
15020 (define_expand "fmodxf3"
15021   [(use (match_operand:XF 0 "register_operand" ""))
15022    (use (match_operand:XF 1 "register_operand" ""))
15023    (use (match_operand:XF 2 "register_operand" ""))]
15024   "TARGET_USE_FANCY_MATH_387
15025    && flag_unsafe_math_optimizations"
15027   rtx label = gen_label_rtx ();
15029   emit_label (label);
15031   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15032                            operands[1], operands[2]));
15033   ix86_emit_fp_unordered_jump (label);
15035   emit_move_insn (operands[0], operands[1]);
15036   DONE;
15039 (define_insn "fprem1xf4"
15040   [(set (match_operand:XF 0 "register_operand" "=f")
15041         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15042                     (match_operand:XF 3 "register_operand" "1")]
15043                    UNSPEC_FPREM1_F))
15044    (set (match_operand:XF 1 "register_operand" "=u")
15045         (unspec:XF [(match_dup 2) (match_dup 3)]
15046                    UNSPEC_FPREM1_U))
15047    (set (reg:CCFP FPSR_REG)
15048         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15049   "TARGET_USE_FANCY_MATH_387
15050    && flag_unsafe_math_optimizations"
15051   "fprem1"
15052   [(set_attr "type" "fpspc")
15053    (set_attr "mode" "XF")])
15055 (define_expand "dremsf3"
15056   [(use (match_operand:SF 0 "register_operand" ""))
15057    (use (match_operand:SF 1 "register_operand" ""))
15058    (use (match_operand:SF 2 "register_operand" ""))]
15059   "TARGET_USE_FANCY_MATH_387
15060    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15061    && flag_unsafe_math_optimizations"
15063   rtx label = gen_label_rtx ();
15065   rtx op1 = gen_reg_rtx (XFmode);
15066   rtx op2 = gen_reg_rtx (XFmode);
15068   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15069   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15071   emit_label (label);
15073   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15074   ix86_emit_fp_unordered_jump (label);
15076   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15077   DONE;
15080 (define_expand "dremdf3"
15081   [(use (match_operand:DF 0 "register_operand" ""))
15082    (use (match_operand:DF 1 "register_operand" ""))
15083    (use (match_operand:DF 2 "register_operand" ""))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15086    && flag_unsafe_math_optimizations"
15088   rtx label = gen_label_rtx ();
15090   rtx op1 = gen_reg_rtx (XFmode);
15091   rtx op2 = gen_reg_rtx (XFmode);
15093   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15094   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15096   emit_label (label);
15098   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15099   ix86_emit_fp_unordered_jump (label);
15101   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15102   DONE;
15105 (define_expand "dremxf3"
15106   [(use (match_operand:XF 0 "register_operand" ""))
15107    (use (match_operand:XF 1 "register_operand" ""))
15108    (use (match_operand:XF 2 "register_operand" ""))]
15109   "TARGET_USE_FANCY_MATH_387
15110    && flag_unsafe_math_optimizations"
15112   rtx label = gen_label_rtx ();
15114   emit_label (label);
15116   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15117                             operands[1], operands[2]));
15118   ix86_emit_fp_unordered_jump (label);
15120   emit_move_insn (operands[0], operands[1]);
15121   DONE;
15124 (define_insn "*sindf2"
15125   [(set (match_operand:DF 0 "register_operand" "=f")
15126         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15127   "TARGET_USE_FANCY_MATH_387
15128    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15129    && flag_unsafe_math_optimizations"
15130   "fsin"
15131   [(set_attr "type" "fpspc")
15132    (set_attr "mode" "DF")])
15134 (define_insn "*sinsf2"
15135   [(set (match_operand:SF 0 "register_operand" "=f")
15136         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15137   "TARGET_USE_FANCY_MATH_387
15138    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15139    && flag_unsafe_math_optimizations"
15140   "fsin"
15141   [(set_attr "type" "fpspc")
15142    (set_attr "mode" "SF")])
15144 (define_insn "*sinextendsfdf2"
15145   [(set (match_operand:DF 0 "register_operand" "=f")
15146         (unspec:DF [(float_extend:DF
15147                      (match_operand:SF 1 "register_operand" "0"))]
15148                    UNSPEC_SIN))]
15149   "TARGET_USE_FANCY_MATH_387
15150    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15151    && flag_unsafe_math_optimizations"
15152   "fsin"
15153   [(set_attr "type" "fpspc")
15154    (set_attr "mode" "DF")])
15156 (define_insn "*sinxf2"
15157   [(set (match_operand:XF 0 "register_operand" "=f")
15158         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15159   "TARGET_USE_FANCY_MATH_387
15160    && flag_unsafe_math_optimizations"
15161   "fsin"
15162   [(set_attr "type" "fpspc")
15163    (set_attr "mode" "XF")])
15165 (define_insn "*cosdf2"
15166   [(set (match_operand:DF 0 "register_operand" "=f")
15167         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15170    && flag_unsafe_math_optimizations"
15171   "fcos"
15172   [(set_attr "type" "fpspc")
15173    (set_attr "mode" "DF")])
15175 (define_insn "*cossf2"
15176   [(set (match_operand:SF 0 "register_operand" "=f")
15177         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15178   "TARGET_USE_FANCY_MATH_387
15179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180    && flag_unsafe_math_optimizations"
15181   "fcos"
15182   [(set_attr "type" "fpspc")
15183    (set_attr "mode" "SF")])
15185 (define_insn "*cosextendsfdf2"
15186   [(set (match_operand:DF 0 "register_operand" "=f")
15187         (unspec:DF [(float_extend:DF
15188                      (match_operand:SF 1 "register_operand" "0"))]
15189                    UNSPEC_COS))]
15190   "TARGET_USE_FANCY_MATH_387
15191    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15192    && flag_unsafe_math_optimizations"
15193   "fcos"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "DF")])
15197 (define_insn "*cosxf2"
15198   [(set (match_operand:XF 0 "register_operand" "=f")
15199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15200   "TARGET_USE_FANCY_MATH_387
15201    && flag_unsafe_math_optimizations"
15202   "fcos"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "mode" "XF")])
15206 ;; With sincos pattern defined, sin and cos builtin function will be
15207 ;; expanded to sincos pattern with one of its outputs left unused. 
15208 ;; Cse pass  will detected, if two sincos patterns can be combined,
15209 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15210 ;; depending on the unused output.
15212 (define_insn "sincosdf3"
15213   [(set (match_operand:DF 0 "register_operand" "=f")
15214         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15215                    UNSPEC_SINCOS_COS))
15216    (set (match_operand:DF 1 "register_operand" "=u")
15217         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15218   "TARGET_USE_FANCY_MATH_387
15219    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15220    && flag_unsafe_math_optimizations"
15221   "fsincos"
15222   [(set_attr "type" "fpspc")
15223    (set_attr "mode" "DF")])
15225 (define_split
15226   [(set (match_operand:DF 0 "register_operand" "")
15227         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15228                    UNSPEC_SINCOS_COS))
15229    (set (match_operand:DF 1 "register_operand" "")
15230         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15231   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15232    && !reload_completed && !reload_in_progress"
15233   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15234   "")
15236 (define_split
15237   [(set (match_operand:DF 0 "register_operand" "")
15238         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15239                    UNSPEC_SINCOS_COS))
15240    (set (match_operand:DF 1 "register_operand" "")
15241         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15243    && !reload_completed && !reload_in_progress"
15244   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15245   "")
15247 (define_insn "sincossf3"
15248   [(set (match_operand:SF 0 "register_operand" "=f")
15249         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15250                    UNSPEC_SINCOS_COS))
15251    (set (match_operand:SF 1 "register_operand" "=u")
15252         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15253   "TARGET_USE_FANCY_MATH_387
15254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15255    && flag_unsafe_math_optimizations"
15256   "fsincos"
15257   [(set_attr "type" "fpspc")
15258    (set_attr "mode" "SF")])
15260 (define_split
15261   [(set (match_operand:SF 0 "register_operand" "")
15262         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15263                    UNSPEC_SINCOS_COS))
15264    (set (match_operand:SF 1 "register_operand" "")
15265         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15266   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15267    && !reload_completed && !reload_in_progress"
15268   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15269   "")
15271 (define_split
15272   [(set (match_operand:SF 0 "register_operand" "")
15273         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15274                    UNSPEC_SINCOS_COS))
15275    (set (match_operand:SF 1 "register_operand" "")
15276         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15277   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15278    && !reload_completed && !reload_in_progress"
15279   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15280   "")
15282 (define_insn "*sincosextendsfdf3"
15283   [(set (match_operand:DF 0 "register_operand" "=f")
15284         (unspec:DF [(float_extend:DF
15285                      (match_operand:SF 2 "register_operand" "0"))]
15286                    UNSPEC_SINCOS_COS))
15287    (set (match_operand:DF 1 "register_operand" "=u")
15288         (unspec:DF [(float_extend:DF
15289                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15290   "TARGET_USE_FANCY_MATH_387
15291    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15292    && flag_unsafe_math_optimizations"
15293   "fsincos"
15294   [(set_attr "type" "fpspc")
15295    (set_attr "mode" "DF")])
15297 (define_split
15298   [(set (match_operand:DF 0 "register_operand" "")
15299         (unspec:DF [(float_extend:DF
15300                      (match_operand:SF 2 "register_operand" ""))]
15301                    UNSPEC_SINCOS_COS))
15302    (set (match_operand:DF 1 "register_operand" "")
15303         (unspec:DF [(float_extend:DF
15304                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15305   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15306    && !reload_completed && !reload_in_progress"
15307   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15308                                    (match_dup 2))] UNSPEC_SIN))]
15309   "")
15311 (define_split
15312   [(set (match_operand:DF 0 "register_operand" "")
15313         (unspec:DF [(float_extend:DF
15314                      (match_operand:SF 2 "register_operand" ""))]
15315                    UNSPEC_SINCOS_COS))
15316    (set (match_operand:DF 1 "register_operand" "")
15317         (unspec:DF [(float_extend:DF
15318                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15319   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15320    && !reload_completed && !reload_in_progress"
15321   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15322                                    (match_dup 2))] UNSPEC_COS))]
15323   "")
15325 (define_insn "sincosxf3"
15326   [(set (match_operand:XF 0 "register_operand" "=f")
15327         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15328                    UNSPEC_SINCOS_COS))
15329    (set (match_operand:XF 1 "register_operand" "=u")
15330         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && flag_unsafe_math_optimizations"
15333   "fsincos"
15334   [(set_attr "type" "fpspc")
15335    (set_attr "mode" "XF")])
15337 (define_split
15338   [(set (match_operand:XF 0 "register_operand" "")
15339         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15340                    UNSPEC_SINCOS_COS))
15341    (set (match_operand:XF 1 "register_operand" "")
15342         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15343   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15344    && !reload_completed && !reload_in_progress"
15345   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15346   "")
15348 (define_split
15349   [(set (match_operand:XF 0 "register_operand" "")
15350         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15351                    UNSPEC_SINCOS_COS))
15352    (set (match_operand:XF 1 "register_operand" "")
15353         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15354   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15355    && !reload_completed && !reload_in_progress"
15356   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15357   "")
15359 (define_insn "*tandf3_1"
15360   [(set (match_operand:DF 0 "register_operand" "=f")
15361         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15362                    UNSPEC_TAN_ONE))
15363    (set (match_operand:DF 1 "register_operand" "=u")
15364         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15365   "TARGET_USE_FANCY_MATH_387
15366    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15367    && flag_unsafe_math_optimizations"
15368   "fptan"
15369   [(set_attr "type" "fpspc")
15370    (set_attr "mode" "DF")])
15372 ;; optimize sequence: fptan
15373 ;;                    fstp    %st(0)
15374 ;;                    fld1
15375 ;; into fptan insn.
15377 (define_peephole2
15378   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15379                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15380                              UNSPEC_TAN_ONE))
15381              (set (match_operand:DF 1 "register_operand" "")
15382                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15383    (set (match_dup 0)
15384         (match_operand:DF 3 "immediate_operand" ""))]
15385   "standard_80387_constant_p (operands[3]) == 2"
15386   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15387              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15388   "")
15390 (define_expand "tandf2"
15391   [(parallel [(set (match_dup 2)
15392                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15393                               UNSPEC_TAN_ONE))
15394               (set (match_operand:DF 0 "register_operand" "")
15395                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15396   "TARGET_USE_FANCY_MATH_387
15397    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15398    && flag_unsafe_math_optimizations"
15400   operands[2] = gen_reg_rtx (DFmode);
15403 (define_insn "*tansf3_1"
15404   [(set (match_operand:SF 0 "register_operand" "=f")
15405         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15406                    UNSPEC_TAN_ONE))
15407    (set (match_operand:SF 1 "register_operand" "=u")
15408         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15409   "TARGET_USE_FANCY_MATH_387
15410    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15411    && flag_unsafe_math_optimizations"
15412   "fptan"
15413   [(set_attr "type" "fpspc")
15414    (set_attr "mode" "SF")])
15416 ;; optimize sequence: fptan
15417 ;;                    fstp    %st(0)
15418 ;;                    fld1
15419 ;; into fptan insn.
15421 (define_peephole2
15422   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15423                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15424                              UNSPEC_TAN_ONE))
15425              (set (match_operand:SF 1 "register_operand" "")
15426                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15427    (set (match_dup 0)
15428         (match_operand:SF 3 "immediate_operand" ""))]
15429   "standard_80387_constant_p (operands[3]) == 2"
15430   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15431              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15432   "")
15434 (define_expand "tansf2"
15435   [(parallel [(set (match_dup 2)
15436                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15437                               UNSPEC_TAN_ONE))
15438               (set (match_operand:SF 0 "register_operand" "")
15439                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15440   "TARGET_USE_FANCY_MATH_387
15441    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15442    && flag_unsafe_math_optimizations"
15444   operands[2] = gen_reg_rtx (SFmode);
15447 (define_insn "*tanxf3_1"
15448   [(set (match_operand:XF 0 "register_operand" "=f")
15449         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15450                    UNSPEC_TAN_ONE))
15451    (set (match_operand:XF 1 "register_operand" "=u")
15452         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15453   "TARGET_USE_FANCY_MATH_387
15454    && flag_unsafe_math_optimizations"
15455   "fptan"
15456   [(set_attr "type" "fpspc")
15457    (set_attr "mode" "XF")])
15459 ;; optimize sequence: fptan
15460 ;;                    fstp    %st(0)
15461 ;;                    fld1
15462 ;; into fptan insn.
15464 (define_peephole2
15465   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15466                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15467                              UNSPEC_TAN_ONE))
15468              (set (match_operand:XF 1 "register_operand" "")
15469                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15470    (set (match_dup 0)
15471         (match_operand:XF 3 "immediate_operand" ""))]
15472   "standard_80387_constant_p (operands[3]) == 2"
15473   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15474              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15475   "")
15477 (define_expand "tanxf2"
15478   [(parallel [(set (match_dup 2)
15479                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15480                               UNSPEC_TAN_ONE))
15481               (set (match_operand:XF 0 "register_operand" "")
15482                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15483   "TARGET_USE_FANCY_MATH_387
15484    && flag_unsafe_math_optimizations"
15486   operands[2] = gen_reg_rtx (XFmode);
15489 (define_insn "atan2df3_1"
15490   [(set (match_operand:DF 0 "register_operand" "=f")
15491         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15492                     (match_operand:DF 1 "register_operand" "u")]
15493                    UNSPEC_FPATAN))
15494    (clobber (match_scratch:DF 3 "=1"))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15497    && flag_unsafe_math_optimizations"
15498   "fpatan"
15499   [(set_attr "type" "fpspc")
15500    (set_attr "mode" "DF")])
15502 (define_expand "atan2df3"
15503   [(use (match_operand:DF 0 "register_operand" ""))
15504    (use (match_operand:DF 2 "register_operand" ""))
15505    (use (match_operand:DF 1 "register_operand" ""))]
15506   "TARGET_USE_FANCY_MATH_387
15507    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15508    && flag_unsafe_math_optimizations"
15510   rtx copy = gen_reg_rtx (DFmode);
15511   emit_move_insn (copy, operands[1]);
15512   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15513   DONE;
15516 (define_expand "atandf2"
15517   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15518                    (unspec:DF [(match_dup 2)
15519                                (match_operand:DF 1 "register_operand" "")]
15520                     UNSPEC_FPATAN))
15521               (clobber (match_scratch:DF 3 ""))])]
15522   "TARGET_USE_FANCY_MATH_387
15523    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15524    && flag_unsafe_math_optimizations"
15526   operands[2] = gen_reg_rtx (DFmode);
15527   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15530 (define_insn "atan2sf3_1"
15531   [(set (match_operand:SF 0 "register_operand" "=f")
15532         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15533                     (match_operand:SF 1 "register_operand" "u")]
15534                    UNSPEC_FPATAN))
15535    (clobber (match_scratch:SF 3 "=1"))]
15536   "TARGET_USE_FANCY_MATH_387
15537    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15538    && flag_unsafe_math_optimizations"
15539   "fpatan"
15540   [(set_attr "type" "fpspc")
15541    (set_attr "mode" "SF")])
15543 (define_expand "atan2sf3"
15544   [(use (match_operand:SF 0 "register_operand" ""))
15545    (use (match_operand:SF 2 "register_operand" ""))
15546    (use (match_operand:SF 1 "register_operand" ""))]
15547   "TARGET_USE_FANCY_MATH_387
15548    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15549    && flag_unsafe_math_optimizations"
15551   rtx copy = gen_reg_rtx (SFmode);
15552   emit_move_insn (copy, operands[1]);
15553   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15554   DONE;
15557 (define_expand "atansf2"
15558   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15559                    (unspec:SF [(match_dup 2)
15560                                (match_operand:SF 1 "register_operand" "")]
15561                     UNSPEC_FPATAN))
15562               (clobber (match_scratch:SF 3 ""))])]
15563   "TARGET_USE_FANCY_MATH_387
15564    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15565    && flag_unsafe_math_optimizations"
15567   operands[2] = gen_reg_rtx (SFmode);
15568   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15571 (define_insn "atan2xf3_1"
15572   [(set (match_operand:XF 0 "register_operand" "=f")
15573         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15574                     (match_operand:XF 1 "register_operand" "u")]
15575                    UNSPEC_FPATAN))
15576    (clobber (match_scratch:XF 3 "=1"))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && flag_unsafe_math_optimizations"
15579   "fpatan"
15580   [(set_attr "type" "fpspc")
15581    (set_attr "mode" "XF")])
15583 (define_expand "atan2xf3"
15584   [(use (match_operand:XF 0 "register_operand" ""))
15585    (use (match_operand:XF 2 "register_operand" ""))
15586    (use (match_operand:XF 1 "register_operand" ""))]
15587   "TARGET_USE_FANCY_MATH_387
15588    && flag_unsafe_math_optimizations"
15590   rtx copy = gen_reg_rtx (XFmode);
15591   emit_move_insn (copy, operands[1]);
15592   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15593   DONE;
15596 (define_expand "atanxf2"
15597   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15598                    (unspec:XF [(match_dup 2)
15599                                (match_operand:XF 1 "register_operand" "")]
15600                     UNSPEC_FPATAN))
15601               (clobber (match_scratch:XF 3 ""))])]
15602   "TARGET_USE_FANCY_MATH_387
15603    && flag_unsafe_math_optimizations"
15605   operands[2] = gen_reg_rtx (XFmode);
15606   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15609 (define_expand "asindf2"
15610   [(set (match_dup 2)
15611         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15612    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15613    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15614    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15615    (parallel [(set (match_dup 7)
15616                    (unspec:XF [(match_dup 6) (match_dup 2)]
15617                               UNSPEC_FPATAN))
15618               (clobber (match_scratch:XF 8 ""))])
15619    (set (match_operand:DF 0 "register_operand" "")
15620         (float_truncate:DF (match_dup 7)))]
15621   "TARGET_USE_FANCY_MATH_387
15622    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15623    && flag_unsafe_math_optimizations"
15625   int i;
15627   for (i=2; i<8; i++)
15628     operands[i] = gen_reg_rtx (XFmode);
15630   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15633 (define_expand "asinsf2"
15634   [(set (match_dup 2)
15635         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15636    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15637    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15638    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15639    (parallel [(set (match_dup 7)
15640                    (unspec:XF [(match_dup 6) (match_dup 2)]
15641                               UNSPEC_FPATAN))
15642               (clobber (match_scratch:XF 8 ""))])
15643    (set (match_operand:SF 0 "register_operand" "")
15644         (float_truncate:SF (match_dup 7)))]
15645   "TARGET_USE_FANCY_MATH_387
15646    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15647    && flag_unsafe_math_optimizations"
15649   int i;
15651   for (i=2; i<8; i++)
15652     operands[i] = gen_reg_rtx (XFmode);
15654   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15657 (define_expand "asinxf2"
15658   [(set (match_dup 2)
15659         (mult:XF (match_operand:XF 1 "register_operand" "")
15660                  (match_dup 1)))
15661    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15662    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15663    (parallel [(set (match_operand:XF 0 "register_operand" "")
15664                    (unspec:XF [(match_dup 5) (match_dup 1)]
15665                               UNSPEC_FPATAN))
15666               (clobber (match_scratch:XF 6 ""))])]
15667   "TARGET_USE_FANCY_MATH_387
15668    && flag_unsafe_math_optimizations"
15670   int i;
15672   for (i=2; i<6; i++)
15673     operands[i] = gen_reg_rtx (XFmode);
15675   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15678 (define_expand "acosdf2"
15679   [(set (match_dup 2)
15680         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15681    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15682    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15683    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15684    (parallel [(set (match_dup 7)
15685                    (unspec:XF [(match_dup 2) (match_dup 6)]
15686                               UNSPEC_FPATAN))
15687               (clobber (match_scratch:XF 8 ""))])
15688    (set (match_operand:DF 0 "register_operand" "")
15689         (float_truncate:DF (match_dup 7)))]
15690   "TARGET_USE_FANCY_MATH_387
15691    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15692    && flag_unsafe_math_optimizations"
15694   int i;
15696   for (i=2; i<8; i++)
15697     operands[i] = gen_reg_rtx (XFmode);
15699   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15702 (define_expand "acossf2"
15703   [(set (match_dup 2)
15704         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15705    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15706    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15707    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15708    (parallel [(set (match_dup 7)
15709                    (unspec:XF [(match_dup 2) (match_dup 6)]
15710                               UNSPEC_FPATAN))
15711               (clobber (match_scratch:XF 8 ""))])
15712    (set (match_operand:SF 0 "register_operand" "")
15713         (float_truncate:SF (match_dup 7)))]
15714   "TARGET_USE_FANCY_MATH_387
15715    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15716    && flag_unsafe_math_optimizations"
15718   int i;
15720   for (i=2; i<8; i++)
15721     operands[i] = gen_reg_rtx (XFmode);
15723   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15726 (define_expand "acosxf2"
15727   [(set (match_dup 2)
15728         (mult:XF (match_operand:XF 1 "register_operand" "")
15729                  (match_dup 1)))
15730    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15731    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15732    (parallel [(set (match_operand:XF 0 "register_operand" "")
15733                    (unspec:XF [(match_dup 1) (match_dup 5)]
15734                               UNSPEC_FPATAN))
15735               (clobber (match_scratch:XF 6 ""))])]
15736   "TARGET_USE_FANCY_MATH_387
15737    && flag_unsafe_math_optimizations"
15739   int i;
15741   for (i=2; i<6; i++)
15742     operands[i] = gen_reg_rtx (XFmode);
15744   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15747 (define_insn "fyl2x_xf3"
15748   [(set (match_operand:XF 0 "register_operand" "=f")
15749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15750                     (match_operand:XF 1 "register_operand" "u")]
15751                    UNSPEC_FYL2X))
15752    (clobber (match_scratch:XF 3 "=1"))]
15753   "TARGET_USE_FANCY_MATH_387
15754    && flag_unsafe_math_optimizations"
15755   "fyl2x"
15756   [(set_attr "type" "fpspc")
15757    (set_attr "mode" "XF")])
15759 (define_expand "logsf2"
15760   [(set (match_dup 2)
15761         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15762    (parallel [(set (match_dup 4)
15763                    (unspec:XF [(match_dup 2)
15764                                (match_dup 3)] UNSPEC_FYL2X))
15765               (clobber (match_scratch:XF 5 ""))])
15766    (set (match_operand:SF 0 "register_operand" "")
15767         (float_truncate:SF (match_dup 4)))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations"
15772   rtx temp;
15774   operands[2] = gen_reg_rtx (XFmode);
15775   operands[3] = gen_reg_rtx (XFmode);
15776   operands[4] = gen_reg_rtx (XFmode);
15778   temp = standard_80387_constant_rtx (4); /* fldln2 */
15779   emit_move_insn (operands[3], temp);
15782 (define_expand "logdf2"
15783   [(set (match_dup 2)
15784         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15785    (parallel [(set (match_dup 4)
15786                    (unspec:XF [(match_dup 2)
15787                                (match_dup 3)] UNSPEC_FYL2X))
15788               (clobber (match_scratch:XF 5 ""))])
15789    (set (match_operand:DF 0 "register_operand" "")
15790         (float_truncate:DF (match_dup 4)))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15795   rtx temp;
15797   operands[2] = gen_reg_rtx (XFmode);
15798   operands[3] = gen_reg_rtx (XFmode);
15799   operands[4] = gen_reg_rtx (XFmode);
15801   temp = standard_80387_constant_rtx (4); /* fldln2 */
15802   emit_move_insn (operands[3], temp);
15805 (define_expand "logxf2"
15806   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15807                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15808                                (match_dup 2)] UNSPEC_FYL2X))
15809               (clobber (match_scratch:XF 3 ""))])]
15810   "TARGET_USE_FANCY_MATH_387
15811    && flag_unsafe_math_optimizations"
15813   rtx temp;
15815   operands[2] = gen_reg_rtx (XFmode);
15816   temp = standard_80387_constant_rtx (4); /* fldln2 */
15817   emit_move_insn (operands[2], temp);
15820 (define_expand "log10sf2"
15821   [(set (match_dup 2)
15822         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15823    (parallel [(set (match_dup 4)
15824                    (unspec:XF [(match_dup 2)
15825                                (match_dup 3)] UNSPEC_FYL2X))
15826               (clobber (match_scratch:XF 5 ""))])
15827    (set (match_operand:SF 0 "register_operand" "")
15828         (float_truncate:SF (match_dup 4)))]
15829   "TARGET_USE_FANCY_MATH_387
15830    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15831    && flag_unsafe_math_optimizations"
15833   rtx temp;
15835   operands[2] = gen_reg_rtx (XFmode);
15836   operands[3] = gen_reg_rtx (XFmode);
15837   operands[4] = gen_reg_rtx (XFmode);
15839   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15840   emit_move_insn (operands[3], temp);
15843 (define_expand "log10df2"
15844   [(set (match_dup 2)
15845         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15846    (parallel [(set (match_dup 4)
15847                    (unspec:XF [(match_dup 2)
15848                                (match_dup 3)] UNSPEC_FYL2X))
15849               (clobber (match_scratch:XF 5 ""))])
15850    (set (match_operand:DF 0 "register_operand" "")
15851         (float_truncate:DF (match_dup 4)))]
15852   "TARGET_USE_FANCY_MATH_387
15853    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15854    && flag_unsafe_math_optimizations"
15856   rtx temp;
15858   operands[2] = gen_reg_rtx (XFmode);
15859   operands[3] = gen_reg_rtx (XFmode);
15860   operands[4] = gen_reg_rtx (XFmode);
15862   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15863   emit_move_insn (operands[3], temp);
15866 (define_expand "log10xf2"
15867   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15868                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15869                                (match_dup 2)] UNSPEC_FYL2X))
15870               (clobber (match_scratch:XF 3 ""))])]
15871   "TARGET_USE_FANCY_MATH_387
15872    && flag_unsafe_math_optimizations"
15874   rtx temp;
15876   operands[2] = gen_reg_rtx (XFmode);
15877   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15878   emit_move_insn (operands[2], temp);
15881 (define_expand "log2sf2"
15882   [(set (match_dup 2)
15883         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15884    (parallel [(set (match_dup 4)
15885                    (unspec:XF [(match_dup 2)
15886                                (match_dup 3)] UNSPEC_FYL2X))
15887               (clobber (match_scratch:XF 5 ""))])
15888    (set (match_operand:SF 0 "register_operand" "")
15889         (float_truncate:SF (match_dup 4)))]
15890   "TARGET_USE_FANCY_MATH_387
15891    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15892    && flag_unsafe_math_optimizations"
15894   operands[2] = gen_reg_rtx (XFmode);
15895   operands[3] = gen_reg_rtx (XFmode);
15896   operands[4] = gen_reg_rtx (XFmode);
15898   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15901 (define_expand "log2df2"
15902   [(set (match_dup 2)
15903         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15904    (parallel [(set (match_dup 4)
15905                    (unspec:XF [(match_dup 2)
15906                                (match_dup 3)] UNSPEC_FYL2X))
15907               (clobber (match_scratch:XF 5 ""))])
15908    (set (match_operand:DF 0 "register_operand" "")
15909         (float_truncate:DF (match_dup 4)))]
15910   "TARGET_USE_FANCY_MATH_387
15911    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15912    && flag_unsafe_math_optimizations"
15914   operands[2] = gen_reg_rtx (XFmode);
15915   operands[3] = gen_reg_rtx (XFmode);
15916   operands[4] = gen_reg_rtx (XFmode);
15918   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15921 (define_expand "log2xf2"
15922   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15923                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15924                                (match_dup 2)] UNSPEC_FYL2X))
15925               (clobber (match_scratch:XF 3 ""))])]
15926   "TARGET_USE_FANCY_MATH_387
15927    && flag_unsafe_math_optimizations"
15929   operands[2] = gen_reg_rtx (XFmode);
15930   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15933 (define_insn "fyl2xp1_xf3"
15934   [(set (match_operand:XF 0 "register_operand" "=f")
15935         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15936                     (match_operand:XF 1 "register_operand" "u")]
15937                    UNSPEC_FYL2XP1))
15938    (clobber (match_scratch:XF 3 "=1"))]
15939   "TARGET_USE_FANCY_MATH_387
15940    && flag_unsafe_math_optimizations"
15941   "fyl2xp1"
15942   [(set_attr "type" "fpspc")
15943    (set_attr "mode" "XF")])
15945 (define_expand "log1psf2"
15946   [(use (match_operand:SF 0 "register_operand" ""))
15947    (use (match_operand:SF 1 "register_operand" ""))]
15948   "TARGET_USE_FANCY_MATH_387
15949    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15950    && flag_unsafe_math_optimizations"
15952   rtx op0 = gen_reg_rtx (XFmode);
15953   rtx op1 = gen_reg_rtx (XFmode);
15955   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15956   ix86_emit_i387_log1p (op0, op1);
15957   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15958   DONE;
15961 (define_expand "log1pdf2"
15962   [(use (match_operand:DF 0 "register_operand" ""))
15963    (use (match_operand:DF 1 "register_operand" ""))]
15964   "TARGET_USE_FANCY_MATH_387
15965    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15966    && flag_unsafe_math_optimizations"
15968   rtx op0 = gen_reg_rtx (XFmode);
15969   rtx op1 = gen_reg_rtx (XFmode);
15971   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15972   ix86_emit_i387_log1p (op0, op1);
15973   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15974   DONE;
15977 (define_expand "log1pxf2"
15978   [(use (match_operand:XF 0 "register_operand" ""))
15979    (use (match_operand:XF 1 "register_operand" ""))]
15980   "TARGET_USE_FANCY_MATH_387
15981    && flag_unsafe_math_optimizations"
15983   ix86_emit_i387_log1p (operands[0], operands[1]);
15984   DONE;
15987 (define_insn "*fxtractxf3"
15988   [(set (match_operand:XF 0 "register_operand" "=f")
15989         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15990                    UNSPEC_XTRACT_FRACT))
15991    (set (match_operand:XF 1 "register_operand" "=u")
15992         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15993   "TARGET_USE_FANCY_MATH_387
15994    && flag_unsafe_math_optimizations"
15995   "fxtract"
15996   [(set_attr "type" "fpspc")
15997    (set_attr "mode" "XF")])
15999 (define_expand "logbsf2"
16000   [(set (match_dup 2)
16001         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16002    (parallel [(set (match_dup 3)
16003                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16004               (set (match_dup 4)
16005                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16006    (set (match_operand:SF 0 "register_operand" "")
16007         (float_truncate:SF (match_dup 4)))]
16008   "TARGET_USE_FANCY_MATH_387
16009    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16010    && flag_unsafe_math_optimizations"
16012   operands[2] = gen_reg_rtx (XFmode);
16013   operands[3] = gen_reg_rtx (XFmode);
16014   operands[4] = gen_reg_rtx (XFmode);
16017 (define_expand "logbdf2"
16018   [(set (match_dup 2)
16019         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16020    (parallel [(set (match_dup 3)
16021                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16022               (set (match_dup 4)
16023                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16024    (set (match_operand:DF 0 "register_operand" "")
16025         (float_truncate:DF (match_dup 4)))]
16026   "TARGET_USE_FANCY_MATH_387
16027    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16028    && flag_unsafe_math_optimizations"
16030   operands[2] = gen_reg_rtx (XFmode);
16031   operands[3] = gen_reg_rtx (XFmode);
16032   operands[4] = gen_reg_rtx (XFmode);
16035 (define_expand "logbxf2"
16036   [(parallel [(set (match_dup 2)
16037                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16038                               UNSPEC_XTRACT_FRACT))
16039               (set (match_operand:XF 0 "register_operand" "")
16040                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16041   "TARGET_USE_FANCY_MATH_387
16042    && flag_unsafe_math_optimizations"
16044   operands[2] = gen_reg_rtx (XFmode);
16047 (define_expand "ilogbsi2"
16048   [(parallel [(set (match_dup 2)
16049                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16050                               UNSPEC_XTRACT_FRACT))
16051               (set (match_operand:XF 3 "register_operand" "")
16052                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16053    (parallel [(set (match_operand:SI 0 "register_operand" "")
16054                    (fix:SI (match_dup 3)))
16055               (clobber (reg:CC FLAGS_REG))])]
16056   "TARGET_USE_FANCY_MATH_387
16057    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16058    && flag_unsafe_math_optimizations"
16060   operands[2] = gen_reg_rtx (XFmode);
16061   operands[3] = gen_reg_rtx (XFmode);
16064 (define_insn "*f2xm1xf2"
16065   [(set (match_operand:XF 0 "register_operand" "=f")
16066         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16067          UNSPEC_F2XM1))]
16068   "TARGET_USE_FANCY_MATH_387
16069    && flag_unsafe_math_optimizations"
16070   "f2xm1"
16071   [(set_attr "type" "fpspc")
16072    (set_attr "mode" "XF")])
16074 (define_insn "*fscalexf4"
16075   [(set (match_operand:XF 0 "register_operand" "=f")
16076         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16077                     (match_operand:XF 3 "register_operand" "1")]
16078                    UNSPEC_FSCALE_FRACT))
16079    (set (match_operand:XF 1 "register_operand" "=u")
16080         (unspec:XF [(match_dup 2) (match_dup 3)]
16081                    UNSPEC_FSCALE_EXP))]
16082   "TARGET_USE_FANCY_MATH_387
16083    && flag_unsafe_math_optimizations"
16084   "fscale"
16085   [(set_attr "type" "fpspc")
16086    (set_attr "mode" "XF")])
16088 (define_expand "expsf2"
16089   [(set (match_dup 2)
16090         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16091    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16092    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16093    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16094    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16095    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16096    (parallel [(set (match_dup 10)
16097                    (unspec:XF [(match_dup 9) (match_dup 5)]
16098                               UNSPEC_FSCALE_FRACT))
16099               (set (match_dup 11)
16100                    (unspec:XF [(match_dup 9) (match_dup 5)]
16101                               UNSPEC_FSCALE_EXP))])
16102    (set (match_operand:SF 0 "register_operand" "")
16103         (float_truncate:SF (match_dup 10)))]
16104   "TARGET_USE_FANCY_MATH_387
16105    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16106    && flag_unsafe_math_optimizations"
16108   rtx temp;
16109   int i;
16111   for (i=2; i<12; i++)
16112     operands[i] = gen_reg_rtx (XFmode);
16113   temp = standard_80387_constant_rtx (5); /* fldl2e */
16114   emit_move_insn (operands[3], temp);
16115   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16118 (define_expand "expdf2"
16119   [(set (match_dup 2)
16120         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16121    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16122    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16123    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16124    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16125    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16126    (parallel [(set (match_dup 10)
16127                    (unspec:XF [(match_dup 9) (match_dup 5)]
16128                               UNSPEC_FSCALE_FRACT))
16129               (set (match_dup 11)
16130                    (unspec:XF [(match_dup 9) (match_dup 5)]
16131                               UNSPEC_FSCALE_EXP))])
16132    (set (match_operand:DF 0 "register_operand" "")
16133         (float_truncate:DF (match_dup 10)))]
16134   "TARGET_USE_FANCY_MATH_387
16135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16136    && flag_unsafe_math_optimizations"
16138   rtx temp;
16139   int i;
16141   for (i=2; i<12; i++)
16142     operands[i] = gen_reg_rtx (XFmode);
16143   temp = standard_80387_constant_rtx (5); /* fldl2e */
16144   emit_move_insn (operands[3], temp);
16145   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16148 (define_expand "expxf2"
16149   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16150                                (match_dup 2)))
16151    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16152    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16153    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16154    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16155    (parallel [(set (match_operand:XF 0 "register_operand" "")
16156                    (unspec:XF [(match_dup 8) (match_dup 4)]
16157                               UNSPEC_FSCALE_FRACT))
16158               (set (match_dup 9)
16159                    (unspec:XF [(match_dup 8) (match_dup 4)]
16160                               UNSPEC_FSCALE_EXP))])]
16161   "TARGET_USE_FANCY_MATH_387
16162    && flag_unsafe_math_optimizations"
16164   rtx temp;
16165   int i;
16167   for (i=2; i<10; i++)
16168     operands[i] = gen_reg_rtx (XFmode);
16169   temp = standard_80387_constant_rtx (5); /* fldl2e */
16170   emit_move_insn (operands[2], temp);
16171   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16174 (define_expand "exp10sf2"
16175   [(set (match_dup 2)
16176         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16177    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16178    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16179    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16180    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16181    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16182    (parallel [(set (match_dup 10)
16183                    (unspec:XF [(match_dup 9) (match_dup 5)]
16184                               UNSPEC_FSCALE_FRACT))
16185               (set (match_dup 11)
16186                    (unspec:XF [(match_dup 9) (match_dup 5)]
16187                               UNSPEC_FSCALE_EXP))])
16188    (set (match_operand:SF 0 "register_operand" "")
16189         (float_truncate:SF (match_dup 10)))]
16190   "TARGET_USE_FANCY_MATH_387
16191    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16192    && flag_unsafe_math_optimizations"
16194   rtx temp;
16195   int i;
16197   for (i=2; i<12; i++)
16198     operands[i] = gen_reg_rtx (XFmode);
16199   temp = standard_80387_constant_rtx (6); /* fldl2t */
16200   emit_move_insn (operands[3], temp);
16201   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16204 (define_expand "exp10df2"
16205   [(set (match_dup 2)
16206         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16207    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16208    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16209    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16210    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16211    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16212    (parallel [(set (match_dup 10)
16213                    (unspec:XF [(match_dup 9) (match_dup 5)]
16214                               UNSPEC_FSCALE_FRACT))
16215               (set (match_dup 11)
16216                    (unspec:XF [(match_dup 9) (match_dup 5)]
16217                               UNSPEC_FSCALE_EXP))])
16218    (set (match_operand:DF 0 "register_operand" "")
16219         (float_truncate:DF (match_dup 10)))]
16220   "TARGET_USE_FANCY_MATH_387
16221    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16222    && flag_unsafe_math_optimizations"
16224   rtx temp;
16225   int i;
16227   for (i=2; i<12; i++)
16228     operands[i] = gen_reg_rtx (XFmode);
16229   temp = standard_80387_constant_rtx (6); /* fldl2t */
16230   emit_move_insn (operands[3], temp);
16231   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16234 (define_expand "exp10xf2"
16235   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16236                                (match_dup 2)))
16237    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16238    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16239    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16240    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16241    (parallel [(set (match_operand:XF 0 "register_operand" "")
16242                    (unspec:XF [(match_dup 8) (match_dup 4)]
16243                               UNSPEC_FSCALE_FRACT))
16244               (set (match_dup 9)
16245                    (unspec:XF [(match_dup 8) (match_dup 4)]
16246                               UNSPEC_FSCALE_EXP))])]
16247   "TARGET_USE_FANCY_MATH_387
16248    && flag_unsafe_math_optimizations"
16250   rtx temp;
16251   int i;
16253   for (i=2; i<10; i++)
16254     operands[i] = gen_reg_rtx (XFmode);
16255   temp = standard_80387_constant_rtx (6); /* fldl2t */
16256   emit_move_insn (operands[2], temp);
16257   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16260 (define_expand "exp2sf2"
16261   [(set (match_dup 2)
16262         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16263    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16264    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16265    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16266    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16267    (parallel [(set (match_dup 8)
16268                    (unspec:XF [(match_dup 7) (match_dup 3)]
16269                               UNSPEC_FSCALE_FRACT))
16270               (set (match_dup 9)
16271                    (unspec:XF [(match_dup 7) (match_dup 3)]
16272                               UNSPEC_FSCALE_EXP))])
16273    (set (match_operand:SF 0 "register_operand" "")
16274         (float_truncate:SF (match_dup 8)))]
16275   "TARGET_USE_FANCY_MATH_387
16276    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16277    && flag_unsafe_math_optimizations"
16279   int i;
16281   for (i=2; i<10; i++)
16282     operands[i] = gen_reg_rtx (XFmode);
16283   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16286 (define_expand "exp2df2"
16287   [(set (match_dup 2)
16288         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16289    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16290    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16291    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16292    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16293    (parallel [(set (match_dup 8)
16294                    (unspec:XF [(match_dup 7) (match_dup 3)]
16295                               UNSPEC_FSCALE_FRACT))
16296               (set (match_dup 9)
16297                    (unspec:XF [(match_dup 7) (match_dup 3)]
16298                               UNSPEC_FSCALE_EXP))])
16299    (set (match_operand:DF 0 "register_operand" "")
16300         (float_truncate:DF (match_dup 8)))]
16301   "TARGET_USE_FANCY_MATH_387
16302    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16303    && flag_unsafe_math_optimizations"
16305   int i;
16307   for (i=2; i<10; i++)
16308     operands[i] = gen_reg_rtx (XFmode);
16309   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16312 (define_expand "exp2xf2"
16313   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16314    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16315    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16316    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16317    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16318    (parallel [(set (match_operand:XF 0 "register_operand" "")
16319                    (unspec:XF [(match_dup 7) (match_dup 3)]
16320                               UNSPEC_FSCALE_FRACT))
16321               (set (match_dup 8)
16322                    (unspec:XF [(match_dup 7) (match_dup 3)]
16323                               UNSPEC_FSCALE_EXP))])]
16324   "TARGET_USE_FANCY_MATH_387
16325    && flag_unsafe_math_optimizations"
16327   int i;
16329   for (i=2; i<9; i++)
16330     operands[i] = gen_reg_rtx (XFmode);
16331   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16334 (define_expand "expm1df2"
16335   [(set (match_dup 2)
16336         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16337    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16338    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16339    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16340    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16341    (parallel [(set (match_dup 8)
16342                    (unspec:XF [(match_dup 7) (match_dup 5)]
16343                               UNSPEC_FSCALE_FRACT))
16344                    (set (match_dup 9)
16345                    (unspec:XF [(match_dup 7) (match_dup 5)]
16346                               UNSPEC_FSCALE_EXP))])
16347    (parallel [(set (match_dup 11)
16348                    (unspec:XF [(match_dup 10) (match_dup 9)]
16349                               UNSPEC_FSCALE_FRACT))
16350               (set (match_dup 12)
16351                    (unspec:XF [(match_dup 10) (match_dup 9)]
16352                               UNSPEC_FSCALE_EXP))])
16353    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16354    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16355    (set (match_operand:DF 0 "register_operand" "")
16356         (float_truncate:DF (match_dup 14)))]
16357   "TARGET_USE_FANCY_MATH_387
16358    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16359    && flag_unsafe_math_optimizations"
16361   rtx temp;
16362   int i;
16364   for (i=2; i<15; i++)
16365     operands[i] = gen_reg_rtx (XFmode);
16366   temp = standard_80387_constant_rtx (5); /* fldl2e */
16367   emit_move_insn (operands[3], temp);
16368   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16371 (define_expand "expm1sf2"
16372   [(set (match_dup 2)
16373         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16374    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16375    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16376    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16377    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16378    (parallel [(set (match_dup 8)
16379                    (unspec:XF [(match_dup 7) (match_dup 5)]
16380                               UNSPEC_FSCALE_FRACT))
16381                    (set (match_dup 9)
16382                    (unspec:XF [(match_dup 7) (match_dup 5)]
16383                               UNSPEC_FSCALE_EXP))])
16384    (parallel [(set (match_dup 11)
16385                    (unspec:XF [(match_dup 10) (match_dup 9)]
16386                               UNSPEC_FSCALE_FRACT))
16387               (set (match_dup 12)
16388                    (unspec:XF [(match_dup 10) (match_dup 9)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16391    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16392    (set (match_operand:SF 0 "register_operand" "")
16393         (float_truncate:SF (match_dup 14)))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16398   rtx temp;
16399   int i;
16401   for (i=2; i<15; i++)
16402     operands[i] = gen_reg_rtx (XFmode);
16403   temp = standard_80387_constant_rtx (5); /* fldl2e */
16404   emit_move_insn (operands[3], temp);
16405   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16408 (define_expand "expm1xf2"
16409   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16410                                (match_dup 2)))
16411    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16412    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16413    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16414    (parallel [(set (match_dup 7)
16415                    (unspec:XF [(match_dup 6) (match_dup 4)]
16416                               UNSPEC_FSCALE_FRACT))
16417                    (set (match_dup 8)
16418                    (unspec:XF [(match_dup 6) (match_dup 4)]
16419                               UNSPEC_FSCALE_EXP))])
16420    (parallel [(set (match_dup 10)
16421                    (unspec:XF [(match_dup 9) (match_dup 8)]
16422                               UNSPEC_FSCALE_FRACT))
16423               (set (match_dup 11)
16424                    (unspec:XF [(match_dup 9) (match_dup 8)]
16425                               UNSPEC_FSCALE_EXP))])
16426    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16427    (set (match_operand:XF 0 "register_operand" "")
16428         (plus:XF (match_dup 12) (match_dup 7)))]
16429   "TARGET_USE_FANCY_MATH_387
16430    && flag_unsafe_math_optimizations"
16432   rtx temp;
16433   int i;
16435   for (i=2; i<13; i++)
16436     operands[i] = gen_reg_rtx (XFmode);
16437   temp = standard_80387_constant_rtx (5); /* fldl2e */
16438   emit_move_insn (operands[2], temp);
16439   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16442 (define_expand "ldexpdf3"
16443   [(set (match_dup 3)
16444         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16445    (set (match_dup 4)
16446         (float:XF (match_operand:SI 2 "register_operand" "")))
16447    (parallel [(set (match_dup 5)
16448                    (unspec:XF [(match_dup 3) (match_dup 4)]
16449                               UNSPEC_FSCALE_FRACT))
16450               (set (match_dup 6)
16451                    (unspec:XF [(match_dup 3) (match_dup 4)]
16452                               UNSPEC_FSCALE_EXP))])
16453    (set (match_operand:DF 0 "register_operand" "")
16454         (float_truncate:DF (match_dup 5)))]
16455   "TARGET_USE_FANCY_MATH_387
16456    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16457    && flag_unsafe_math_optimizations"
16459   int i;
16461   for (i=3; i<7; i++)
16462     operands[i] = gen_reg_rtx (XFmode);
16465 (define_expand "ldexpsf3"
16466   [(set (match_dup 3)
16467         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16468    (set (match_dup 4)
16469         (float:XF (match_operand:SI 2 "register_operand" "")))
16470    (parallel [(set (match_dup 5)
16471                    (unspec:XF [(match_dup 3) (match_dup 4)]
16472                               UNSPEC_FSCALE_FRACT))
16473               (set (match_dup 6)
16474                    (unspec:XF [(match_dup 3) (match_dup 4)]
16475                               UNSPEC_FSCALE_EXP))])
16476    (set (match_operand:SF 0 "register_operand" "")
16477         (float_truncate:SF (match_dup 5)))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16482   int i;
16484   for (i=3; i<7; i++)
16485     operands[i] = gen_reg_rtx (XFmode);
16488 (define_expand "ldexpxf3"
16489   [(set (match_dup 3)
16490         (float:XF (match_operand:SI 2 "register_operand" "")))
16491    (parallel [(set (match_operand:XF 0 " register_operand" "")
16492                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16493                                (match_dup 3)]
16494                               UNSPEC_FSCALE_FRACT))
16495               (set (match_dup 4)
16496                    (unspec:XF [(match_dup 1) (match_dup 3)]
16497                               UNSPEC_FSCALE_EXP))])]
16498   "TARGET_USE_FANCY_MATH_387
16499    && flag_unsafe_math_optimizations"
16501   int i;
16503   for (i=3; i<5; i++)
16504     operands[i] = gen_reg_rtx (XFmode);
16508 (define_insn "frndintxf2"
16509   [(set (match_operand:XF 0 "register_operand" "=f")
16510         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16511          UNSPEC_FRNDINT))]
16512   "TARGET_USE_FANCY_MATH_387
16513    && flag_unsafe_math_optimizations"
16514   "frndint"
16515   [(set_attr "type" "fpspc")
16516    (set_attr "mode" "XF")])
16518 (define_expand "rintdf2"
16519   [(use (match_operand:DF 0 "register_operand" ""))
16520    (use (match_operand:DF 1 "register_operand" ""))]
16521   "TARGET_USE_FANCY_MATH_387
16522    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16523    && flag_unsafe_math_optimizations"
16525   rtx op0 = gen_reg_rtx (XFmode);
16526   rtx op1 = gen_reg_rtx (XFmode);
16528   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16529   emit_insn (gen_frndintxf2 (op0, op1));
16531   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16532   DONE;
16535 (define_expand "rintsf2"
16536   [(use (match_operand:SF 0 "register_operand" ""))
16537    (use (match_operand:SF 1 "register_operand" ""))]
16538   "TARGET_USE_FANCY_MATH_387
16539    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16540    && flag_unsafe_math_optimizations"
16542   rtx op0 = gen_reg_rtx (XFmode);
16543   rtx op1 = gen_reg_rtx (XFmode);
16545   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16546   emit_insn (gen_frndintxf2 (op0, op1));
16548   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16549   DONE;
16552 (define_expand "rintxf2"
16553   [(use (match_operand:XF 0 "register_operand" ""))
16554    (use (match_operand:XF 1 "register_operand" ""))]
16555   "TARGET_USE_FANCY_MATH_387
16556    && flag_unsafe_math_optimizations"
16558   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16559   DONE;
16562 (define_insn_and_split "*fistdi2_1"
16563   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16564         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16565          UNSPEC_FIST))]
16566   "TARGET_USE_FANCY_MATH_387
16567    && flag_unsafe_math_optimizations
16568    && !(reload_completed || reload_in_progress)"
16569   "#"
16570   "&& 1"
16571   [(const_int 0)]
16573   if (memory_operand (operands[0], VOIDmode))
16574     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16575   else
16576     {
16577       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16578       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16579                                          operands[2]));
16580     }
16581   DONE;
16583   [(set_attr "type" "fpspc")
16584    (set_attr "mode" "DI")])
16586 (define_insn "fistdi2"
16587   [(set (match_operand:DI 0 "memory_operand" "=m")
16588         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16589          UNSPEC_FIST))
16590    (clobber (match_scratch:XF 2 "=&1f"))]
16591   "TARGET_USE_FANCY_MATH_387
16592    && flag_unsafe_math_optimizations"
16593   "* return output_fix_trunc (insn, operands, 0);"
16594   [(set_attr "type" "fpspc")
16595    (set_attr "mode" "DI")])
16597 (define_insn "fistdi2_with_temp"
16598   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16599         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16600          UNSPEC_FIST))
16601    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16602    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16603   "TARGET_USE_FANCY_MATH_387
16604    && flag_unsafe_math_optimizations"
16605   "#"
16606   [(set_attr "type" "fpspc")
16607    (set_attr "mode" "DI")])
16609 (define_split 
16610   [(set (match_operand:DI 0 "register_operand" "")
16611         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16612          UNSPEC_FIST))
16613    (clobber (match_operand:DI 2 "memory_operand" ""))
16614    (clobber (match_scratch 3 ""))]
16615   "reload_completed"
16616   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16617               (clobber (match_dup 3))])
16618    (set (match_dup 0) (match_dup 2))]
16619   "")
16621 (define_split 
16622   [(set (match_operand:DI 0 "memory_operand" "")
16623         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16624          UNSPEC_FIST))
16625    (clobber (match_operand:DI 2 "memory_operand" ""))
16626    (clobber (match_scratch 3 ""))]
16627   "reload_completed"
16628   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16629               (clobber (match_dup 3))])]
16630   "")
16632 (define_insn_and_split "*fist<mode>2_1"
16633   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16634         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16635          UNSPEC_FIST))]
16636   "TARGET_USE_FANCY_MATH_387
16637    && flag_unsafe_math_optimizations
16638    && !(reload_completed || reload_in_progress)"
16639   "#"
16640   "&& 1"
16641   [(const_int 0)]
16643   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16644   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16645                                         operands[2]));
16646   DONE;
16648   [(set_attr "type" "fpspc")
16649    (set_attr "mode" "<MODE>")])
16651 (define_insn "fist<mode>2"
16652   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16653         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16654          UNSPEC_FIST))]
16655   "TARGET_USE_FANCY_MATH_387
16656    && flag_unsafe_math_optimizations"
16657   "* return output_fix_trunc (insn, operands, 0);"
16658   [(set_attr "type" "fpspc")
16659    (set_attr "mode" "<MODE>")])
16661 (define_insn "fist<mode>2_with_temp"
16662   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16663         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16664          UNSPEC_FIST))
16665    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && flag_unsafe_math_optimizations"
16668   "#"
16669   [(set_attr "type" "fpspc")
16670    (set_attr "mode" "<MODE>")])
16672 (define_split 
16673   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16674         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16675          UNSPEC_FIST))
16676    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16677   "reload_completed"
16678   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16679                        UNSPEC_FIST))
16680    (set (match_dup 0) (match_dup 2))]
16681   "")
16683 (define_split 
16684   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16685         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16686          UNSPEC_FIST))
16687    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16688   "reload_completed"
16689   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16690                        UNSPEC_FIST))]
16691   "")
16693 (define_expand "lrint<mode>2"
16694   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16695         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16696          UNSPEC_FIST))]
16697   "TARGET_USE_FANCY_MATH_387
16698    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16699    && flag_unsafe_math_optimizations"
16700   "")
16702 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16703 (define_insn_and_split "frndintxf2_floor"
16704   [(set (match_operand:XF 0 "register_operand" "=f")
16705         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16706          UNSPEC_FRNDINT_FLOOR))
16707    (clobber (reg:CC FLAGS_REG))]
16708   "TARGET_USE_FANCY_MATH_387
16709    && flag_unsafe_math_optimizations
16710    && !(reload_completed || reload_in_progress)"
16711   "#"
16712   "&& 1"
16713   [(const_int 0)]
16715   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16717   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16718   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16720   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16721                                         operands[2], operands[3]));
16722   DONE;
16724   [(set_attr "type" "frndint")
16725    (set_attr "i387_cw" "floor")
16726    (set_attr "mode" "XF")])
16728 (define_insn "frndintxf2_floor_i387"
16729   [(set (match_operand:XF 0 "register_operand" "=f")
16730         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16731          UNSPEC_FRNDINT_FLOOR))
16732    (use (match_operand:HI 2 "memory_operand" "m"))
16733    (use (match_operand:HI 3 "memory_operand" "m"))]
16734   "TARGET_USE_FANCY_MATH_387
16735    && flag_unsafe_math_optimizations"
16736   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16737   [(set_attr "type" "frndint")
16738    (set_attr "i387_cw" "floor")
16739    (set_attr "mode" "XF")])
16741 (define_expand "floorxf2"
16742   [(use (match_operand:XF 0 "register_operand" ""))
16743    (use (match_operand:XF 1 "register_operand" ""))]
16744   "TARGET_USE_FANCY_MATH_387
16745    && flag_unsafe_math_optimizations"
16747   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16748   DONE;
16751 (define_expand "floordf2"
16752   [(use (match_operand:DF 0 "register_operand" ""))
16753    (use (match_operand:DF 1 "register_operand" ""))]
16754   "TARGET_USE_FANCY_MATH_387
16755    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16756    && flag_unsafe_math_optimizations"
16758   rtx op0 = gen_reg_rtx (XFmode);
16759   rtx op1 = gen_reg_rtx (XFmode);
16761   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16762   emit_insn (gen_frndintxf2_floor (op0, op1));
16764   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16765   DONE;
16768 (define_expand "floorsf2"
16769   [(use (match_operand:SF 0 "register_operand" ""))
16770    (use (match_operand:SF 1 "register_operand" ""))]
16771   "TARGET_USE_FANCY_MATH_387
16772    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16773    && flag_unsafe_math_optimizations"
16775   rtx op0 = gen_reg_rtx (XFmode);
16776   rtx op1 = gen_reg_rtx (XFmode);
16778   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16779   emit_insn (gen_frndintxf2_floor (op0, op1));
16781   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16782   DONE;
16785 (define_insn_and_split "*fist<mode>2_floor_1"
16786   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16787         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16788          UNSPEC_FIST_FLOOR))
16789    (clobber (reg:CC FLAGS_REG))]
16790   "TARGET_USE_FANCY_MATH_387
16791    && flag_unsafe_math_optimizations
16792    && !(reload_completed || reload_in_progress)"
16793   "#"
16794   "&& 1"
16795   [(const_int 0)]
16797   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16799   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16800   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16801   if (memory_operand (operands[0], VOIDmode))
16802     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16803                                       operands[2], operands[3]));
16804   else
16805     {
16806       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16807       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16808                                                   operands[2], operands[3],
16809                                                   operands[4]));
16810     }
16811   DONE;
16813   [(set_attr "type" "fistp")
16814    (set_attr "i387_cw" "floor")
16815    (set_attr "mode" "<MODE>")])
16817 (define_insn "fistdi2_floor"
16818   [(set (match_operand:DI 0 "memory_operand" "=m")
16819         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16820          UNSPEC_FIST_FLOOR))
16821    (use (match_operand:HI 2 "memory_operand" "m"))
16822    (use (match_operand:HI 3 "memory_operand" "m"))
16823    (clobber (match_scratch:XF 4 "=&1f"))]
16824   "TARGET_USE_FANCY_MATH_387
16825    && flag_unsafe_math_optimizations"
16826   "* return output_fix_trunc (insn, operands, 0);"
16827   [(set_attr "type" "fistp")
16828    (set_attr "i387_cw" "floor")
16829    (set_attr "mode" "DI")])
16831 (define_insn "fistdi2_floor_with_temp"
16832   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16833         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16834          UNSPEC_FIST_FLOOR))
16835    (use (match_operand:HI 2 "memory_operand" "m,m"))
16836    (use (match_operand:HI 3 "memory_operand" "m,m"))
16837    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16838    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16839   "TARGET_USE_FANCY_MATH_387
16840    && flag_unsafe_math_optimizations"
16841   "#"
16842   [(set_attr "type" "fistp")
16843    (set_attr "i387_cw" "floor")
16844    (set_attr "mode" "DI")])
16846 (define_split 
16847   [(set (match_operand:DI 0 "register_operand" "")
16848         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16849          UNSPEC_FIST_FLOOR))
16850    (use (match_operand:HI 2 "memory_operand" ""))
16851    (use (match_operand:HI 3 "memory_operand" ""))
16852    (clobber (match_operand:DI 4 "memory_operand" ""))
16853    (clobber (match_scratch 5 ""))]
16854   "reload_completed"
16855   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16856               (use (match_dup 2))
16857               (use (match_dup 3))
16858               (clobber (match_dup 5))])
16859    (set (match_dup 0) (match_dup 4))]
16860   "")
16862 (define_split 
16863   [(set (match_operand:DI 0 "memory_operand" "")
16864         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16865          UNSPEC_FIST_FLOOR))
16866    (use (match_operand:HI 2 "memory_operand" ""))
16867    (use (match_operand:HI 3 "memory_operand" ""))
16868    (clobber (match_operand:DI 4 "memory_operand" ""))
16869    (clobber (match_scratch 5 ""))]
16870   "reload_completed"
16871   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16872               (use (match_dup 2))
16873               (use (match_dup 3))
16874               (clobber (match_dup 5))])]
16875   "")
16877 (define_insn "fist<mode>2_floor"
16878   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16879         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16880          UNSPEC_FIST_FLOOR))
16881    (use (match_operand:HI 2 "memory_operand" "m"))
16882    (use (match_operand:HI 3 "memory_operand" "m"))]
16883   "TARGET_USE_FANCY_MATH_387
16884    && flag_unsafe_math_optimizations"
16885   "* return output_fix_trunc (insn, operands, 0);"
16886   [(set_attr "type" "fistp")
16887    (set_attr "i387_cw" "floor")
16888    (set_attr "mode" "<MODE>")])
16890 (define_insn "fist<mode>2_floor_with_temp"
16891   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16892         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16893          UNSPEC_FIST_FLOOR))
16894    (use (match_operand:HI 2 "memory_operand" "m,m"))
16895    (use (match_operand:HI 3 "memory_operand" "m,m"))
16896    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16897   "TARGET_USE_FANCY_MATH_387
16898    && flag_unsafe_math_optimizations"
16899   "#"
16900   [(set_attr "type" "fistp")
16901    (set_attr "i387_cw" "floor")
16902    (set_attr "mode" "<MODE>")])
16904 (define_split 
16905   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16906         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16907          UNSPEC_FIST_FLOOR))
16908    (use (match_operand:HI 2 "memory_operand" ""))
16909    (use (match_operand:HI 3 "memory_operand" ""))
16910    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16911   "reload_completed"
16912   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16913                                   UNSPEC_FIST_FLOOR))
16914               (use (match_dup 2))
16915               (use (match_dup 3))])
16916    (set (match_dup 0) (match_dup 4))]
16917   "")
16919 (define_split 
16920   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16921         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16922          UNSPEC_FIST_FLOOR))
16923    (use (match_operand:HI 2 "memory_operand" ""))
16924    (use (match_operand:HI 3 "memory_operand" ""))
16925    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16926   "reload_completed"
16927   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16928                                   UNSPEC_FIST_FLOOR))
16929               (use (match_dup 2))
16930               (use (match_dup 3))])]
16931   "")
16933 (define_expand "lfloor<mode>2"
16934   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16935                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16936                     UNSPEC_FIST_FLOOR))
16937               (clobber (reg:CC FLAGS_REG))])]
16938   "TARGET_USE_FANCY_MATH_387
16939    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16940    && flag_unsafe_math_optimizations"
16941   "")
16943 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16944 (define_insn_and_split "frndintxf2_ceil"
16945   [(set (match_operand:XF 0 "register_operand" "=f")
16946         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16947          UNSPEC_FRNDINT_CEIL))
16948    (clobber (reg:CC FLAGS_REG))]
16949   "TARGET_USE_FANCY_MATH_387
16950    && flag_unsafe_math_optimizations
16951    && !(reload_completed || reload_in_progress)"
16952   "#"
16953   "&& 1"
16954   [(const_int 0)]
16956   ix86_optimize_mode_switching[I387_CEIL] = 1;
16958   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16959   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16961   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16962                                        operands[2], operands[3]));
16963   DONE;
16965   [(set_attr "type" "frndint")
16966    (set_attr "i387_cw" "ceil")
16967    (set_attr "mode" "XF")])
16969 (define_insn "frndintxf2_ceil_i387"
16970   [(set (match_operand:XF 0 "register_operand" "=f")
16971         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16972          UNSPEC_FRNDINT_CEIL))
16973    (use (match_operand:HI 2 "memory_operand" "m"))
16974    (use (match_operand:HI 3 "memory_operand" "m"))]
16975   "TARGET_USE_FANCY_MATH_387
16976    && flag_unsafe_math_optimizations"
16977   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16978   [(set_attr "type" "frndint")
16979    (set_attr "i387_cw" "ceil")
16980    (set_attr "mode" "XF")])
16982 (define_expand "ceilxf2"
16983   [(use (match_operand:XF 0 "register_operand" ""))
16984    (use (match_operand:XF 1 "register_operand" ""))]
16985   "TARGET_USE_FANCY_MATH_387
16986    && flag_unsafe_math_optimizations"
16988   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16989   DONE;
16992 (define_expand "ceildf2"
16993   [(use (match_operand:DF 0 "register_operand" ""))
16994    (use (match_operand:DF 1 "register_operand" ""))]
16995   "TARGET_USE_FANCY_MATH_387
16996    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16997    && flag_unsafe_math_optimizations"
16999   rtx op0 = gen_reg_rtx (XFmode);
17000   rtx op1 = gen_reg_rtx (XFmode);
17002   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17003   emit_insn (gen_frndintxf2_ceil (op0, op1));
17005   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17006   DONE;
17009 (define_expand "ceilsf2"
17010   [(use (match_operand:SF 0 "register_operand" ""))
17011    (use (match_operand:SF 1 "register_operand" ""))]
17012   "TARGET_USE_FANCY_MATH_387
17013    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17014    && flag_unsafe_math_optimizations"
17016   rtx op0 = gen_reg_rtx (XFmode);
17017   rtx op1 = gen_reg_rtx (XFmode);
17019   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17020   emit_insn (gen_frndintxf2_ceil (op0, op1));
17022   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17023   DONE;
17026 (define_insn_and_split "*fist<mode>2_ceil_1"
17027   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17028         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17029          UNSPEC_FIST_CEIL))
17030    (clobber (reg:CC FLAGS_REG))]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations
17033    && !(reload_completed || reload_in_progress)"
17034   "#"
17035   "&& 1"
17036   [(const_int 0)]
17038   ix86_optimize_mode_switching[I387_CEIL] = 1;
17040   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17041   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17042   if (memory_operand (operands[0], VOIDmode))
17043     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17044                                      operands[2], operands[3]));
17045   else
17046     {
17047       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17048       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17049                                                  operands[2], operands[3],
17050                                                  operands[4]));
17051     }
17052   DONE;
17054   [(set_attr "type" "fistp")
17055    (set_attr "i387_cw" "ceil")
17056    (set_attr "mode" "<MODE>")])
17058 (define_insn "fistdi2_ceil"
17059   [(set (match_operand:DI 0 "memory_operand" "=m")
17060         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17061          UNSPEC_FIST_CEIL))
17062    (use (match_operand:HI 2 "memory_operand" "m"))
17063    (use (match_operand:HI 3 "memory_operand" "m"))
17064    (clobber (match_scratch:XF 4 "=&1f"))]
17065   "TARGET_USE_FANCY_MATH_387
17066    && flag_unsafe_math_optimizations"
17067   "* return output_fix_trunc (insn, operands, 0);"
17068   [(set_attr "type" "fistp")
17069    (set_attr "i387_cw" "ceil")
17070    (set_attr "mode" "DI")])
17072 (define_insn "fistdi2_ceil_with_temp"
17073   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17074         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17075          UNSPEC_FIST_CEIL))
17076    (use (match_operand:HI 2 "memory_operand" "m,m"))
17077    (use (match_operand:HI 3 "memory_operand" "m,m"))
17078    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17079    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17080   "TARGET_USE_FANCY_MATH_387
17081    && flag_unsafe_math_optimizations"
17082   "#"
17083   [(set_attr "type" "fistp")
17084    (set_attr "i387_cw" "ceil")
17085    (set_attr "mode" "DI")])
17087 (define_split 
17088   [(set (match_operand:DI 0 "register_operand" "")
17089         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17090          UNSPEC_FIST_CEIL))
17091    (use (match_operand:HI 2 "memory_operand" ""))
17092    (use (match_operand:HI 3 "memory_operand" ""))
17093    (clobber (match_operand:DI 4 "memory_operand" ""))
17094    (clobber (match_scratch 5 ""))]
17095   "reload_completed"
17096   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17097               (use (match_dup 2))
17098               (use (match_dup 3))
17099               (clobber (match_dup 5))])
17100    (set (match_dup 0) (match_dup 4))]
17101   "")
17103 (define_split 
17104   [(set (match_operand:DI 0 "memory_operand" "")
17105         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17106          UNSPEC_FIST_CEIL))
17107    (use (match_operand:HI 2 "memory_operand" ""))
17108    (use (match_operand:HI 3 "memory_operand" ""))
17109    (clobber (match_operand:DI 4 "memory_operand" ""))
17110    (clobber (match_scratch 5 ""))]
17111   "reload_completed"
17112   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17113               (use (match_dup 2))
17114               (use (match_dup 3))
17115               (clobber (match_dup 5))])]
17116   "")
17118 (define_insn "fist<mode>2_ceil"
17119   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17120         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17121          UNSPEC_FIST_CEIL))
17122    (use (match_operand:HI 2 "memory_operand" "m"))
17123    (use (match_operand:HI 3 "memory_operand" "m"))]
17124   "TARGET_USE_FANCY_MATH_387
17125    && flag_unsafe_math_optimizations"
17126   "* return output_fix_trunc (insn, operands, 0);"
17127   [(set_attr "type" "fistp")
17128    (set_attr "i387_cw" "ceil")
17129    (set_attr "mode" "<MODE>")])
17131 (define_insn "fist<mode>2_ceil_with_temp"
17132   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17133         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17134          UNSPEC_FIST_CEIL))
17135    (use (match_operand:HI 2 "memory_operand" "m,m"))
17136    (use (match_operand:HI 3 "memory_operand" "m,m"))
17137    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17138   "TARGET_USE_FANCY_MATH_387
17139    && flag_unsafe_math_optimizations"
17140   "#"
17141   [(set_attr "type" "fistp")
17142    (set_attr "i387_cw" "ceil")
17143    (set_attr "mode" "<MODE>")])
17145 (define_split 
17146   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17147         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17148          UNSPEC_FIST_CEIL))
17149    (use (match_operand:HI 2 "memory_operand" ""))
17150    (use (match_operand:HI 3 "memory_operand" ""))
17151    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17152   "reload_completed"
17153   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17154                                   UNSPEC_FIST_CEIL))
17155               (use (match_dup 2))
17156               (use (match_dup 3))])
17157    (set (match_dup 0) (match_dup 4))]
17158   "")
17160 (define_split 
17161   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17162         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17163          UNSPEC_FIST_CEIL))
17164    (use (match_operand:HI 2 "memory_operand" ""))
17165    (use (match_operand:HI 3 "memory_operand" ""))
17166    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17167   "reload_completed"
17168   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17169                                   UNSPEC_FIST_CEIL))
17170               (use (match_dup 2))
17171               (use (match_dup 3))])]
17172   "")
17174 (define_expand "lceil<mode>2"
17175   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17176                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17177                     UNSPEC_FIST_CEIL))
17178               (clobber (reg:CC FLAGS_REG))])]
17179   "TARGET_USE_FANCY_MATH_387
17180    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17181    && flag_unsafe_math_optimizations"
17182   "")
17184 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17185 (define_insn_and_split "frndintxf2_trunc"
17186   [(set (match_operand:XF 0 "register_operand" "=f")
17187         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17188          UNSPEC_FRNDINT_TRUNC))
17189    (clobber (reg:CC FLAGS_REG))]
17190   "TARGET_USE_FANCY_MATH_387
17191    && flag_unsafe_math_optimizations
17192    && !(reload_completed || reload_in_progress)"
17193   "#"
17194   "&& 1"
17195   [(const_int 0)]
17197   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17199   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17200   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17202   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17203                                         operands[2], operands[3]));
17204   DONE;
17206   [(set_attr "type" "frndint")
17207    (set_attr "i387_cw" "trunc")
17208    (set_attr "mode" "XF")])
17210 (define_insn "frndintxf2_trunc_i387"
17211   [(set (match_operand:XF 0 "register_operand" "=f")
17212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17213          UNSPEC_FRNDINT_TRUNC))
17214    (use (match_operand:HI 2 "memory_operand" "m"))
17215    (use (match_operand:HI 3 "memory_operand" "m"))]
17216   "TARGET_USE_FANCY_MATH_387
17217    && flag_unsafe_math_optimizations"
17218   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17219   [(set_attr "type" "frndint")
17220    (set_attr "i387_cw" "trunc")
17221    (set_attr "mode" "XF")])
17223 (define_expand "btruncxf2"
17224   [(use (match_operand:XF 0 "register_operand" ""))
17225    (use (match_operand:XF 1 "register_operand" ""))]
17226   "TARGET_USE_FANCY_MATH_387
17227    && flag_unsafe_math_optimizations"
17229   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17230   DONE;
17233 (define_expand "btruncdf2"
17234   [(use (match_operand:DF 0 "register_operand" ""))
17235    (use (match_operand:DF 1 "register_operand" ""))]
17236   "TARGET_USE_FANCY_MATH_387
17237    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17238    && flag_unsafe_math_optimizations"
17240   rtx op0 = gen_reg_rtx (XFmode);
17241   rtx op1 = gen_reg_rtx (XFmode);
17243   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17244   emit_insn (gen_frndintxf2_trunc (op0, op1));
17246   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17247   DONE;
17250 (define_expand "btruncsf2"
17251   [(use (match_operand:SF 0 "register_operand" ""))
17252    (use (match_operand:SF 1 "register_operand" ""))]
17253   "TARGET_USE_FANCY_MATH_387
17254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17255    && flag_unsafe_math_optimizations"
17257   rtx op0 = gen_reg_rtx (XFmode);
17258   rtx op1 = gen_reg_rtx (XFmode);
17260   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17261   emit_insn (gen_frndintxf2_trunc (op0, op1));
17263   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17264   DONE;
17267 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17268 (define_insn_and_split "frndintxf2_mask_pm"
17269   [(set (match_operand:XF 0 "register_operand" "=f")
17270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17271          UNSPEC_FRNDINT_MASK_PM))
17272    (clobber (reg:CC FLAGS_REG))]
17273   "TARGET_USE_FANCY_MATH_387
17274    && flag_unsafe_math_optimizations
17275    && !(reload_completed || reload_in_progress)"
17276   "#"
17277   "&& 1"
17278   [(const_int 0)]
17280   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17282   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17283   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17285   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17286                                           operands[2], operands[3]));
17287   DONE;
17289   [(set_attr "type" "frndint")
17290    (set_attr "i387_cw" "mask_pm")
17291    (set_attr "mode" "XF")])
17293 (define_insn "frndintxf2_mask_pm_i387"
17294   [(set (match_operand:XF 0 "register_operand" "=f")
17295         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17296          UNSPEC_FRNDINT_MASK_PM))
17297    (use (match_operand:HI 2 "memory_operand" "m"))
17298    (use (match_operand:HI 3 "memory_operand" "m"))]
17299   "TARGET_USE_FANCY_MATH_387
17300    && flag_unsafe_math_optimizations"
17301   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17302   [(set_attr "type" "frndint")
17303    (set_attr "i387_cw" "mask_pm")
17304    (set_attr "mode" "XF")])
17306 (define_expand "nearbyintxf2"
17307   [(use (match_operand:XF 0 "register_operand" ""))
17308    (use (match_operand:XF 1 "register_operand" ""))]
17309   "TARGET_USE_FANCY_MATH_387
17310    && flag_unsafe_math_optimizations"
17312   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17314   DONE;
17317 (define_expand "nearbyintdf2"
17318   [(use (match_operand:DF 0 "register_operand" ""))
17319    (use (match_operand:DF 1 "register_operand" ""))]
17320   "TARGET_USE_FANCY_MATH_387
17321    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17322    && flag_unsafe_math_optimizations"
17324   rtx op0 = gen_reg_rtx (XFmode);
17325   rtx op1 = gen_reg_rtx (XFmode);
17327   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17328   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17330   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17331   DONE;
17334 (define_expand "nearbyintsf2"
17335   [(use (match_operand:SF 0 "register_operand" ""))
17336    (use (match_operand:SF 1 "register_operand" ""))]
17337   "TARGET_USE_FANCY_MATH_387
17338    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17339    && flag_unsafe_math_optimizations"
17341   rtx op0 = gen_reg_rtx (XFmode);
17342   rtx op1 = gen_reg_rtx (XFmode);
17344   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17345   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17347   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17348   DONE;
17352 ;; Block operation instructions
17354 (define_insn "cld"
17355  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17356  ""
17357  "cld"
17358   [(set_attr "type" "cld")])
17360 (define_expand "movmemsi"
17361   [(use (match_operand:BLK 0 "memory_operand" ""))
17362    (use (match_operand:BLK 1 "memory_operand" ""))
17363    (use (match_operand:SI 2 "nonmemory_operand" ""))
17364    (use (match_operand:SI 3 "const_int_operand" ""))]
17365   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17367  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17368    DONE;
17369  else
17370    FAIL;
17373 (define_expand "movmemdi"
17374   [(use (match_operand:BLK 0 "memory_operand" ""))
17375    (use (match_operand:BLK 1 "memory_operand" ""))
17376    (use (match_operand:DI 2 "nonmemory_operand" ""))
17377    (use (match_operand:DI 3 "const_int_operand" ""))]
17378   "TARGET_64BIT"
17380  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17381    DONE;
17382  else
17383    FAIL;
17386 ;; Most CPUs don't like single string operations
17387 ;; Handle this case here to simplify previous expander.
17389 (define_expand "strmov"
17390   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17391    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17392    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17393               (clobber (reg:CC FLAGS_REG))])
17394    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17395               (clobber (reg:CC FLAGS_REG))])]
17396   ""
17398   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17400   /* If .md ever supports :P for Pmode, these can be directly
17401      in the pattern above.  */
17402   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17403   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17405   if (TARGET_SINGLE_STRINGOP || optimize_size)
17406     {
17407       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17408                                       operands[2], operands[3],
17409                                       operands[5], operands[6]));
17410       DONE;
17411     }
17413   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17416 (define_expand "strmov_singleop"
17417   [(parallel [(set (match_operand 1 "memory_operand" "")
17418                    (match_operand 3 "memory_operand" ""))
17419               (set (match_operand 0 "register_operand" "")
17420                    (match_operand 4 "" ""))
17421               (set (match_operand 2 "register_operand" "")
17422                    (match_operand 5 "" ""))
17423               (use (reg:SI DIRFLAG_REG))])]
17424   "TARGET_SINGLE_STRINGOP || optimize_size"
17425   "")
17427 (define_insn "*strmovdi_rex_1"
17428   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17429         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17430    (set (match_operand:DI 0 "register_operand" "=D")
17431         (plus:DI (match_dup 2)
17432                  (const_int 8)))
17433    (set (match_operand:DI 1 "register_operand" "=S")
17434         (plus:DI (match_dup 3)
17435                  (const_int 8)))
17436    (use (reg:SI DIRFLAG_REG))]
17437   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17438   "movsq"
17439   [(set_attr "type" "str")
17440    (set_attr "mode" "DI")
17441    (set_attr "memory" "both")])
17443 (define_insn "*strmovsi_1"
17444   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17445         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17446    (set (match_operand:SI 0 "register_operand" "=D")
17447         (plus:SI (match_dup 2)
17448                  (const_int 4)))
17449    (set (match_operand:SI 1 "register_operand" "=S")
17450         (plus:SI (match_dup 3)
17451                  (const_int 4)))
17452    (use (reg:SI DIRFLAG_REG))]
17453   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17454   "{movsl|movsd}"
17455   [(set_attr "type" "str")
17456    (set_attr "mode" "SI")
17457    (set_attr "memory" "both")])
17459 (define_insn "*strmovsi_rex_1"
17460   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17461         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17462    (set (match_operand:DI 0 "register_operand" "=D")
17463         (plus:DI (match_dup 2)
17464                  (const_int 4)))
17465    (set (match_operand:DI 1 "register_operand" "=S")
17466         (plus:DI (match_dup 3)
17467                  (const_int 4)))
17468    (use (reg:SI DIRFLAG_REG))]
17469   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17470   "{movsl|movsd}"
17471   [(set_attr "type" "str")
17472    (set_attr "mode" "SI")
17473    (set_attr "memory" "both")])
17475 (define_insn "*strmovhi_1"
17476   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17477         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17478    (set (match_operand:SI 0 "register_operand" "=D")
17479         (plus:SI (match_dup 2)
17480                  (const_int 2)))
17481    (set (match_operand:SI 1 "register_operand" "=S")
17482         (plus:SI (match_dup 3)
17483                  (const_int 2)))
17484    (use (reg:SI DIRFLAG_REG))]
17485   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17486   "movsw"
17487   [(set_attr "type" "str")
17488    (set_attr "memory" "both")
17489    (set_attr "mode" "HI")])
17491 (define_insn "*strmovhi_rex_1"
17492   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17493         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17494    (set (match_operand:DI 0 "register_operand" "=D")
17495         (plus:DI (match_dup 2)
17496                  (const_int 2)))
17497    (set (match_operand:DI 1 "register_operand" "=S")
17498         (plus:DI (match_dup 3)
17499                  (const_int 2)))
17500    (use (reg:SI DIRFLAG_REG))]
17501   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17502   "movsw"
17503   [(set_attr "type" "str")
17504    (set_attr "memory" "both")
17505    (set_attr "mode" "HI")])
17507 (define_insn "*strmovqi_1"
17508   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17509         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17510    (set (match_operand:SI 0 "register_operand" "=D")
17511         (plus:SI (match_dup 2)
17512                  (const_int 1)))
17513    (set (match_operand:SI 1 "register_operand" "=S")
17514         (plus:SI (match_dup 3)
17515                  (const_int 1)))
17516    (use (reg:SI DIRFLAG_REG))]
17517   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17518   "movsb"
17519   [(set_attr "type" "str")
17520    (set_attr "memory" "both")
17521    (set_attr "mode" "QI")])
17523 (define_insn "*strmovqi_rex_1"
17524   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17525         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17526    (set (match_operand:DI 0 "register_operand" "=D")
17527         (plus:DI (match_dup 2)
17528                  (const_int 1)))
17529    (set (match_operand:DI 1 "register_operand" "=S")
17530         (plus:DI (match_dup 3)
17531                  (const_int 1)))
17532    (use (reg:SI DIRFLAG_REG))]
17533   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17534   "movsb"
17535   [(set_attr "type" "str")
17536    (set_attr "memory" "both")
17537    (set_attr "mode" "QI")])
17539 (define_expand "rep_mov"
17540   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17541               (set (match_operand 0 "register_operand" "")
17542                    (match_operand 5 "" ""))
17543               (set (match_operand 2 "register_operand" "")
17544                    (match_operand 6 "" ""))
17545               (set (match_operand 1 "memory_operand" "")
17546                    (match_operand 3 "memory_operand" ""))
17547               (use (match_dup 4))
17548               (use (reg:SI DIRFLAG_REG))])]
17549   ""
17550   "")
17552 (define_insn "*rep_movdi_rex64"
17553   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17554    (set (match_operand:DI 0 "register_operand" "=D") 
17555         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17556                             (const_int 3))
17557                  (match_operand:DI 3 "register_operand" "0")))
17558    (set (match_operand:DI 1 "register_operand" "=S") 
17559         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17560                  (match_operand:DI 4 "register_operand" "1")))
17561    (set (mem:BLK (match_dup 3))
17562         (mem:BLK (match_dup 4)))
17563    (use (match_dup 5))
17564    (use (reg:SI DIRFLAG_REG))]
17565   "TARGET_64BIT"
17566   "{rep\;movsq|rep movsq}"
17567   [(set_attr "type" "str")
17568    (set_attr "prefix_rep" "1")
17569    (set_attr "memory" "both")
17570    (set_attr "mode" "DI")])
17572 (define_insn "*rep_movsi"
17573   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17574    (set (match_operand:SI 0 "register_operand" "=D") 
17575         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17576                             (const_int 2))
17577                  (match_operand:SI 3 "register_operand" "0")))
17578    (set (match_operand:SI 1 "register_operand" "=S") 
17579         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17580                  (match_operand:SI 4 "register_operand" "1")))
17581    (set (mem:BLK (match_dup 3))
17582         (mem:BLK (match_dup 4)))
17583    (use (match_dup 5))
17584    (use (reg:SI DIRFLAG_REG))]
17585   "!TARGET_64BIT"
17586   "{rep\;movsl|rep movsd}"
17587   [(set_attr "type" "str")
17588    (set_attr "prefix_rep" "1")
17589    (set_attr "memory" "both")
17590    (set_attr "mode" "SI")])
17592 (define_insn "*rep_movsi_rex64"
17593   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17594    (set (match_operand:DI 0 "register_operand" "=D") 
17595         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17596                             (const_int 2))
17597                  (match_operand:DI 3 "register_operand" "0")))
17598    (set (match_operand:DI 1 "register_operand" "=S") 
17599         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17600                  (match_operand:DI 4 "register_operand" "1")))
17601    (set (mem:BLK (match_dup 3))
17602         (mem:BLK (match_dup 4)))
17603    (use (match_dup 5))
17604    (use (reg:SI DIRFLAG_REG))]
17605   "TARGET_64BIT"
17606   "{rep\;movsl|rep movsd}"
17607   [(set_attr "type" "str")
17608    (set_attr "prefix_rep" "1")
17609    (set_attr "memory" "both")
17610    (set_attr "mode" "SI")])
17612 (define_insn "*rep_movqi"
17613   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17614    (set (match_operand:SI 0 "register_operand" "=D") 
17615         (plus:SI (match_operand:SI 3 "register_operand" "0")
17616                  (match_operand:SI 5 "register_operand" "2")))
17617    (set (match_operand:SI 1 "register_operand" "=S") 
17618         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17619    (set (mem:BLK (match_dup 3))
17620         (mem:BLK (match_dup 4)))
17621    (use (match_dup 5))
17622    (use (reg:SI DIRFLAG_REG))]
17623   "!TARGET_64BIT"
17624   "{rep\;movsb|rep movsb}"
17625   [(set_attr "type" "str")
17626    (set_attr "prefix_rep" "1")
17627    (set_attr "memory" "both")
17628    (set_attr "mode" "SI")])
17630 (define_insn "*rep_movqi_rex64"
17631   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17632    (set (match_operand:DI 0 "register_operand" "=D") 
17633         (plus:DI (match_operand:DI 3 "register_operand" "0")
17634                  (match_operand:DI 5 "register_operand" "2")))
17635    (set (match_operand:DI 1 "register_operand" "=S") 
17636         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17637    (set (mem:BLK (match_dup 3))
17638         (mem:BLK (match_dup 4)))
17639    (use (match_dup 5))
17640    (use (reg:SI DIRFLAG_REG))]
17641   "TARGET_64BIT"
17642   "{rep\;movsb|rep movsb}"
17643   [(set_attr "type" "str")
17644    (set_attr "prefix_rep" "1")
17645    (set_attr "memory" "both")
17646    (set_attr "mode" "SI")])
17648 (define_expand "setmemsi"
17649    [(use (match_operand:BLK 0 "memory_operand" ""))
17650     (use (match_operand:SI 1 "nonmemory_operand" ""))
17651     (use (match_operand 2 "const_int_operand" ""))
17652     (use (match_operand 3 "const_int_operand" ""))]
17653   ""
17655  /* If value to set is not zero, use the library routine.  */
17656  if (operands[2] != const0_rtx)
17657    FAIL;
17659  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17660    DONE;
17661  else
17662    FAIL;
17665 (define_expand "setmemdi"
17666    [(use (match_operand:BLK 0 "memory_operand" ""))
17667     (use (match_operand:DI 1 "nonmemory_operand" ""))
17668     (use (match_operand 2 "const_int_operand" ""))
17669     (use (match_operand 3 "const_int_operand" ""))]
17670   "TARGET_64BIT"
17672  /* If value to set is not zero, use the library routine.  */
17673  if (operands[2] != const0_rtx)
17674    FAIL;
17676  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17677    DONE;
17678  else
17679    FAIL;
17682 ;; Most CPUs don't like single string operations
17683 ;; Handle this case here to simplify previous expander.
17685 (define_expand "strset"
17686   [(set (match_operand 1 "memory_operand" "")
17687         (match_operand 2 "register_operand" ""))
17688    (parallel [(set (match_operand 0 "register_operand" "")
17689                    (match_dup 3))
17690               (clobber (reg:CC FLAGS_REG))])]
17691   ""
17693   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17694     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17696   /* If .md ever supports :P for Pmode, this can be directly
17697      in the pattern above.  */
17698   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17699                               GEN_INT (GET_MODE_SIZE (GET_MODE
17700                                                       (operands[2]))));
17701   if (TARGET_SINGLE_STRINGOP || optimize_size)
17702     {
17703       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17704                                       operands[3]));
17705       DONE;
17706     }
17709 (define_expand "strset_singleop"
17710   [(parallel [(set (match_operand 1 "memory_operand" "")
17711                    (match_operand 2 "register_operand" ""))
17712               (set (match_operand 0 "register_operand" "")
17713                    (match_operand 3 "" ""))
17714               (use (reg:SI DIRFLAG_REG))])]
17715   "TARGET_SINGLE_STRINGOP || optimize_size"
17716   "")
17718 (define_insn "*strsetdi_rex_1"
17719   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17720         (match_operand:DI 2 "register_operand" "a"))
17721    (set (match_operand:DI 0 "register_operand" "=D")
17722         (plus:DI (match_dup 1)
17723                  (const_int 8)))
17724    (use (reg:SI DIRFLAG_REG))]
17725   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17726   "stosq"
17727   [(set_attr "type" "str")
17728    (set_attr "memory" "store")
17729    (set_attr "mode" "DI")])
17731 (define_insn "*strsetsi_1"
17732   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17733         (match_operand:SI 2 "register_operand" "a"))
17734    (set (match_operand:SI 0 "register_operand" "=D")
17735         (plus:SI (match_dup 1)
17736                  (const_int 4)))
17737    (use (reg:SI DIRFLAG_REG))]
17738   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17739   "{stosl|stosd}"
17740   [(set_attr "type" "str")
17741    (set_attr "memory" "store")
17742    (set_attr "mode" "SI")])
17744 (define_insn "*strsetsi_rex_1"
17745   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17746         (match_operand:SI 2 "register_operand" "a"))
17747    (set (match_operand:DI 0 "register_operand" "=D")
17748         (plus:DI (match_dup 1)
17749                  (const_int 4)))
17750    (use (reg:SI DIRFLAG_REG))]
17751   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17752   "{stosl|stosd}"
17753   [(set_attr "type" "str")
17754    (set_attr "memory" "store")
17755    (set_attr "mode" "SI")])
17757 (define_insn "*strsethi_1"
17758   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17759         (match_operand:HI 2 "register_operand" "a"))
17760    (set (match_operand:SI 0 "register_operand" "=D")
17761         (plus:SI (match_dup 1)
17762                  (const_int 2)))
17763    (use (reg:SI DIRFLAG_REG))]
17764   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17765   "stosw"
17766   [(set_attr "type" "str")
17767    (set_attr "memory" "store")
17768    (set_attr "mode" "HI")])
17770 (define_insn "*strsethi_rex_1"
17771   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17772         (match_operand:HI 2 "register_operand" "a"))
17773    (set (match_operand:DI 0 "register_operand" "=D")
17774         (plus:DI (match_dup 1)
17775                  (const_int 2)))
17776    (use (reg:SI DIRFLAG_REG))]
17777   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17778   "stosw"
17779   [(set_attr "type" "str")
17780    (set_attr "memory" "store")
17781    (set_attr "mode" "HI")])
17783 (define_insn "*strsetqi_1"
17784   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17785         (match_operand:QI 2 "register_operand" "a"))
17786    (set (match_operand:SI 0 "register_operand" "=D")
17787         (plus:SI (match_dup 1)
17788                  (const_int 1)))
17789    (use (reg:SI DIRFLAG_REG))]
17790   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17791   "stosb"
17792   [(set_attr "type" "str")
17793    (set_attr "memory" "store")
17794    (set_attr "mode" "QI")])
17796 (define_insn "*strsetqi_rex_1"
17797   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17798         (match_operand:QI 2 "register_operand" "a"))
17799    (set (match_operand:DI 0 "register_operand" "=D")
17800         (plus:DI (match_dup 1)
17801                  (const_int 1)))
17802    (use (reg:SI DIRFLAG_REG))]
17803   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17804   "stosb"
17805   [(set_attr "type" "str")
17806    (set_attr "memory" "store")
17807    (set_attr "mode" "QI")])
17809 (define_expand "rep_stos"
17810   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17811               (set (match_operand 0 "register_operand" "")
17812                    (match_operand 4 "" ""))
17813               (set (match_operand 2 "memory_operand" "") (const_int 0))
17814               (use (match_operand 3 "register_operand" ""))
17815               (use (match_dup 1))
17816               (use (reg:SI DIRFLAG_REG))])]
17817   ""
17818   "")
17820 (define_insn "*rep_stosdi_rex64"
17821   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17822    (set (match_operand:DI 0 "register_operand" "=D") 
17823         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17824                             (const_int 3))
17825                  (match_operand:DI 3 "register_operand" "0")))
17826    (set (mem:BLK (match_dup 3))
17827         (const_int 0))
17828    (use (match_operand:DI 2 "register_operand" "a"))
17829    (use (match_dup 4))
17830    (use (reg:SI DIRFLAG_REG))]
17831   "TARGET_64BIT"
17832   "{rep\;stosq|rep stosq}"
17833   [(set_attr "type" "str")
17834    (set_attr "prefix_rep" "1")
17835    (set_attr "memory" "store")
17836    (set_attr "mode" "DI")])
17838 (define_insn "*rep_stossi"
17839   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17840    (set (match_operand:SI 0 "register_operand" "=D") 
17841         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17842                             (const_int 2))
17843                  (match_operand:SI 3 "register_operand" "0")))
17844    (set (mem:BLK (match_dup 3))
17845         (const_int 0))
17846    (use (match_operand:SI 2 "register_operand" "a"))
17847    (use (match_dup 4))
17848    (use (reg:SI DIRFLAG_REG))]
17849   "!TARGET_64BIT"
17850   "{rep\;stosl|rep stosd}"
17851   [(set_attr "type" "str")
17852    (set_attr "prefix_rep" "1")
17853    (set_attr "memory" "store")
17854    (set_attr "mode" "SI")])
17856 (define_insn "*rep_stossi_rex64"
17857   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17858    (set (match_operand:DI 0 "register_operand" "=D") 
17859         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17860                             (const_int 2))
17861                  (match_operand:DI 3 "register_operand" "0")))
17862    (set (mem:BLK (match_dup 3))
17863         (const_int 0))
17864    (use (match_operand:SI 2 "register_operand" "a"))
17865    (use (match_dup 4))
17866    (use (reg:SI DIRFLAG_REG))]
17867   "TARGET_64BIT"
17868   "{rep\;stosl|rep stosd}"
17869   [(set_attr "type" "str")
17870    (set_attr "prefix_rep" "1")
17871    (set_attr "memory" "store")
17872    (set_attr "mode" "SI")])
17874 (define_insn "*rep_stosqi"
17875   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17876    (set (match_operand:SI 0 "register_operand" "=D") 
17877         (plus:SI (match_operand:SI 3 "register_operand" "0")
17878                  (match_operand:SI 4 "register_operand" "1")))
17879    (set (mem:BLK (match_dup 3))
17880         (const_int 0))
17881    (use (match_operand:QI 2 "register_operand" "a"))
17882    (use (match_dup 4))
17883    (use (reg:SI DIRFLAG_REG))]
17884   "!TARGET_64BIT"
17885   "{rep\;stosb|rep stosb}"
17886   [(set_attr "type" "str")
17887    (set_attr "prefix_rep" "1")
17888    (set_attr "memory" "store")
17889    (set_attr "mode" "QI")])
17891 (define_insn "*rep_stosqi_rex64"
17892   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17893    (set (match_operand:DI 0 "register_operand" "=D") 
17894         (plus:DI (match_operand:DI 3 "register_operand" "0")
17895                  (match_operand:DI 4 "register_operand" "1")))
17896    (set (mem:BLK (match_dup 3))
17897         (const_int 0))
17898    (use (match_operand:QI 2 "register_operand" "a"))
17899    (use (match_dup 4))
17900    (use (reg:SI DIRFLAG_REG))]
17901   "TARGET_64BIT"
17902   "{rep\;stosb|rep stosb}"
17903   [(set_attr "type" "str")
17904    (set_attr "prefix_rep" "1")
17905    (set_attr "memory" "store")
17906    (set_attr "mode" "QI")])
17908 (define_expand "cmpstrnsi"
17909   [(set (match_operand:SI 0 "register_operand" "")
17910         (compare:SI (match_operand:BLK 1 "general_operand" "")
17911                     (match_operand:BLK 2 "general_operand" "")))
17912    (use (match_operand 3 "general_operand" ""))
17913    (use (match_operand 4 "immediate_operand" ""))]
17914   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17916   rtx addr1, addr2, out, outlow, count, countreg, align;
17918   /* Can't use this if the user has appropriated esi or edi.  */
17919   if (global_regs[4] || global_regs[5])
17920     FAIL;
17922   out = operands[0];
17923   if (GET_CODE (out) != REG)
17924     out = gen_reg_rtx (SImode);
17926   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17927   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17928   if (addr1 != XEXP (operands[1], 0))
17929     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17930   if (addr2 != XEXP (operands[2], 0))
17931     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17933   count = operands[3];
17934   countreg = ix86_zero_extend_to_Pmode (count);
17936   /* %%% Iff we are testing strict equality, we can use known alignment
17937      to good advantage.  This may be possible with combine, particularly
17938      once cc0 is dead.  */
17939   align = operands[4];
17941   emit_insn (gen_cld ());
17942   if (GET_CODE (count) == CONST_INT)
17943     {
17944       if (INTVAL (count) == 0)
17945         {
17946           emit_move_insn (operands[0], const0_rtx);
17947           DONE;
17948         }
17949       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17950                                      operands[1], operands[2]));
17951     }
17952   else
17953     {
17954       if (TARGET_64BIT)
17955         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17956       else
17957         emit_insn (gen_cmpsi_1 (countreg, countreg));
17958       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17959                                   operands[1], operands[2]));
17960     }
17962   outlow = gen_lowpart (QImode, out);
17963   emit_insn (gen_cmpintqi (outlow));
17964   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17966   if (operands[0] != out)
17967     emit_move_insn (operands[0], out);
17969   DONE;
17972 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17974 (define_expand "cmpintqi"
17975   [(set (match_dup 1)
17976         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17977    (set (match_dup 2)
17978         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17979    (parallel [(set (match_operand:QI 0 "register_operand" "")
17980                    (minus:QI (match_dup 1)
17981                              (match_dup 2)))
17982               (clobber (reg:CC FLAGS_REG))])]
17983   ""
17984   "operands[1] = gen_reg_rtx (QImode);
17985    operands[2] = gen_reg_rtx (QImode);")
17987 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17988 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17990 (define_expand "cmpstrnqi_nz_1"
17991   [(parallel [(set (reg:CC FLAGS_REG)
17992                    (compare:CC (match_operand 4 "memory_operand" "")
17993                                (match_operand 5 "memory_operand" "")))
17994               (use (match_operand 2 "register_operand" ""))
17995               (use (match_operand:SI 3 "immediate_operand" ""))
17996               (use (reg:SI DIRFLAG_REG))
17997               (clobber (match_operand 0 "register_operand" ""))
17998               (clobber (match_operand 1 "register_operand" ""))
17999               (clobber (match_dup 2))])]
18000   ""
18001   "")
18003 (define_insn "*cmpstrnqi_nz_1"
18004   [(set (reg:CC FLAGS_REG)
18005         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18006                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18007    (use (match_operand:SI 6 "register_operand" "2"))
18008    (use (match_operand:SI 3 "immediate_operand" "i"))
18009    (use (reg:SI DIRFLAG_REG))
18010    (clobber (match_operand:SI 0 "register_operand" "=S"))
18011    (clobber (match_operand:SI 1 "register_operand" "=D"))
18012    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18013   "!TARGET_64BIT"
18014   "repz{\;| }cmpsb"
18015   [(set_attr "type" "str")
18016    (set_attr "mode" "QI")
18017    (set_attr "prefix_rep" "1")])
18019 (define_insn "*cmpstrnqi_nz_rex_1"
18020   [(set (reg:CC FLAGS_REG)
18021         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18022                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18023    (use (match_operand:DI 6 "register_operand" "2"))
18024    (use (match_operand:SI 3 "immediate_operand" "i"))
18025    (use (reg:SI DIRFLAG_REG))
18026    (clobber (match_operand:DI 0 "register_operand" "=S"))
18027    (clobber (match_operand:DI 1 "register_operand" "=D"))
18028    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18029   "TARGET_64BIT"
18030   "repz{\;| }cmpsb"
18031   [(set_attr "type" "str")
18032    (set_attr "mode" "QI")
18033    (set_attr "prefix_rep" "1")])
18035 ;; The same, but the count is not known to not be zero.
18037 (define_expand "cmpstrnqi_1"
18038   [(parallel [(set (reg:CC FLAGS_REG)
18039                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18040                                      (const_int 0))
18041                   (compare:CC (match_operand 4 "memory_operand" "")
18042                               (match_operand 5 "memory_operand" ""))
18043                   (const_int 0)))
18044               (use (match_operand:SI 3 "immediate_operand" ""))
18045               (use (reg:CC FLAGS_REG))
18046               (use (reg:SI DIRFLAG_REG))
18047               (clobber (match_operand 0 "register_operand" ""))
18048               (clobber (match_operand 1 "register_operand" ""))
18049               (clobber (match_dup 2))])]
18050   ""
18051   "")
18053 (define_insn "*cmpstrnqi_1"
18054   [(set (reg:CC FLAGS_REG)
18055         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18056                              (const_int 0))
18057           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18058                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18059           (const_int 0)))
18060    (use (match_operand:SI 3 "immediate_operand" "i"))
18061    (use (reg:CC FLAGS_REG))
18062    (use (reg:SI DIRFLAG_REG))
18063    (clobber (match_operand:SI 0 "register_operand" "=S"))
18064    (clobber (match_operand:SI 1 "register_operand" "=D"))
18065    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18066   "!TARGET_64BIT"
18067   "repz{\;| }cmpsb"
18068   [(set_attr "type" "str")
18069    (set_attr "mode" "QI")
18070    (set_attr "prefix_rep" "1")])
18072 (define_insn "*cmpstrnqi_rex_1"
18073   [(set (reg:CC FLAGS_REG)
18074         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18075                              (const_int 0))
18076           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18077                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18078           (const_int 0)))
18079    (use (match_operand:SI 3 "immediate_operand" "i"))
18080    (use (reg:CC FLAGS_REG))
18081    (use (reg:SI DIRFLAG_REG))
18082    (clobber (match_operand:DI 0 "register_operand" "=S"))
18083    (clobber (match_operand:DI 1 "register_operand" "=D"))
18084    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18085   "TARGET_64BIT"
18086   "repz{\;| }cmpsb"
18087   [(set_attr "type" "str")
18088    (set_attr "mode" "QI")
18089    (set_attr "prefix_rep" "1")])
18091 (define_expand "strlensi"
18092   [(set (match_operand:SI 0 "register_operand" "")
18093         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18094                     (match_operand:QI 2 "immediate_operand" "")
18095                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18096   ""
18098  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18099    DONE;
18100  else
18101    FAIL;
18104 (define_expand "strlendi"
18105   [(set (match_operand:DI 0 "register_operand" "")
18106         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18107                     (match_operand:QI 2 "immediate_operand" "")
18108                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18109   ""
18111  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18112    DONE;
18113  else
18114    FAIL;
18117 (define_expand "strlenqi_1"
18118   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18119               (use (reg:SI DIRFLAG_REG))
18120               (clobber (match_operand 1 "register_operand" ""))
18121               (clobber (reg:CC FLAGS_REG))])]
18122   ""
18123   "")
18125 (define_insn "*strlenqi_1"
18126   [(set (match_operand:SI 0 "register_operand" "=&c")
18127         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18128                     (match_operand:QI 2 "register_operand" "a")
18129                     (match_operand:SI 3 "immediate_operand" "i")
18130                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18131    (use (reg:SI DIRFLAG_REG))
18132    (clobber (match_operand:SI 1 "register_operand" "=D"))
18133    (clobber (reg:CC FLAGS_REG))]
18134   "!TARGET_64BIT"
18135   "repnz{\;| }scasb"
18136   [(set_attr "type" "str")
18137    (set_attr "mode" "QI")
18138    (set_attr "prefix_rep" "1")])
18140 (define_insn "*strlenqi_rex_1"
18141   [(set (match_operand:DI 0 "register_operand" "=&c")
18142         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18143                     (match_operand:QI 2 "register_operand" "a")
18144                     (match_operand:DI 3 "immediate_operand" "i")
18145                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18146    (use (reg:SI DIRFLAG_REG))
18147    (clobber (match_operand:DI 1 "register_operand" "=D"))
18148    (clobber (reg:CC FLAGS_REG))]
18149   "TARGET_64BIT"
18150   "repnz{\;| }scasb"
18151   [(set_attr "type" "str")
18152    (set_attr "mode" "QI")
18153    (set_attr "prefix_rep" "1")])
18155 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18156 ;; handled in combine, but it is not currently up to the task.
18157 ;; When used for their truth value, the cmpstrn* expanders generate
18158 ;; code like this:
18160 ;;   repz cmpsb
18161 ;;   seta       %al
18162 ;;   setb       %dl
18163 ;;   cmpb       %al, %dl
18164 ;;   jcc        label
18166 ;; The intermediate three instructions are unnecessary.
18168 ;; This one handles cmpstrn*_nz_1...
18169 (define_peephole2
18170   [(parallel[
18171      (set (reg:CC FLAGS_REG)
18172           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18173                       (mem:BLK (match_operand 5 "register_operand" ""))))
18174      (use (match_operand 6 "register_operand" ""))
18175      (use (match_operand:SI 3 "immediate_operand" ""))
18176      (use (reg:SI DIRFLAG_REG))
18177      (clobber (match_operand 0 "register_operand" ""))
18178      (clobber (match_operand 1 "register_operand" ""))
18179      (clobber (match_operand 2 "register_operand" ""))])
18180    (set (match_operand:QI 7 "register_operand" "")
18181         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18182    (set (match_operand:QI 8 "register_operand" "")
18183         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18184    (set (reg FLAGS_REG)
18185         (compare (match_dup 7) (match_dup 8)))
18186   ]
18187   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18188   [(parallel[
18189      (set (reg:CC FLAGS_REG)
18190           (compare:CC (mem:BLK (match_dup 4))
18191                       (mem:BLK (match_dup 5))))
18192      (use (match_dup 6))
18193      (use (match_dup 3))
18194      (use (reg:SI DIRFLAG_REG))
18195      (clobber (match_dup 0))
18196      (clobber (match_dup 1))
18197      (clobber (match_dup 2))])]
18198   "")
18200 ;; ...and this one handles cmpstrn*_1.
18201 (define_peephole2
18202   [(parallel[
18203      (set (reg:CC FLAGS_REG)
18204           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18205                                (const_int 0))
18206             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18207                         (mem:BLK (match_operand 5 "register_operand" "")))
18208             (const_int 0)))
18209      (use (match_operand:SI 3 "immediate_operand" ""))
18210      (use (reg:CC FLAGS_REG))
18211      (use (reg:SI DIRFLAG_REG))
18212      (clobber (match_operand 0 "register_operand" ""))
18213      (clobber (match_operand 1 "register_operand" ""))
18214      (clobber (match_operand 2 "register_operand" ""))])
18215    (set (match_operand:QI 7 "register_operand" "")
18216         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18217    (set (match_operand:QI 8 "register_operand" "")
18218         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18219    (set (reg FLAGS_REG)
18220         (compare (match_dup 7) (match_dup 8)))
18221   ]
18222   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18223   [(parallel[
18224      (set (reg:CC FLAGS_REG)
18225           (if_then_else:CC (ne (match_dup 6)
18226                                (const_int 0))
18227             (compare:CC (mem:BLK (match_dup 4))
18228                         (mem:BLK (match_dup 5)))
18229             (const_int 0)))
18230      (use (match_dup 3))
18231      (use (reg:CC FLAGS_REG))
18232      (use (reg:SI DIRFLAG_REG))
18233      (clobber (match_dup 0))
18234      (clobber (match_dup 1))
18235      (clobber (match_dup 2))])]
18236   "")
18240 ;; Conditional move instructions.
18242 (define_expand "movdicc"
18243   [(set (match_operand:DI 0 "register_operand" "")
18244         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18245                          (match_operand:DI 2 "general_operand" "")
18246                          (match_operand:DI 3 "general_operand" "")))]
18247   "TARGET_64BIT"
18248   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18250 (define_insn "x86_movdicc_0_m1_rex64"
18251   [(set (match_operand:DI 0 "register_operand" "=r")
18252         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18253           (const_int -1)
18254           (const_int 0)))
18255    (clobber (reg:CC FLAGS_REG))]
18256   "TARGET_64BIT"
18257   "sbb{q}\t%0, %0"
18258   ; Since we don't have the proper number of operands for an alu insn,
18259   ; fill in all the blanks.
18260   [(set_attr "type" "alu")
18261    (set_attr "pent_pair" "pu")
18262    (set_attr "memory" "none")
18263    (set_attr "imm_disp" "false")
18264    (set_attr "mode" "DI")
18265    (set_attr "length_immediate" "0")])
18267 (define_insn "*movdicc_c_rex64"
18268   [(set (match_operand:DI 0 "register_operand" "=r,r")
18269         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18270                                 [(reg FLAGS_REG) (const_int 0)])
18271                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18272                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18273   "TARGET_64BIT && TARGET_CMOVE
18274    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18275   "@
18276    cmov%O2%C1\t{%2, %0|%0, %2}
18277    cmov%O2%c1\t{%3, %0|%0, %3}"
18278   [(set_attr "type" "icmov")
18279    (set_attr "mode" "DI")])
18281 (define_expand "movsicc"
18282   [(set (match_operand:SI 0 "register_operand" "")
18283         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18284                          (match_operand:SI 2 "general_operand" "")
18285                          (match_operand:SI 3 "general_operand" "")))]
18286   ""
18287   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18289 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18290 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18291 ;; So just document what we're doing explicitly.
18293 (define_insn "x86_movsicc_0_m1"
18294   [(set (match_operand:SI 0 "register_operand" "=r")
18295         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18296           (const_int -1)
18297           (const_int 0)))
18298    (clobber (reg:CC FLAGS_REG))]
18299   ""
18300   "sbb{l}\t%0, %0"
18301   ; Since we don't have the proper number of operands for an alu insn,
18302   ; fill in all the blanks.
18303   [(set_attr "type" "alu")
18304    (set_attr "pent_pair" "pu")
18305    (set_attr "memory" "none")
18306    (set_attr "imm_disp" "false")
18307    (set_attr "mode" "SI")
18308    (set_attr "length_immediate" "0")])
18310 (define_insn "*movsicc_noc"
18311   [(set (match_operand:SI 0 "register_operand" "=r,r")
18312         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18313                                 [(reg FLAGS_REG) (const_int 0)])
18314                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18315                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18316   "TARGET_CMOVE
18317    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18318   "@
18319    cmov%O2%C1\t{%2, %0|%0, %2}
18320    cmov%O2%c1\t{%3, %0|%0, %3}"
18321   [(set_attr "type" "icmov")
18322    (set_attr "mode" "SI")])
18324 (define_expand "movhicc"
18325   [(set (match_operand:HI 0 "register_operand" "")
18326         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18327                          (match_operand:HI 2 "general_operand" "")
18328                          (match_operand:HI 3 "general_operand" "")))]
18329   "TARGET_HIMODE_MATH"
18330   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18332 (define_insn "*movhicc_noc"
18333   [(set (match_operand:HI 0 "register_operand" "=r,r")
18334         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18335                                 [(reg FLAGS_REG) (const_int 0)])
18336                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18337                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18338   "TARGET_CMOVE
18339    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18340   "@
18341    cmov%O2%C1\t{%2, %0|%0, %2}
18342    cmov%O2%c1\t{%3, %0|%0, %3}"
18343   [(set_attr "type" "icmov")
18344    (set_attr "mode" "HI")])
18346 (define_expand "movqicc"
18347   [(set (match_operand:QI 0 "register_operand" "")
18348         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18349                          (match_operand:QI 2 "general_operand" "")
18350                          (match_operand:QI 3 "general_operand" "")))]
18351   "TARGET_QIMODE_MATH"
18352   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18354 (define_insn_and_split "*movqicc_noc"
18355   [(set (match_operand:QI 0 "register_operand" "=r,r")
18356         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18357                                 [(match_operand 4 "flags_reg_operand" "")
18358                                  (const_int 0)])
18359                       (match_operand:QI 2 "register_operand" "r,0")
18360                       (match_operand:QI 3 "register_operand" "0,r")))]
18361   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18362   "#"
18363   "&& reload_completed"
18364   [(set (match_dup 0)
18365         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18366                       (match_dup 2)
18367                       (match_dup 3)))]
18368   "operands[0] = gen_lowpart (SImode, operands[0]);
18369    operands[2] = gen_lowpart (SImode, operands[2]);
18370    operands[3] = gen_lowpart (SImode, operands[3]);"
18371   [(set_attr "type" "icmov")
18372    (set_attr "mode" "SI")])
18374 (define_expand "movsfcc"
18375   [(set (match_operand:SF 0 "register_operand" "")
18376         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18377                          (match_operand:SF 2 "register_operand" "")
18378                          (match_operand:SF 3 "register_operand" "")))]
18379   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18380   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18382 (define_insn "*movsfcc_1_387"
18383   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18384         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18385                                 [(reg FLAGS_REG) (const_int 0)])
18386                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18387                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18388   "TARGET_80387 && TARGET_CMOVE
18389    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18390   "@
18391    fcmov%F1\t{%2, %0|%0, %2}
18392    fcmov%f1\t{%3, %0|%0, %3}
18393    cmov%O2%C1\t{%2, %0|%0, %2}
18394    cmov%O2%c1\t{%3, %0|%0, %3}"
18395   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18396    (set_attr "mode" "SF,SF,SI,SI")])
18398 (define_expand "movdfcc"
18399   [(set (match_operand:DF 0 "register_operand" "")
18400         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18401                          (match_operand:DF 2 "register_operand" "")
18402                          (match_operand:DF 3 "register_operand" "")))]
18403   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18404   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18406 (define_insn "*movdfcc_1"
18407   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18408         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18409                                 [(reg FLAGS_REG) (const_int 0)])
18410                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18411                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18412   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18413    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18414   "@
18415    fcmov%F1\t{%2, %0|%0, %2}
18416    fcmov%f1\t{%3, %0|%0, %3}
18417    #
18418    #"
18419   [(set_attr "type" "fcmov,fcmov,multi,multi")
18420    (set_attr "mode" "DF")])
18422 (define_insn "*movdfcc_1_rex64"
18423   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18424         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18425                                 [(reg FLAGS_REG) (const_int 0)])
18426                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18427                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18428   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18429    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18430   "@
18431    fcmov%F1\t{%2, %0|%0, %2}
18432    fcmov%f1\t{%3, %0|%0, %3}
18433    cmov%O2%C1\t{%2, %0|%0, %2}
18434    cmov%O2%c1\t{%3, %0|%0, %3}"
18435   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18436    (set_attr "mode" "DF")])
18438 (define_split
18439   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18440         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18441                                 [(match_operand 4 "flags_reg_operand" "")
18442                                  (const_int 0)])
18443                       (match_operand:DF 2 "nonimmediate_operand" "")
18444                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18445   "!TARGET_64BIT && reload_completed"
18446   [(set (match_dup 2)
18447         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18448                       (match_dup 5)
18449                       (match_dup 7)))
18450    (set (match_dup 3)
18451         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18452                       (match_dup 6)
18453                       (match_dup 8)))]
18454   "split_di (operands+2, 1, operands+5, operands+6);
18455    split_di (operands+3, 1, operands+7, operands+8);
18456    split_di (operands, 1, operands+2, operands+3);")
18458 (define_expand "movxfcc"
18459   [(set (match_operand:XF 0 "register_operand" "")
18460         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18461                          (match_operand:XF 2 "register_operand" "")
18462                          (match_operand:XF 3 "register_operand" "")))]
18463   "TARGET_80387 && TARGET_CMOVE"
18464   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18466 (define_insn "*movxfcc_1"
18467   [(set (match_operand:XF 0 "register_operand" "=f,f")
18468         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18469                                 [(reg FLAGS_REG) (const_int 0)])
18470                       (match_operand:XF 2 "register_operand" "f,0")
18471                       (match_operand:XF 3 "register_operand" "0,f")))]
18472   "TARGET_80387 && TARGET_CMOVE"
18473   "@
18474    fcmov%F1\t{%2, %0|%0, %2}
18475    fcmov%f1\t{%3, %0|%0, %3}"
18476   [(set_attr "type" "fcmov")
18477    (set_attr "mode" "XF")])
18479 ;; These versions of the min/max patterns are intentionally ignorant of
18480 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18481 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18482 ;; are undefined in this condition, we're certain this is correct.
18484 (define_insn "sminsf3"
18485   [(set (match_operand:SF 0 "register_operand" "=x")
18486         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18487                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18488   "TARGET_SSE_MATH"
18489   "minss\t{%2, %0|%0, %2}"
18490   [(set_attr "type" "sseadd")
18491    (set_attr "mode" "SF")])
18493 (define_insn "smaxsf3"
18494   [(set (match_operand:SF 0 "register_operand" "=x")
18495         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18496                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18497   "TARGET_SSE_MATH"
18498   "maxss\t{%2, %0|%0, %2}"
18499   [(set_attr "type" "sseadd")
18500    (set_attr "mode" "SF")])
18502 (define_insn "smindf3"
18503   [(set (match_operand:DF 0 "register_operand" "=x")
18504         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18505                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18506   "TARGET_SSE2 && TARGET_SSE_MATH"
18507   "minsd\t{%2, %0|%0, %2}"
18508   [(set_attr "type" "sseadd")
18509    (set_attr "mode" "DF")])
18511 (define_insn "smaxdf3"
18512   [(set (match_operand:DF 0 "register_operand" "=x")
18513         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18514                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18515   "TARGET_SSE2 && TARGET_SSE_MATH"
18516   "maxsd\t{%2, %0|%0, %2}"
18517   [(set_attr "type" "sseadd")
18518    (set_attr "mode" "DF")])
18520 ;; These versions of the min/max patterns implement exactly the operations
18521 ;;   min = (op1 < op2 ? op1 : op2)
18522 ;;   max = (!(op1 < op2) ? op1 : op2)
18523 ;; Their operands are not commutative, and thus they may be used in the
18524 ;; presence of -0.0 and NaN.
18526 (define_insn "*ieee_sminsf3"
18527   [(set (match_operand:SF 0 "register_operand" "=x")
18528         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18529                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18530                    UNSPEC_IEEE_MIN))]
18531   "TARGET_SSE_MATH"
18532   "minss\t{%2, %0|%0, %2}"
18533   [(set_attr "type" "sseadd")
18534    (set_attr "mode" "SF")])
18536 (define_insn "*ieee_smaxsf3"
18537   [(set (match_operand:SF 0 "register_operand" "=x")
18538         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18539                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18540                    UNSPEC_IEEE_MAX))]
18541   "TARGET_SSE_MATH"
18542   "maxss\t{%2, %0|%0, %2}"
18543   [(set_attr "type" "sseadd")
18544    (set_attr "mode" "SF")])
18546 (define_insn "*ieee_smindf3"
18547   [(set (match_operand:DF 0 "register_operand" "=x")
18548         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18549                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18550                    UNSPEC_IEEE_MIN))]
18551   "TARGET_SSE2 && TARGET_SSE_MATH"
18552   "minsd\t{%2, %0|%0, %2}"
18553   [(set_attr "type" "sseadd")
18554    (set_attr "mode" "DF")])
18556 (define_insn "*ieee_smaxdf3"
18557   [(set (match_operand:DF 0 "register_operand" "=x")
18558         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18559                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18560                    UNSPEC_IEEE_MAX))]
18561   "TARGET_SSE2 && TARGET_SSE_MATH"
18562   "maxsd\t{%2, %0|%0, %2}"
18563   [(set_attr "type" "sseadd")
18564    (set_attr "mode" "DF")])
18566 ;; Conditional addition patterns
18567 (define_expand "addqicc"
18568   [(match_operand:QI 0 "register_operand" "")
18569    (match_operand 1 "comparison_operator" "")
18570    (match_operand:QI 2 "register_operand" "")
18571    (match_operand:QI 3 "const_int_operand" "")]
18572   ""
18573   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18575 (define_expand "addhicc"
18576   [(match_operand:HI 0 "register_operand" "")
18577    (match_operand 1 "comparison_operator" "")
18578    (match_operand:HI 2 "register_operand" "")
18579    (match_operand:HI 3 "const_int_operand" "")]
18580   ""
18581   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18583 (define_expand "addsicc"
18584   [(match_operand:SI 0 "register_operand" "")
18585    (match_operand 1 "comparison_operator" "")
18586    (match_operand:SI 2 "register_operand" "")
18587    (match_operand:SI 3 "const_int_operand" "")]
18588   ""
18589   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18591 (define_expand "adddicc"
18592   [(match_operand:DI 0 "register_operand" "")
18593    (match_operand 1 "comparison_operator" "")
18594    (match_operand:DI 2 "register_operand" "")
18595    (match_operand:DI 3 "const_int_operand" "")]
18596   "TARGET_64BIT"
18597   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18600 ;; Misc patterns (?)
18602 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18603 ;; Otherwise there will be nothing to keep
18604 ;; 
18605 ;; [(set (reg ebp) (reg esp))]
18606 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18607 ;;  (clobber (eflags)]
18608 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18610 ;; in proper program order.
18611 (define_insn "pro_epilogue_adjust_stack_1"
18612   [(set (match_operand:SI 0 "register_operand" "=r,r")
18613         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18614                  (match_operand:SI 2 "immediate_operand" "i,i")))
18615    (clobber (reg:CC FLAGS_REG))
18616    (clobber (mem:BLK (scratch)))]
18617   "!TARGET_64BIT"
18619   switch (get_attr_type (insn))
18620     {
18621     case TYPE_IMOV:
18622       return "mov{l}\t{%1, %0|%0, %1}";
18624     case TYPE_ALU:
18625       if (GET_CODE (operands[2]) == CONST_INT
18626           && (INTVAL (operands[2]) == 128
18627               || (INTVAL (operands[2]) < 0
18628                   && INTVAL (operands[2]) != -128)))
18629         {
18630           operands[2] = GEN_INT (-INTVAL (operands[2]));
18631           return "sub{l}\t{%2, %0|%0, %2}";
18632         }
18633       return "add{l}\t{%2, %0|%0, %2}";
18635     case TYPE_LEA:
18636       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18637       return "lea{l}\t{%a2, %0|%0, %a2}";
18639     default:
18640       gcc_unreachable ();
18641     }
18643   [(set (attr "type")
18644         (cond [(eq_attr "alternative" "0")
18645                  (const_string "alu")
18646                (match_operand:SI 2 "const0_operand" "")
18647                  (const_string "imov")
18648               ]
18649               (const_string "lea")))
18650    (set_attr "mode" "SI")])
18652 (define_insn "pro_epilogue_adjust_stack_rex64"
18653   [(set (match_operand:DI 0 "register_operand" "=r,r")
18654         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18655                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18656    (clobber (reg:CC FLAGS_REG))
18657    (clobber (mem:BLK (scratch)))]
18658   "TARGET_64BIT"
18660   switch (get_attr_type (insn))
18661     {
18662     case TYPE_IMOV:
18663       return "mov{q}\t{%1, %0|%0, %1}";
18665     case TYPE_ALU:
18666       if (GET_CODE (operands[2]) == CONST_INT
18667           /* Avoid overflows.  */
18668           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18669           && (INTVAL (operands[2]) == 128
18670               || (INTVAL (operands[2]) < 0
18671                   && INTVAL (operands[2]) != -128)))
18672         {
18673           operands[2] = GEN_INT (-INTVAL (operands[2]));
18674           return "sub{q}\t{%2, %0|%0, %2}";
18675         }
18676       return "add{q}\t{%2, %0|%0, %2}";
18678     case TYPE_LEA:
18679       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18680       return "lea{q}\t{%a2, %0|%0, %a2}";
18682     default:
18683       gcc_unreachable ();
18684     }
18686   [(set (attr "type")
18687         (cond [(eq_attr "alternative" "0")
18688                  (const_string "alu")
18689                (match_operand:DI 2 "const0_operand" "")
18690                  (const_string "imov")
18691               ]
18692               (const_string "lea")))
18693    (set_attr "mode" "DI")])
18695 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18696   [(set (match_operand:DI 0 "register_operand" "=r,r")
18697         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18698                  (match_operand:DI 3 "immediate_operand" "i,i")))
18699    (use (match_operand:DI 2 "register_operand" "r,r"))
18700    (clobber (reg:CC FLAGS_REG))
18701    (clobber (mem:BLK (scratch)))]
18702   "TARGET_64BIT"
18704   switch (get_attr_type (insn))
18705     {
18706     case TYPE_ALU:
18707       return "add{q}\t{%2, %0|%0, %2}";
18709     case TYPE_LEA:
18710       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18711       return "lea{q}\t{%a2, %0|%0, %a2}";
18713     default:
18714       gcc_unreachable ();
18715     }
18717   [(set_attr "type" "alu,lea")
18718    (set_attr "mode" "DI")])
18720 (define_expand "allocate_stack_worker"
18721   [(match_operand:SI 0 "register_operand" "")]
18722   "TARGET_STACK_PROBE"
18724   if (reload_completed)
18725     {
18726       if (TARGET_64BIT)
18727         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18728       else
18729         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18730     }
18731   else
18732     {
18733       if (TARGET_64BIT)
18734         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18735       else
18736         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18737     }
18738   DONE;
18741 (define_insn "allocate_stack_worker_1"
18742   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18743     UNSPECV_STACK_PROBE)
18744    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18745    (clobber (match_scratch:SI 1 "=0"))
18746    (clobber (reg:CC FLAGS_REG))]
18747   "!TARGET_64BIT && TARGET_STACK_PROBE"
18748   "call\t__alloca"
18749   [(set_attr "type" "multi")
18750    (set_attr "length" "5")])
18752 (define_expand "allocate_stack_worker_postreload"
18753   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18754                                     UNSPECV_STACK_PROBE)
18755               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18756               (clobber (match_dup 0))
18757               (clobber (reg:CC FLAGS_REG))])]
18758   ""
18759   "")
18761 (define_insn "allocate_stack_worker_rex64"
18762   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18763     UNSPECV_STACK_PROBE)
18764    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18765    (clobber (match_scratch:DI 1 "=0"))
18766    (clobber (reg:CC FLAGS_REG))]
18767   "TARGET_64BIT && TARGET_STACK_PROBE"
18768   "call\t__alloca"
18769   [(set_attr "type" "multi")
18770    (set_attr "length" "5")])
18772 (define_expand "allocate_stack_worker_rex64_postreload"
18773   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18774                                     UNSPECV_STACK_PROBE)
18775               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18776               (clobber (match_dup 0))
18777               (clobber (reg:CC FLAGS_REG))])]
18778   ""
18779   "")
18781 (define_expand "allocate_stack"
18782   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18783                    (minus:SI (reg:SI SP_REG)
18784                              (match_operand:SI 1 "general_operand" "")))
18785               (clobber (reg:CC FLAGS_REG))])
18786    (parallel [(set (reg:SI SP_REG)
18787                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18788               (clobber (reg:CC FLAGS_REG))])]
18789   "TARGET_STACK_PROBE"
18791 #ifdef CHECK_STACK_LIMIT
18792   if (GET_CODE (operands[1]) == CONST_INT
18793       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18794     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18795                            operands[1]));
18796   else 
18797 #endif
18798     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18799                                                             operands[1])));
18801   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18802   DONE;
18805 (define_expand "builtin_setjmp_receiver"
18806   [(label_ref (match_operand 0 "" ""))]
18807   "!TARGET_64BIT && flag_pic"
18809   emit_insn (gen_set_got (pic_offset_table_rtx));
18810   DONE;
18813 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18815 (define_split
18816   [(set (match_operand 0 "register_operand" "")
18817         (match_operator 3 "promotable_binary_operator"
18818            [(match_operand 1 "register_operand" "")
18819             (match_operand 2 "aligned_operand" "")]))
18820    (clobber (reg:CC FLAGS_REG))]
18821   "! TARGET_PARTIAL_REG_STALL && reload_completed
18822    && ((GET_MODE (operands[0]) == HImode 
18823         && ((!optimize_size && !TARGET_FAST_PREFIX)
18824             || GET_CODE (operands[2]) != CONST_INT
18825             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18826        || (GET_MODE (operands[0]) == QImode 
18827            && (TARGET_PROMOTE_QImode || optimize_size)))"
18828   [(parallel [(set (match_dup 0)
18829                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18830               (clobber (reg:CC FLAGS_REG))])]
18831   "operands[0] = gen_lowpart (SImode, operands[0]);
18832    operands[1] = gen_lowpart (SImode, operands[1]);
18833    if (GET_CODE (operands[3]) != ASHIFT)
18834      operands[2] = gen_lowpart (SImode, operands[2]);
18835    PUT_MODE (operands[3], SImode);")
18837 ; Promote the QImode tests, as i386 has encoding of the AND
18838 ; instruction with 32-bit sign-extended immediate and thus the
18839 ; instruction size is unchanged, except in the %eax case for
18840 ; which it is increased by one byte, hence the ! optimize_size.
18841 (define_split
18842   [(set (match_operand 0 "flags_reg_operand" "")
18843         (match_operator 2 "compare_operator"
18844           [(and (match_operand 3 "aligned_operand" "")
18845                 (match_operand 4 "const_int_operand" ""))
18846            (const_int 0)]))
18847    (set (match_operand 1 "register_operand" "")
18848         (and (match_dup 3) (match_dup 4)))]
18849   "! TARGET_PARTIAL_REG_STALL && reload_completed
18850    /* Ensure that the operand will remain sign-extended immediate.  */
18851    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18852    && ! optimize_size
18853    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18854        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18855   [(parallel [(set (match_dup 0)
18856                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18857                                     (const_int 0)]))
18858               (set (match_dup 1)
18859                    (and:SI (match_dup 3) (match_dup 4)))])]
18861   operands[4]
18862     = gen_int_mode (INTVAL (operands[4])
18863                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18864   operands[1] = gen_lowpart (SImode, operands[1]);
18865   operands[3] = gen_lowpart (SImode, operands[3]);
18868 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18869 ; the TEST instruction with 32-bit sign-extended immediate and thus
18870 ; the instruction size would at least double, which is not what we
18871 ; want even with ! optimize_size.
18872 (define_split
18873   [(set (match_operand 0 "flags_reg_operand" "")
18874         (match_operator 1 "compare_operator"
18875           [(and (match_operand:HI 2 "aligned_operand" "")
18876                 (match_operand:HI 3 "const_int_operand" ""))
18877            (const_int 0)]))]
18878   "! TARGET_PARTIAL_REG_STALL && reload_completed
18879    /* Ensure that the operand will remain sign-extended immediate.  */
18880    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18881    && ! TARGET_FAST_PREFIX
18882    && ! optimize_size"
18883   [(set (match_dup 0)
18884         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18885                          (const_int 0)]))]
18887   operands[3]
18888     = gen_int_mode (INTVAL (operands[3])
18889                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18890   operands[2] = gen_lowpart (SImode, operands[2]);
18893 (define_split
18894   [(set (match_operand 0 "register_operand" "")
18895         (neg (match_operand 1 "register_operand" "")))
18896    (clobber (reg:CC FLAGS_REG))]
18897   "! TARGET_PARTIAL_REG_STALL && reload_completed
18898    && (GET_MODE (operands[0]) == HImode
18899        || (GET_MODE (operands[0]) == QImode 
18900            && (TARGET_PROMOTE_QImode || optimize_size)))"
18901   [(parallel [(set (match_dup 0)
18902                    (neg:SI (match_dup 1)))
18903               (clobber (reg:CC FLAGS_REG))])]
18904   "operands[0] = gen_lowpart (SImode, operands[0]);
18905    operands[1] = gen_lowpart (SImode, operands[1]);")
18907 (define_split
18908   [(set (match_operand 0 "register_operand" "")
18909         (not (match_operand 1 "register_operand" "")))]
18910   "! TARGET_PARTIAL_REG_STALL && reload_completed
18911    && (GET_MODE (operands[0]) == HImode
18912        || (GET_MODE (operands[0]) == QImode 
18913            && (TARGET_PROMOTE_QImode || optimize_size)))"
18914   [(set (match_dup 0)
18915         (not:SI (match_dup 1)))]
18916   "operands[0] = gen_lowpart (SImode, operands[0]);
18917    operands[1] = gen_lowpart (SImode, operands[1]);")
18919 (define_split 
18920   [(set (match_operand 0 "register_operand" "")
18921         (if_then_else (match_operator 1 "comparison_operator" 
18922                                 [(reg FLAGS_REG) (const_int 0)])
18923                       (match_operand 2 "register_operand" "")
18924                       (match_operand 3 "register_operand" "")))]
18925   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18926    && (GET_MODE (operands[0]) == HImode
18927        || (GET_MODE (operands[0]) == QImode 
18928            && (TARGET_PROMOTE_QImode || optimize_size)))"
18929   [(set (match_dup 0)
18930         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18931   "operands[0] = gen_lowpart (SImode, operands[0]);
18932    operands[2] = gen_lowpart (SImode, operands[2]);
18933    operands[3] = gen_lowpart (SImode, operands[3]);")
18934                         
18936 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18937 ;; transform a complex memory operation into two memory to register operations.
18939 ;; Don't push memory operands
18940 (define_peephole2
18941   [(set (match_operand:SI 0 "push_operand" "")
18942         (match_operand:SI 1 "memory_operand" ""))
18943    (match_scratch:SI 2 "r")]
18944   "!optimize_size && !TARGET_PUSH_MEMORY
18945    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18946   [(set (match_dup 2) (match_dup 1))
18947    (set (match_dup 0) (match_dup 2))]
18948   "")
18950 (define_peephole2
18951   [(set (match_operand:DI 0 "push_operand" "")
18952         (match_operand:DI 1 "memory_operand" ""))
18953    (match_scratch:DI 2 "r")]
18954   "!optimize_size && !TARGET_PUSH_MEMORY
18955    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18956   [(set (match_dup 2) (match_dup 1))
18957    (set (match_dup 0) (match_dup 2))]
18958   "")
18960 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18961 ;; SImode pushes.
18962 (define_peephole2
18963   [(set (match_operand:SF 0 "push_operand" "")
18964         (match_operand:SF 1 "memory_operand" ""))
18965    (match_scratch:SF 2 "r")]
18966   "!optimize_size && !TARGET_PUSH_MEMORY
18967    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18968   [(set (match_dup 2) (match_dup 1))
18969    (set (match_dup 0) (match_dup 2))]
18970   "")
18972 (define_peephole2
18973   [(set (match_operand:HI 0 "push_operand" "")
18974         (match_operand:HI 1 "memory_operand" ""))
18975    (match_scratch:HI 2 "r")]
18976   "!optimize_size && !TARGET_PUSH_MEMORY
18977    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18978   [(set (match_dup 2) (match_dup 1))
18979    (set (match_dup 0) (match_dup 2))]
18980   "")
18982 (define_peephole2
18983   [(set (match_operand:QI 0 "push_operand" "")
18984         (match_operand:QI 1 "memory_operand" ""))
18985    (match_scratch:QI 2 "q")]
18986   "!optimize_size && !TARGET_PUSH_MEMORY
18987    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18988   [(set (match_dup 2) (match_dup 1))
18989    (set (match_dup 0) (match_dup 2))]
18990   "")
18992 ;; Don't move an immediate directly to memory when the instruction
18993 ;; gets too big.
18994 (define_peephole2
18995   [(match_scratch:SI 1 "r")
18996    (set (match_operand:SI 0 "memory_operand" "")
18997         (const_int 0))]
18998   "! optimize_size
18999    && ! TARGET_USE_MOV0
19000    && TARGET_SPLIT_LONG_MOVES
19001    && get_attr_length (insn) >= ix86_cost->large_insn
19002    && peep2_regno_dead_p (0, FLAGS_REG)"
19003   [(parallel [(set (match_dup 1) (const_int 0))
19004               (clobber (reg:CC FLAGS_REG))])
19005    (set (match_dup 0) (match_dup 1))]
19006   "")
19008 (define_peephole2
19009   [(match_scratch:HI 1 "r")
19010    (set (match_operand:HI 0 "memory_operand" "")
19011         (const_int 0))]
19012   "! optimize_size
19013    && ! TARGET_USE_MOV0
19014    && TARGET_SPLIT_LONG_MOVES
19015    && get_attr_length (insn) >= ix86_cost->large_insn
19016    && peep2_regno_dead_p (0, FLAGS_REG)"
19017   [(parallel [(set (match_dup 2) (const_int 0))
19018               (clobber (reg:CC FLAGS_REG))])
19019    (set (match_dup 0) (match_dup 1))]
19020   "operands[2] = gen_lowpart (SImode, operands[1]);")
19022 (define_peephole2
19023   [(match_scratch:QI 1 "q")
19024    (set (match_operand:QI 0 "memory_operand" "")
19025         (const_int 0))]
19026   "! optimize_size
19027    && ! TARGET_USE_MOV0
19028    && TARGET_SPLIT_LONG_MOVES
19029    && get_attr_length (insn) >= ix86_cost->large_insn
19030    && peep2_regno_dead_p (0, FLAGS_REG)"
19031   [(parallel [(set (match_dup 2) (const_int 0))
19032               (clobber (reg:CC FLAGS_REG))])
19033    (set (match_dup 0) (match_dup 1))]
19034   "operands[2] = gen_lowpart (SImode, operands[1]);")
19036 (define_peephole2
19037   [(match_scratch:SI 2 "r")
19038    (set (match_operand:SI 0 "memory_operand" "")
19039         (match_operand:SI 1 "immediate_operand" ""))]
19040   "! optimize_size
19041    && get_attr_length (insn) >= ix86_cost->large_insn
19042    && TARGET_SPLIT_LONG_MOVES"
19043   [(set (match_dup 2) (match_dup 1))
19044    (set (match_dup 0) (match_dup 2))]
19045   "")
19047 (define_peephole2
19048   [(match_scratch:HI 2 "r")
19049    (set (match_operand:HI 0 "memory_operand" "")
19050         (match_operand:HI 1 "immediate_operand" ""))]
19051   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19052   && TARGET_SPLIT_LONG_MOVES"
19053   [(set (match_dup 2) (match_dup 1))
19054    (set (match_dup 0) (match_dup 2))]
19055   "")
19057 (define_peephole2
19058   [(match_scratch:QI 2 "q")
19059    (set (match_operand:QI 0 "memory_operand" "")
19060         (match_operand:QI 1 "immediate_operand" ""))]
19061   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19062   && TARGET_SPLIT_LONG_MOVES"
19063   [(set (match_dup 2) (match_dup 1))
19064    (set (match_dup 0) (match_dup 2))]
19065   "")
19067 ;; Don't compare memory with zero, load and use a test instead.
19068 (define_peephole2
19069   [(set (match_operand 0 "flags_reg_operand" "")
19070         (match_operator 1 "compare_operator"
19071           [(match_operand:SI 2 "memory_operand" "")
19072            (const_int 0)]))
19073    (match_scratch:SI 3 "r")]
19074   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19075   [(set (match_dup 3) (match_dup 2))
19076    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19077   "")
19079 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19080 ;; Don't split NOTs with a displacement operand, because resulting XOR
19081 ;; will not be pairable anyway.
19083 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19084 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19085 ;; so this split helps here as well.
19087 ;; Note: Can't do this as a regular split because we can't get proper
19088 ;; lifetime information then.
19090 (define_peephole2
19091   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19092         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19093   "!optimize_size
19094    && peep2_regno_dead_p (0, FLAGS_REG)
19095    && ((TARGET_PENTIUM 
19096         && (GET_CODE (operands[0]) != MEM
19097             || !memory_displacement_operand (operands[0], SImode)))
19098        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19099   [(parallel [(set (match_dup 0)
19100                    (xor:SI (match_dup 1) (const_int -1)))
19101               (clobber (reg:CC FLAGS_REG))])]
19102   "")
19104 (define_peephole2
19105   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19106         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19107   "!optimize_size
19108    && peep2_regno_dead_p (0, FLAGS_REG)
19109    && ((TARGET_PENTIUM 
19110         && (GET_CODE (operands[0]) != MEM
19111             || !memory_displacement_operand (operands[0], HImode)))
19112        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19113   [(parallel [(set (match_dup 0)
19114                    (xor:HI (match_dup 1) (const_int -1)))
19115               (clobber (reg:CC FLAGS_REG))])]
19116   "")
19118 (define_peephole2
19119   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19120         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19121   "!optimize_size
19122    && peep2_regno_dead_p (0, FLAGS_REG)
19123    && ((TARGET_PENTIUM 
19124         && (GET_CODE (operands[0]) != MEM
19125             || !memory_displacement_operand (operands[0], QImode)))
19126        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19127   [(parallel [(set (match_dup 0)
19128                    (xor:QI (match_dup 1) (const_int -1)))
19129               (clobber (reg:CC FLAGS_REG))])]
19130   "")
19132 ;; Non pairable "test imm, reg" instructions can be translated to
19133 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19134 ;; byte opcode instead of two, have a short form for byte operands),
19135 ;; so do it for other CPUs as well.  Given that the value was dead,
19136 ;; this should not create any new dependencies.  Pass on the sub-word
19137 ;; versions if we're concerned about partial register stalls.
19139 (define_peephole2
19140   [(set (match_operand 0 "flags_reg_operand" "")
19141         (match_operator 1 "compare_operator"
19142           [(and:SI (match_operand:SI 2 "register_operand" "")
19143                    (match_operand:SI 3 "immediate_operand" ""))
19144            (const_int 0)]))]
19145   "ix86_match_ccmode (insn, CCNOmode)
19146    && (true_regnum (operands[2]) != 0
19147        || (GET_CODE (operands[3]) == CONST_INT
19148            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19149    && peep2_reg_dead_p (1, operands[2])"
19150   [(parallel
19151      [(set (match_dup 0)
19152            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19153                             (const_int 0)]))
19154       (set (match_dup 2)
19155            (and:SI (match_dup 2) (match_dup 3)))])]
19156   "")
19158 ;; We don't need to handle HImode case, because it will be promoted to SImode
19159 ;; on ! TARGET_PARTIAL_REG_STALL
19161 (define_peephole2
19162   [(set (match_operand 0 "flags_reg_operand" "")
19163         (match_operator 1 "compare_operator"
19164           [(and:QI (match_operand:QI 2 "register_operand" "")
19165                    (match_operand:QI 3 "immediate_operand" ""))
19166            (const_int 0)]))]
19167   "! TARGET_PARTIAL_REG_STALL
19168    && ix86_match_ccmode (insn, CCNOmode)
19169    && true_regnum (operands[2]) != 0
19170    && peep2_reg_dead_p (1, operands[2])"
19171   [(parallel
19172      [(set (match_dup 0)
19173            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19174                             (const_int 0)]))
19175       (set (match_dup 2)
19176            (and:QI (match_dup 2) (match_dup 3)))])]
19177   "")
19179 (define_peephole2
19180   [(set (match_operand 0 "flags_reg_operand" "")
19181         (match_operator 1 "compare_operator"
19182           [(and:SI
19183              (zero_extract:SI
19184                (match_operand 2 "ext_register_operand" "")
19185                (const_int 8)
19186                (const_int 8))
19187              (match_operand 3 "const_int_operand" ""))
19188            (const_int 0)]))]
19189   "! TARGET_PARTIAL_REG_STALL
19190    && ix86_match_ccmode (insn, CCNOmode)
19191    && true_regnum (operands[2]) != 0
19192    && peep2_reg_dead_p (1, operands[2])"
19193   [(parallel [(set (match_dup 0)
19194                    (match_op_dup 1
19195                      [(and:SI
19196                         (zero_extract:SI
19197                           (match_dup 2)
19198                           (const_int 8)
19199                           (const_int 8))
19200                         (match_dup 3))
19201                       (const_int 0)]))
19202               (set (zero_extract:SI (match_dup 2)
19203                                     (const_int 8)
19204                                     (const_int 8))
19205                    (and:SI 
19206                      (zero_extract:SI
19207                        (match_dup 2)
19208                        (const_int 8)
19209                        (const_int 8))
19210                      (match_dup 3)))])]
19211   "")
19213 ;; Don't do logical operations with memory inputs.
19214 (define_peephole2
19215   [(match_scratch:SI 2 "r")
19216    (parallel [(set (match_operand:SI 0 "register_operand" "")
19217                    (match_operator:SI 3 "arith_or_logical_operator"
19218                      [(match_dup 0)
19219                       (match_operand:SI 1 "memory_operand" "")]))
19220               (clobber (reg:CC FLAGS_REG))])]
19221   "! optimize_size && ! TARGET_READ_MODIFY"
19222   [(set (match_dup 2) (match_dup 1))
19223    (parallel [(set (match_dup 0)
19224                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19225               (clobber (reg:CC FLAGS_REG))])]
19226   "")
19228 (define_peephole2
19229   [(match_scratch:SI 2 "r")
19230    (parallel [(set (match_operand:SI 0 "register_operand" "")
19231                    (match_operator:SI 3 "arith_or_logical_operator"
19232                      [(match_operand:SI 1 "memory_operand" "")
19233                       (match_dup 0)]))
19234               (clobber (reg:CC FLAGS_REG))])]
19235   "! optimize_size && ! TARGET_READ_MODIFY"
19236   [(set (match_dup 2) (match_dup 1))
19237    (parallel [(set (match_dup 0)
19238                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19239               (clobber (reg:CC FLAGS_REG))])]
19240   "")
19242 ; Don't do logical operations with memory outputs
19244 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19245 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19246 ; the same decoder scheduling characteristics as the original.
19248 (define_peephole2
19249   [(match_scratch:SI 2 "r")
19250    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19251                    (match_operator:SI 3 "arith_or_logical_operator"
19252                      [(match_dup 0)
19253                       (match_operand:SI 1 "nonmemory_operand" "")]))
19254               (clobber (reg:CC FLAGS_REG))])]
19255   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19256   [(set (match_dup 2) (match_dup 0))
19257    (parallel [(set (match_dup 2)
19258                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19259               (clobber (reg:CC FLAGS_REG))])
19260    (set (match_dup 0) (match_dup 2))]
19261   "")
19263 (define_peephole2
19264   [(match_scratch:SI 2 "r")
19265    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19266                    (match_operator:SI 3 "arith_or_logical_operator"
19267                      [(match_operand:SI 1 "nonmemory_operand" "")
19268                       (match_dup 0)]))
19269               (clobber (reg:CC FLAGS_REG))])]
19270   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19271   [(set (match_dup 2) (match_dup 0))
19272    (parallel [(set (match_dup 2)
19273                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19274               (clobber (reg:CC FLAGS_REG))])
19275    (set (match_dup 0) (match_dup 2))]
19276   "")
19278 ;; Attempt to always use XOR for zeroing registers.
19279 (define_peephole2
19280   [(set (match_operand 0 "register_operand" "")
19281         (match_operand 1 "const0_operand" ""))]
19282   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19283    && (! TARGET_USE_MOV0 || optimize_size)
19284    && GENERAL_REG_P (operands[0])
19285    && peep2_regno_dead_p (0, FLAGS_REG)"
19286   [(parallel [(set (match_dup 0) (const_int 0))
19287               (clobber (reg:CC FLAGS_REG))])]
19289   operands[0] = gen_lowpart (word_mode, operands[0]);
19292 (define_peephole2
19293   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19294         (const_int 0))]
19295   "(GET_MODE (operands[0]) == QImode
19296     || GET_MODE (operands[0]) == HImode)
19297    && (! TARGET_USE_MOV0 || optimize_size)
19298    && peep2_regno_dead_p (0, FLAGS_REG)"
19299   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19300               (clobber (reg:CC FLAGS_REG))])])
19302 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19303 (define_peephole2
19304   [(set (match_operand 0 "register_operand" "")
19305         (const_int -1))]
19306   "(GET_MODE (operands[0]) == HImode
19307     || GET_MODE (operands[0]) == SImode 
19308     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19309    && (optimize_size || TARGET_PENTIUM)
19310    && peep2_regno_dead_p (0, FLAGS_REG)"
19311   [(parallel [(set (match_dup 0) (const_int -1))
19312               (clobber (reg:CC FLAGS_REG))])]
19313   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19314                               operands[0]);")
19316 ;; Attempt to convert simple leas to adds. These can be created by
19317 ;; move expanders.
19318 (define_peephole2
19319   [(set (match_operand:SI 0 "register_operand" "")
19320         (plus:SI (match_dup 0)
19321                  (match_operand:SI 1 "nonmemory_operand" "")))]
19322   "peep2_regno_dead_p (0, FLAGS_REG)"
19323   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19324               (clobber (reg:CC FLAGS_REG))])]
19325   "")
19327 (define_peephole2
19328   [(set (match_operand:SI 0 "register_operand" "")
19329         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19330                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19331   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19332   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19333               (clobber (reg:CC FLAGS_REG))])]
19334   "operands[2] = gen_lowpart (SImode, operands[2]);")
19336 (define_peephole2
19337   [(set (match_operand:DI 0 "register_operand" "")
19338         (plus:DI (match_dup 0)
19339                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19340   "peep2_regno_dead_p (0, FLAGS_REG)"
19341   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19342               (clobber (reg:CC FLAGS_REG))])]
19343   "")
19345 (define_peephole2
19346   [(set (match_operand:SI 0 "register_operand" "")
19347         (mult:SI (match_dup 0)
19348                  (match_operand:SI 1 "const_int_operand" "")))]
19349   "exact_log2 (INTVAL (operands[1])) >= 0
19350    && peep2_regno_dead_p (0, FLAGS_REG)"
19351   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19352               (clobber (reg:CC FLAGS_REG))])]
19353   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19355 (define_peephole2
19356   [(set (match_operand:DI 0 "register_operand" "")
19357         (mult:DI (match_dup 0)
19358                  (match_operand:DI 1 "const_int_operand" "")))]
19359   "exact_log2 (INTVAL (operands[1])) >= 0
19360    && peep2_regno_dead_p (0, FLAGS_REG)"
19361   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19362               (clobber (reg:CC FLAGS_REG))])]
19363   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19365 (define_peephole2
19366   [(set (match_operand:SI 0 "register_operand" "")
19367         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19368                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19369   "exact_log2 (INTVAL (operands[2])) >= 0
19370    && REGNO (operands[0]) == REGNO (operands[1])
19371    && peep2_regno_dead_p (0, FLAGS_REG)"
19372   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19373               (clobber (reg:CC FLAGS_REG))])]
19374   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19376 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19377 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19378 ;; many CPUs it is also faster, since special hardware to avoid esp
19379 ;; dependencies is present.
19381 ;; While some of these conversions may be done using splitters, we use peepholes
19382 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19384 ;; Convert prologue esp subtractions to push.
19385 ;; We need register to push.  In order to keep verify_flow_info happy we have
19386 ;; two choices
19387 ;; - use scratch and clobber it in order to avoid dependencies
19388 ;; - use already live register
19389 ;; We can't use the second way right now, since there is no reliable way how to
19390 ;; verify that given register is live.  First choice will also most likely in
19391 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19392 ;; call clobbered registers are dead.  We may want to use base pointer as an
19393 ;; alternative when no register is available later.
19395 (define_peephole2
19396   [(match_scratch:SI 0 "r")
19397    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19398               (clobber (reg:CC FLAGS_REG))
19399               (clobber (mem:BLK (scratch)))])]
19400   "optimize_size || !TARGET_SUB_ESP_4"
19401   [(clobber (match_dup 0))
19402    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19403               (clobber (mem:BLK (scratch)))])])
19405 (define_peephole2
19406   [(match_scratch:SI 0 "r")
19407    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19408               (clobber (reg:CC FLAGS_REG))
19409               (clobber (mem:BLK (scratch)))])]
19410   "optimize_size || !TARGET_SUB_ESP_8"
19411   [(clobber (match_dup 0))
19412    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19413    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19414               (clobber (mem:BLK (scratch)))])])
19416 ;; Convert esp subtractions to push.
19417 (define_peephole2
19418   [(match_scratch:SI 0 "r")
19419    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   "optimize_size || !TARGET_SUB_ESP_4"
19422   [(clobber (match_dup 0))
19423    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19425 (define_peephole2
19426   [(match_scratch:SI 0 "r")
19427    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19428               (clobber (reg:CC FLAGS_REG))])]
19429   "optimize_size || !TARGET_SUB_ESP_8"
19430   [(clobber (match_dup 0))
19431    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19432    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19434 ;; Convert epilogue deallocator to pop.
19435 (define_peephole2
19436   [(match_scratch:SI 0 "r")
19437    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19438               (clobber (reg:CC FLAGS_REG))
19439               (clobber (mem:BLK (scratch)))])]
19440   "optimize_size || !TARGET_ADD_ESP_4"
19441   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19442               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19443               (clobber (mem:BLK (scratch)))])]
19444   "")
19446 ;; Two pops case is tricky, since pop causes dependency on destination register.
19447 ;; We use two registers if available.
19448 (define_peephole2
19449   [(match_scratch:SI 0 "r")
19450    (match_scratch:SI 1 "r")
19451    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19452               (clobber (reg:CC FLAGS_REG))
19453               (clobber (mem:BLK (scratch)))])]
19454   "optimize_size || !TARGET_ADD_ESP_8"
19455   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19456               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19457               (clobber (mem:BLK (scratch)))])
19458    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19459               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19460   "")
19462 (define_peephole2
19463   [(match_scratch:SI 0 "r")
19464    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19465               (clobber (reg:CC FLAGS_REG))
19466               (clobber (mem:BLK (scratch)))])]
19467   "optimize_size"
19468   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19469               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19470               (clobber (mem:BLK (scratch)))])
19471    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19472               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19473   "")
19475 ;; Convert esp additions to pop.
19476 (define_peephole2
19477   [(match_scratch:SI 0 "r")
19478    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19479               (clobber (reg:CC FLAGS_REG))])]
19480   ""
19481   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19482               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19483   "")
19485 ;; Two pops case is tricky, since pop causes dependency on destination register.
19486 ;; We use two registers if available.
19487 (define_peephole2
19488   [(match_scratch:SI 0 "r")
19489    (match_scratch:SI 1 "r")
19490    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19491               (clobber (reg:CC FLAGS_REG))])]
19492   ""
19493   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19494               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19495    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19496               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19497   "")
19499 (define_peephole2
19500   [(match_scratch:SI 0 "r")
19501    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19502               (clobber (reg:CC FLAGS_REG))])]
19503   "optimize_size"
19504   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19505               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19506    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19507               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19508   "")
19510 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19511 ;; required and register dies.  Similarly for 128 to plus -128.
19512 (define_peephole2
19513   [(set (match_operand 0 "flags_reg_operand" "")
19514         (match_operator 1 "compare_operator"
19515           [(match_operand 2 "register_operand" "")
19516            (match_operand 3 "const_int_operand" "")]))]
19517   "(INTVAL (operands[3]) == -1
19518     || INTVAL (operands[3]) == 1
19519     || INTVAL (operands[3]) == 128)
19520    && ix86_match_ccmode (insn, CCGCmode)
19521    && peep2_reg_dead_p (1, operands[2])"
19522   [(parallel [(set (match_dup 0)
19523                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19524               (clobber (match_dup 2))])]
19525   "")
19527 (define_peephole2
19528   [(match_scratch:DI 0 "r")
19529    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19530               (clobber (reg:CC FLAGS_REG))
19531               (clobber (mem:BLK (scratch)))])]
19532   "optimize_size || !TARGET_SUB_ESP_4"
19533   [(clobber (match_dup 0))
19534    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19535               (clobber (mem:BLK (scratch)))])])
19537 (define_peephole2
19538   [(match_scratch:DI 0 "r")
19539    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19540               (clobber (reg:CC FLAGS_REG))
19541               (clobber (mem:BLK (scratch)))])]
19542   "optimize_size || !TARGET_SUB_ESP_8"
19543   [(clobber (match_dup 0))
19544    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19545    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19546               (clobber (mem:BLK (scratch)))])])
19548 ;; Convert esp subtractions to push.
19549 (define_peephole2
19550   [(match_scratch:DI 0 "r")
19551    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19552               (clobber (reg:CC FLAGS_REG))])]
19553   "optimize_size || !TARGET_SUB_ESP_4"
19554   [(clobber (match_dup 0))
19555    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19557 (define_peephole2
19558   [(match_scratch:DI 0 "r")
19559    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19560               (clobber (reg:CC FLAGS_REG))])]
19561   "optimize_size || !TARGET_SUB_ESP_8"
19562   [(clobber (match_dup 0))
19563    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19564    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19566 ;; Convert epilogue deallocator to pop.
19567 (define_peephole2
19568   [(match_scratch:DI 0 "r")
19569    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19570               (clobber (reg:CC FLAGS_REG))
19571               (clobber (mem:BLK (scratch)))])]
19572   "optimize_size || !TARGET_ADD_ESP_4"
19573   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19574               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19575               (clobber (mem:BLK (scratch)))])]
19576   "")
19578 ;; Two pops case is tricky, since pop causes dependency on destination register.
19579 ;; We use two registers if available.
19580 (define_peephole2
19581   [(match_scratch:DI 0 "r")
19582    (match_scratch:DI 1 "r")
19583    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19584               (clobber (reg:CC FLAGS_REG))
19585               (clobber (mem:BLK (scratch)))])]
19586   "optimize_size || !TARGET_ADD_ESP_8"
19587   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19588               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19589               (clobber (mem:BLK (scratch)))])
19590    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19591               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19592   "")
19594 (define_peephole2
19595   [(match_scratch:DI 0 "r")
19596    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19597               (clobber (reg:CC FLAGS_REG))
19598               (clobber (mem:BLK (scratch)))])]
19599   "optimize_size"
19600   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19601               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19602               (clobber (mem:BLK (scratch)))])
19603    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19604               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19605   "")
19607 ;; Convert esp additions to pop.
19608 (define_peephole2
19609   [(match_scratch:DI 0 "r")
19610    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19611               (clobber (reg:CC FLAGS_REG))])]
19612   ""
19613   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19614               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19615   "")
19617 ;; Two pops case is tricky, since pop causes dependency on destination register.
19618 ;; We use two registers if available.
19619 (define_peephole2
19620   [(match_scratch:DI 0 "r")
19621    (match_scratch:DI 1 "r")
19622    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19623               (clobber (reg:CC FLAGS_REG))])]
19624   ""
19625   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19626               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19627    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19628               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19629   "")
19631 (define_peephole2
19632   [(match_scratch:DI 0 "r")
19633    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19634               (clobber (reg:CC FLAGS_REG))])]
19635   "optimize_size"
19636   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19637               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19638    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19640   "")
19642 ;; Convert imul by three, five and nine into lea
19643 (define_peephole2
19644   [(parallel
19645     [(set (match_operand:SI 0 "register_operand" "")
19646           (mult:SI (match_operand:SI 1 "register_operand" "")
19647                    (match_operand:SI 2 "const_int_operand" "")))
19648      (clobber (reg:CC FLAGS_REG))])]
19649   "INTVAL (operands[2]) == 3
19650    || INTVAL (operands[2]) == 5
19651    || INTVAL (operands[2]) == 9"
19652   [(set (match_dup 0)
19653         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19654                  (match_dup 1)))]
19655   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19657 (define_peephole2
19658   [(parallel
19659     [(set (match_operand:SI 0 "register_operand" "")
19660           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19661                    (match_operand:SI 2 "const_int_operand" "")))
19662      (clobber (reg:CC FLAGS_REG))])]
19663   "!optimize_size 
19664    && (INTVAL (operands[2]) == 3
19665        || INTVAL (operands[2]) == 5
19666        || INTVAL (operands[2]) == 9)"
19667   [(set (match_dup 0) (match_dup 1))
19668    (set (match_dup 0)
19669         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19670                  (match_dup 0)))]
19671   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19673 (define_peephole2
19674   [(parallel
19675     [(set (match_operand:DI 0 "register_operand" "")
19676           (mult:DI (match_operand:DI 1 "register_operand" "")
19677                    (match_operand:DI 2 "const_int_operand" "")))
19678      (clobber (reg:CC FLAGS_REG))])]
19679   "TARGET_64BIT
19680    && (INTVAL (operands[2]) == 3
19681        || INTVAL (operands[2]) == 5
19682        || INTVAL (operands[2]) == 9)"
19683   [(set (match_dup 0)
19684         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19685                  (match_dup 1)))]
19686   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19688 (define_peephole2
19689   [(parallel
19690     [(set (match_operand:DI 0 "register_operand" "")
19691           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19692                    (match_operand:DI 2 "const_int_operand" "")))
19693      (clobber (reg:CC FLAGS_REG))])]
19694   "TARGET_64BIT
19695    && !optimize_size 
19696    && (INTVAL (operands[2]) == 3
19697        || INTVAL (operands[2]) == 5
19698        || INTVAL (operands[2]) == 9)"
19699   [(set (match_dup 0) (match_dup 1))
19700    (set (match_dup 0)
19701         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19702                  (match_dup 0)))]
19703   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19705 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19706 ;; imul $32bit_imm, reg, reg is direct decoded.
19707 (define_peephole2
19708   [(match_scratch:DI 3 "r")
19709    (parallel [(set (match_operand:DI 0 "register_operand" "")
19710                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19711                             (match_operand:DI 2 "immediate_operand" "")))
19712               (clobber (reg:CC FLAGS_REG))])]
19713   "TARGET_K8 && !optimize_size
19714    && (GET_CODE (operands[2]) != CONST_INT
19715        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19716   [(set (match_dup 3) (match_dup 1))
19717    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19718               (clobber (reg:CC FLAGS_REG))])]
19721 (define_peephole2
19722   [(match_scratch:SI 3 "r")
19723    (parallel [(set (match_operand:SI 0 "register_operand" "")
19724                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19725                             (match_operand:SI 2 "immediate_operand" "")))
19726               (clobber (reg:CC FLAGS_REG))])]
19727   "TARGET_K8 && !optimize_size
19728    && (GET_CODE (operands[2]) != CONST_INT
19729        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19730   [(set (match_dup 3) (match_dup 1))
19731    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19732               (clobber (reg:CC FLAGS_REG))])]
19735 (define_peephole2
19736   [(match_scratch:SI 3 "r")
19737    (parallel [(set (match_operand:DI 0 "register_operand" "")
19738                    (zero_extend:DI
19739                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19740                               (match_operand:SI 2 "immediate_operand" ""))))
19741               (clobber (reg:CC FLAGS_REG))])]
19742   "TARGET_K8 && !optimize_size
19743    && (GET_CODE (operands[2]) != CONST_INT
19744        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19745   [(set (match_dup 3) (match_dup 1))
19746    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19747               (clobber (reg:CC FLAGS_REG))])]
19750 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19751 ;; Convert it into imul reg, reg
19752 ;; It would be better to force assembler to encode instruction using long
19753 ;; immediate, but there is apparently no way to do so.
19754 (define_peephole2
19755   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19756                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19757                             (match_operand:DI 2 "const_int_operand" "")))
19758               (clobber (reg:CC FLAGS_REG))])
19759    (match_scratch:DI 3 "r")]
19760   "TARGET_K8 && !optimize_size
19761    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19762   [(set (match_dup 3) (match_dup 2))
19763    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19764               (clobber (reg:CC FLAGS_REG))])]
19766   if (!rtx_equal_p (operands[0], operands[1]))
19767     emit_move_insn (operands[0], operands[1]);
19770 (define_peephole2
19771   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19772                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19773                             (match_operand:SI 2 "const_int_operand" "")))
19774               (clobber (reg:CC FLAGS_REG))])
19775    (match_scratch:SI 3 "r")]
19776   "TARGET_K8 && !optimize_size
19777    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19778   [(set (match_dup 3) (match_dup 2))
19779    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19780               (clobber (reg:CC FLAGS_REG))])]
19782   if (!rtx_equal_p (operands[0], operands[1]))
19783     emit_move_insn (operands[0], operands[1]);
19786 (define_peephole2
19787   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19788                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19789                             (match_operand:HI 2 "immediate_operand" "")))
19790               (clobber (reg:CC FLAGS_REG))])
19791    (match_scratch:HI 3 "r")]
19792   "TARGET_K8 && !optimize_size"
19793   [(set (match_dup 3) (match_dup 2))
19794    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19795               (clobber (reg:CC FLAGS_REG))])]
19797   if (!rtx_equal_p (operands[0], operands[1]))
19798     emit_move_insn (operands[0], operands[1]);
19801 ;; After splitting up read-modify operations, array accesses with memory
19802 ;; operands might end up in form:
19803 ;;  sall    $2, %eax
19804 ;;  movl    4(%esp), %edx
19805 ;;  addl    %edx, %eax
19806 ;; instead of pre-splitting:
19807 ;;  sall    $2, %eax
19808 ;;  addl    4(%esp), %eax
19809 ;; Turn it into:
19810 ;;  movl    4(%esp), %edx
19811 ;;  leal    (%edx,%eax,4), %eax
19813 (define_peephole2
19814   [(parallel [(set (match_operand 0 "register_operand" "")
19815                    (ashift (match_operand 1 "register_operand" "")
19816                            (match_operand 2 "const_int_operand" "")))
19817                (clobber (reg:CC FLAGS_REG))])
19818    (set (match_operand 3 "register_operand")
19819         (match_operand 4 "x86_64_general_operand" ""))
19820    (parallel [(set (match_operand 5 "register_operand" "")
19821                    (plus (match_operand 6 "register_operand" "")
19822                          (match_operand 7 "register_operand" "")))
19823                    (clobber (reg:CC FLAGS_REG))])]
19824   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19825    /* Validate MODE for lea.  */
19826    && ((!TARGET_PARTIAL_REG_STALL
19827         && (GET_MODE (operands[0]) == QImode
19828             || GET_MODE (operands[0]) == HImode))
19829        || GET_MODE (operands[0]) == SImode 
19830        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19831    /* We reorder load and the shift.  */
19832    && !rtx_equal_p (operands[1], operands[3])
19833    && !reg_overlap_mentioned_p (operands[0], operands[4])
19834    /* Last PLUS must consist of operand 0 and 3.  */
19835    && !rtx_equal_p (operands[0], operands[3])
19836    && (rtx_equal_p (operands[3], operands[6])
19837        || rtx_equal_p (operands[3], operands[7]))
19838    && (rtx_equal_p (operands[0], operands[6])
19839        || rtx_equal_p (operands[0], operands[7]))
19840    /* The intermediate operand 0 must die or be same as output.  */
19841    && (rtx_equal_p (operands[0], operands[5])
19842        || peep2_reg_dead_p (3, operands[0]))"
19843   [(set (match_dup 3) (match_dup 4))
19844    (set (match_dup 0) (match_dup 1))]
19846   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19847   int scale = 1 << INTVAL (operands[2]);
19848   rtx index = gen_lowpart (Pmode, operands[1]);
19849   rtx base = gen_lowpart (Pmode, operands[3]);
19850   rtx dest = gen_lowpart (mode, operands[5]);
19852   operands[1] = gen_rtx_PLUS (Pmode, base,
19853                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19854   if (mode != Pmode)
19855     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19856   operands[0] = dest;
19859 ;; Call-value patterns last so that the wildcard operand does not
19860 ;; disrupt insn-recog's switch tables.
19862 (define_insn "*call_value_pop_0"
19863   [(set (match_operand 0 "" "")
19864         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19865               (match_operand:SI 2 "" "")))
19866    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19867                             (match_operand:SI 3 "immediate_operand" "")))]
19868   "!TARGET_64BIT"
19870   if (SIBLING_CALL_P (insn))
19871     return "jmp\t%P1";
19872   else
19873     return "call\t%P1";
19875   [(set_attr "type" "callv")])
19877 (define_insn "*call_value_pop_1"
19878   [(set (match_operand 0 "" "")
19879         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19880               (match_operand:SI 2 "" "")))
19881    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19882                             (match_operand:SI 3 "immediate_operand" "i")))]
19883   "!TARGET_64BIT"
19885   if (constant_call_address_operand (operands[1], Pmode))
19886     {
19887       if (SIBLING_CALL_P (insn))
19888         return "jmp\t%P1";
19889       else
19890         return "call\t%P1";
19891     }
19892   if (SIBLING_CALL_P (insn))
19893     return "jmp\t%A1";
19894   else
19895     return "call\t%A1";
19897   [(set_attr "type" "callv")])
19899 (define_insn "*call_value_0"
19900   [(set (match_operand 0 "" "")
19901         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19902               (match_operand:SI 2 "" "")))]
19903   "!TARGET_64BIT"
19905   if (SIBLING_CALL_P (insn))
19906     return "jmp\t%P1";
19907   else
19908     return "call\t%P1";
19910   [(set_attr "type" "callv")])
19912 (define_insn "*call_value_0_rex64"
19913   [(set (match_operand 0 "" "")
19914         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19915               (match_operand:DI 2 "const_int_operand" "")))]
19916   "TARGET_64BIT"
19918   if (SIBLING_CALL_P (insn))
19919     return "jmp\t%P1";
19920   else
19921     return "call\t%P1";
19923   [(set_attr "type" "callv")])
19925 (define_insn "*call_value_1"
19926   [(set (match_operand 0 "" "")
19927         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19928               (match_operand:SI 2 "" "")))]
19929   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19931   if (constant_call_address_operand (operands[1], Pmode))
19932     return "call\t%P1";
19933   return "call\t%A1";
19935   [(set_attr "type" "callv")])
19937 (define_insn "*sibcall_value_1"
19938   [(set (match_operand 0 "" "")
19939         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19940               (match_operand:SI 2 "" "")))]
19941   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19943   if (constant_call_address_operand (operands[1], Pmode))
19944     return "jmp\t%P1";
19945   return "jmp\t%A1";
19947   [(set_attr "type" "callv")])
19949 (define_insn "*call_value_1_rex64"
19950   [(set (match_operand 0 "" "")
19951         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19952               (match_operand:DI 2 "" "")))]
19953   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19955   if (constant_call_address_operand (operands[1], Pmode))
19956     return "call\t%P1";
19957   return "call\t%A1";
19959   [(set_attr "type" "callv")])
19961 (define_insn "*sibcall_value_1_rex64"
19962   [(set (match_operand 0 "" "")
19963         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19964               (match_operand:DI 2 "" "")))]
19965   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19966   "jmp\t%P1"
19967   [(set_attr "type" "callv")])
19969 (define_insn "*sibcall_value_1_rex64_v"
19970   [(set (match_operand 0 "" "")
19971         (call (mem:QI (reg:DI 40))
19972               (match_operand:DI 1 "" "")))]
19973   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19974   "jmp\t*%%r11"
19975   [(set_attr "type" "callv")])
19977 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19978 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19979 ;; caught for use by garbage collectors and the like.  Using an insn that
19980 ;; maps to SIGILL makes it more likely the program will rightfully die.
19981 ;; Keeping with tradition, "6" is in honor of #UD.
19982 (define_insn "trap"
19983   [(trap_if (const_int 1) (const_int 6))]
19984   ""
19985   ".word\t0x0b0f"
19986   [(set_attr "length" "2")])
19988 (define_expand "sse_prologue_save"
19989   [(parallel [(set (match_operand:BLK 0 "" "")
19990                    (unspec:BLK [(reg:DI 21)
19991                                 (reg:DI 22)
19992                                 (reg:DI 23)
19993                                 (reg:DI 24)
19994                                 (reg:DI 25)
19995                                 (reg:DI 26)
19996                                 (reg:DI 27)
19997                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19998               (use (match_operand:DI 1 "register_operand" ""))
19999               (use (match_operand:DI 2 "immediate_operand" ""))
20000               (use (label_ref:DI (match_operand 3 "" "")))])]
20001   "TARGET_64BIT"
20002   "")
20004 (define_insn "*sse_prologue_save_insn"
20005   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20006                           (match_operand:DI 4 "const_int_operand" "n")))
20007         (unspec:BLK [(reg:DI 21)
20008                      (reg:DI 22)
20009                      (reg:DI 23)
20010                      (reg:DI 24)
20011                      (reg:DI 25)
20012                      (reg:DI 26)
20013                      (reg:DI 27)
20014                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20015    (use (match_operand:DI 1 "register_operand" "r"))
20016    (use (match_operand:DI 2 "const_int_operand" "i"))
20017    (use (label_ref:DI (match_operand 3 "" "X")))]
20018   "TARGET_64BIT
20019    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20020    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20021   "*
20023   int i;
20024   operands[0] = gen_rtx_MEM (Pmode,
20025                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20026   output_asm_insn (\"jmp\\t%A1\", operands);
20027   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20028     {
20029       operands[4] = adjust_address (operands[0], DImode, i*16);
20030       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20031       PUT_MODE (operands[4], TImode);
20032       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20033         output_asm_insn (\"rex\", operands);
20034       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20035     }
20036   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20037                              CODE_LABEL_NUMBER (operands[3]));
20038   RET;
20040   "
20041   [(set_attr "type" "other")
20042    (set_attr "length_immediate" "0")
20043    (set_attr "length_address" "0")
20044    (set_attr "length" "135")
20045    (set_attr "memory" "store")
20046    (set_attr "modrm" "0")
20047    (set_attr "mode" "DI")])
20049 (define_expand "prefetch"
20050   [(prefetch (match_operand 0 "address_operand" "")
20051              (match_operand:SI 1 "const_int_operand" "")
20052              (match_operand:SI 2 "const_int_operand" ""))]
20053   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20055   int rw = INTVAL (operands[1]);
20056   int locality = INTVAL (operands[2]);
20058   gcc_assert (rw == 0 || rw == 1);
20059   gcc_assert (locality >= 0 && locality <= 3);
20060   gcc_assert (GET_MODE (operands[0]) == Pmode
20061               || GET_MODE (operands[0]) == VOIDmode);
20063   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20064      supported by SSE counterpart or the SSE prefetch is not available
20065      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20066      of locality.  */
20067   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20068     operands[2] = GEN_INT (3);
20069   else
20070     operands[1] = const0_rtx;
20073 (define_insn "*prefetch_sse"
20074   [(prefetch (match_operand:SI 0 "address_operand" "p")
20075              (const_int 0)
20076              (match_operand:SI 1 "const_int_operand" ""))]
20077   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20079   static const char * const patterns[4] = {
20080    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20081   };
20083   int locality = INTVAL (operands[1]);
20084   gcc_assert (locality >= 0 && locality <= 3);
20086   return patterns[locality];  
20088   [(set_attr "type" "sse")
20089    (set_attr "memory" "none")])
20091 (define_insn "*prefetch_sse_rex"
20092   [(prefetch (match_operand:DI 0 "address_operand" "p")
20093              (const_int 0)
20094              (match_operand:SI 1 "const_int_operand" ""))]
20095   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20097   static const char * const patterns[4] = {
20098    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20099   };
20101   int locality = INTVAL (operands[1]);
20102   gcc_assert (locality >= 0 && locality <= 3);
20104   return patterns[locality];  
20106   [(set_attr "type" "sse")
20107    (set_attr "memory" "none")])
20109 (define_insn "*prefetch_3dnow"
20110   [(prefetch (match_operand:SI 0 "address_operand" "p")
20111              (match_operand:SI 1 "const_int_operand" "n")
20112              (const_int 3))]
20113   "TARGET_3DNOW && !TARGET_64BIT"
20115   if (INTVAL (operands[1]) == 0)
20116     return "prefetch\t%a0";
20117   else
20118     return "prefetchw\t%a0";
20120   [(set_attr "type" "mmx")
20121    (set_attr "memory" "none")])
20123 (define_insn "*prefetch_3dnow_rex"
20124   [(prefetch (match_operand:DI 0 "address_operand" "p")
20125              (match_operand:SI 1 "const_int_operand" "n")
20126              (const_int 3))]
20127   "TARGET_3DNOW && TARGET_64BIT"
20129   if (INTVAL (operands[1]) == 0)
20130     return "prefetch\t%a0";
20131   else
20132     return "prefetchw\t%a0";
20134   [(set_attr "type" "mmx")
20135    (set_attr "memory" "none")])
20137 (define_expand "stack_protect_set"
20138   [(match_operand 0 "memory_operand" "")
20139    (match_operand 1 "memory_operand" "")]
20140   ""
20142 #ifdef TARGET_THREAD_SSP_OFFSET
20143   if (TARGET_64BIT)
20144     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20145                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20146   else
20147     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20148                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20149 #else
20150   if (TARGET_64BIT)
20151     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20152   else
20153     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20154 #endif
20155   DONE;
20158 (define_insn "stack_protect_set_si"
20159   [(set (match_operand:SI 0 "memory_operand" "=m")
20160         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20161    (set (match_scratch:SI 2 "=&r") (const_int 0))
20162    (clobber (reg:CC FLAGS_REG))]
20163   ""
20164   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20165   [(set_attr "type" "multi")])
20167 (define_insn "stack_protect_set_di"
20168   [(set (match_operand:DI 0 "memory_operand" "=m")
20169         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20170    (set (match_scratch:DI 2 "=&r") (const_int 0))
20171    (clobber (reg:CC FLAGS_REG))]
20172   "TARGET_64BIT"
20173   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20174   [(set_attr "type" "multi")])
20176 (define_insn "stack_tls_protect_set_si"
20177   [(set (match_operand:SI 0 "memory_operand" "=m")
20178         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20179    (set (match_scratch:SI 2 "=&r") (const_int 0))
20180    (clobber (reg:CC FLAGS_REG))]
20181   ""
20182   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20183   [(set_attr "type" "multi")])
20185 (define_insn "stack_tls_protect_set_di"
20186   [(set (match_operand:DI 0 "memory_operand" "=m")
20187         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20188    (set (match_scratch:DI 2 "=&r") (const_int 0))
20189    (clobber (reg:CC FLAGS_REG))]
20190   "TARGET_64BIT"
20191   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20192   [(set_attr "type" "multi")])
20194 (define_expand "stack_protect_test"
20195   [(match_operand 0 "memory_operand" "")
20196    (match_operand 1 "memory_operand" "")
20197    (match_operand 2 "" "")]
20198   ""
20200   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20201   ix86_compare_op0 = operands[0];
20202   ix86_compare_op1 = operands[1];
20203   ix86_compare_emitted = flags;
20205 #ifdef TARGET_THREAD_SSP_OFFSET
20206   if (TARGET_64BIT)
20207     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20208                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20209   else
20210     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20211                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20212 #else
20213   if (TARGET_64BIT)
20214     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20215   else
20216     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20217 #endif
20218   emit_jump_insn (gen_beq (operands[2]));
20219   DONE;
20222 (define_insn "stack_protect_test_si"
20223   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20224         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20225                      (match_operand:SI 2 "memory_operand" "m")]
20226                     UNSPEC_SP_TEST))
20227    (clobber (match_scratch:SI 3 "=&r"))]
20228   ""
20229   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20230   [(set_attr "type" "multi")])
20232 (define_insn "stack_protect_test_di"
20233   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20234         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20235                      (match_operand:DI 2 "memory_operand" "m")]
20236                     UNSPEC_SP_TEST))
20237    (clobber (match_scratch:DI 3 "=&r"))]
20238   "TARGET_64BIT"
20239   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20240   [(set_attr "type" "multi")])
20242 (define_insn "stack_tls_protect_test_si"
20243   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20244         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20245                      (match_operand:SI 2 "const_int_operand" "i")]
20246                     UNSPEC_SP_TLS_TEST))
20247    (clobber (match_scratch:SI 3 "=r"))]
20248   ""
20249   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20250   [(set_attr "type" "multi")])
20252 (define_insn "stack_tls_protect_test_di"
20253   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20254         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20255                      (match_operand:DI 2 "const_int_operand" "i")]
20256                     UNSPEC_SP_TLS_TEST))
20257    (clobber (match_scratch:DI 3 "=r"))]
20258   "TARGET_64BIT"
20259   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20260   [(set_attr "type" "multi")])
20262 (include "sse.md")
20263 (include "mmx.md")
20264 (include "sync.md")