* Merge from mainline
[official-gcc.git] / gcc / config / i386 / i386.md
blobe651672bd6b53cfb08f39cec7cea26023d5218a1
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
74    (UNSPEC_TLSDESC              19)
76    ; Other random patterns
77    (UNSPEC_SCAS                 20)
78    (UNSPEC_FNSTSW               21)
79    (UNSPEC_SAHF                 22)
80    (UNSPEC_FSTCW                23)
81    (UNSPEC_ADD_CARRY            24)
82    (UNSPEC_FLDCW                25)
83    (UNSPEC_REP                  26)
84    (UNSPEC_EH_RETURN            27)
85    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
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,generic32,generic64"
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 and constraints
478 (include "predicates.md")
479 (include "constraints.md")
482 ;; Compare instructions.
484 ;; All compare insns have expanders that save the operands away without
485 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
486 ;; after the cmp) will actually emit the cmpM.
488 (define_expand "cmpti"
489   [(set (reg:CC FLAGS_REG)
490         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
491                     (match_operand:TI 1 "x86_64_general_operand" "")))]
492   "TARGET_64BIT"
494   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
495     operands[0] = force_reg (TImode, operands[0]);
496   ix86_compare_op0 = operands[0];
497   ix86_compare_op1 = operands[1];
498   DONE;
501 (define_expand "cmpdi"
502   [(set (reg:CC FLAGS_REG)
503         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
504                     (match_operand:DI 1 "x86_64_general_operand" "")))]
505   ""
507   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
508     operands[0] = force_reg (DImode, operands[0]);
509   ix86_compare_op0 = operands[0];
510   ix86_compare_op1 = operands[1];
511   DONE;
514 (define_expand "cmpsi"
515   [(set (reg:CC FLAGS_REG)
516         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
517                     (match_operand:SI 1 "general_operand" "")))]
518   ""
520   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
521     operands[0] = force_reg (SImode, operands[0]);
522   ix86_compare_op0 = operands[0];
523   ix86_compare_op1 = operands[1];
524   DONE;
527 (define_expand "cmphi"
528   [(set (reg:CC FLAGS_REG)
529         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
530                     (match_operand:HI 1 "general_operand" "")))]
531   ""
533   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
534     operands[0] = force_reg (HImode, operands[0]);
535   ix86_compare_op0 = operands[0];
536   ix86_compare_op1 = operands[1];
537   DONE;
540 (define_expand "cmpqi"
541   [(set (reg:CC FLAGS_REG)
542         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
543                     (match_operand:QI 1 "general_operand" "")))]
544   "TARGET_QIMODE_MATH"
546   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
547     operands[0] = force_reg (QImode, operands[0]);
548   ix86_compare_op0 = operands[0];
549   ix86_compare_op1 = operands[1];
550   DONE;
553 (define_insn "cmpdi_ccno_1_rex64"
554   [(set (reg FLAGS_REG)
555         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
556                  (match_operand:DI 1 "const0_operand" "n,n")))]
557   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
558   "@
559    test{q}\t{%0, %0|%0, %0}
560    cmp{q}\t{%1, %0|%0, %1}"
561   [(set_attr "type" "test,icmp")
562    (set_attr "length_immediate" "0,1")
563    (set_attr "mode" "DI")])
565 (define_insn "*cmpdi_minus_1_rex64"
566   [(set (reg FLAGS_REG)
567         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
568                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
569                  (const_int 0)))]
570   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
571   "cmp{q}\t{%1, %0|%0, %1}"
572   [(set_attr "type" "icmp")
573    (set_attr "mode" "DI")])
575 (define_expand "cmpdi_1_rex64"
576   [(set (reg:CC FLAGS_REG)
577         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
578                     (match_operand:DI 1 "general_operand" "")))]
579   "TARGET_64BIT"
580   "")
582 (define_insn "cmpdi_1_insn_rex64"
583   [(set (reg FLAGS_REG)
584         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
585                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
592 (define_insn "*cmpsi_ccno_1"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
595                  (match_operand:SI 1 "const0_operand" "n,n")))]
596   "ix86_match_ccmode (insn, CCNOmode)"
597   "@
598    test{l}\t{%0, %0|%0, %0}
599    cmp{l}\t{%1, %0|%0, %1}"
600   [(set_attr "type" "test,icmp")
601    (set_attr "length_immediate" "0,1")
602    (set_attr "mode" "SI")])
604 (define_insn "*cmpsi_minus_1"
605   [(set (reg FLAGS_REG)
606         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
607                            (match_operand:SI 1 "general_operand" "ri,mr"))
608                  (const_int 0)))]
609   "ix86_match_ccmode (insn, CCGOCmode)"
610   "cmp{l}\t{%1, %0|%0, %1}"
611   [(set_attr "type" "icmp")
612    (set_attr "mode" "SI")])
614 (define_expand "cmpsi_1"
615   [(set (reg:CC FLAGS_REG)
616         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                     (match_operand:SI 1 "general_operand" "ri,mr")))]
618   ""
619   "")
621 (define_insn "*cmpsi_1_insn"
622   [(set (reg FLAGS_REG)
623         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                  (match_operand:SI 1 "general_operand" "ri,mr")))]
625   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
626     && ix86_match_ccmode (insn, CCmode)"
627   "cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "SI")])
631 (define_insn "*cmphi_ccno_1"
632   [(set (reg FLAGS_REG)
633         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
634                  (match_operand:HI 1 "const0_operand" "n,n")))]
635   "ix86_match_ccmode (insn, CCNOmode)"
636   "@
637    test{w}\t{%0, %0|%0, %0}
638    cmp{w}\t{%1, %0|%0, %1}"
639   [(set_attr "type" "test,icmp")
640    (set_attr "length_immediate" "0,1")
641    (set_attr "mode" "HI")])
643 (define_insn "*cmphi_minus_1"
644   [(set (reg FLAGS_REG)
645         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
646                            (match_operand:HI 1 "general_operand" "ri,mr"))
647                  (const_int 0)))]
648   "ix86_match_ccmode (insn, CCGOCmode)"
649   "cmp{w}\t{%1, %0|%0, %1}"
650   [(set_attr "type" "icmp")
651    (set_attr "mode" "HI")])
653 (define_insn "*cmphi_1"
654   [(set (reg FLAGS_REG)
655         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656                  (match_operand:HI 1 "general_operand" "ri,mr")))]
657   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
658    && ix86_match_ccmode (insn, CCmode)"
659   "cmp{w}\t{%1, %0|%0, %1}"
660   [(set_attr "type" "icmp")
661    (set_attr "mode" "HI")])
663 (define_insn "*cmpqi_ccno_1"
664   [(set (reg FLAGS_REG)
665         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
666                  (match_operand:QI 1 "const0_operand" "n,n")))]
667   "ix86_match_ccmode (insn, CCNOmode)"
668   "@
669    test{b}\t{%0, %0|%0, %0}
670    cmp{b}\t{$0, %0|%0, 0}"
671   [(set_attr "type" "test,icmp")
672    (set_attr "length_immediate" "0,1")
673    (set_attr "mode" "QI")])
675 (define_insn "*cmpqi_1"
676   [(set (reg FLAGS_REG)
677         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
678                  (match_operand:QI 1 "general_operand" "qi,mq")))]
679   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
680     && ix86_match_ccmode (insn, CCmode)"
681   "cmp{b}\t{%1, %0|%0, %1}"
682   [(set_attr "type" "icmp")
683    (set_attr "mode" "QI")])
685 (define_insn "*cmpqi_minus_1"
686   [(set (reg FLAGS_REG)
687         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688                            (match_operand:QI 1 "general_operand" "qi,mq"))
689                  (const_int 0)))]
690   "ix86_match_ccmode (insn, CCGOCmode)"
691   "cmp{b}\t{%1, %0|%0, %1}"
692   [(set_attr "type" "icmp")
693    (set_attr "mode" "QI")])
695 (define_insn "*cmpqi_ext_1"
696   [(set (reg FLAGS_REG)
697         (compare
698           (match_operand:QI 0 "general_operand" "Qm")
699           (subreg:QI
700             (zero_extract:SI
701               (match_operand 1 "ext_register_operand" "Q")
702               (const_int 8)
703               (const_int 8)) 0)))]
704   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
705   "cmp{b}\t{%h1, %0|%0, %h1}"
706   [(set_attr "type" "icmp")
707    (set_attr "mode" "QI")])
709 (define_insn "*cmpqi_ext_1_rex64"
710   [(set (reg FLAGS_REG)
711         (compare
712           (match_operand:QI 0 "register_operand" "Q")
713           (subreg:QI
714             (zero_extract:SI
715               (match_operand 1 "ext_register_operand" "Q")
716               (const_int 8)
717               (const_int 8)) 0)))]
718   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
719   "cmp{b}\t{%h1, %0|%0, %h1}"
720   [(set_attr "type" "icmp")
721    (set_attr "mode" "QI")])
723 (define_insn "*cmpqi_ext_2"
724   [(set (reg FLAGS_REG)
725         (compare
726           (subreg:QI
727             (zero_extract:SI
728               (match_operand 0 "ext_register_operand" "Q")
729               (const_int 8)
730               (const_int 8)) 0)
731           (match_operand:QI 1 "const0_operand" "n")))]
732   "ix86_match_ccmode (insn, CCNOmode)"
733   "test{b}\t%h0, %h0"
734   [(set_attr "type" "test")
735    (set_attr "length_immediate" "0")
736    (set_attr "mode" "QI")])
738 (define_expand "cmpqi_ext_3"
739   [(set (reg:CC FLAGS_REG)
740         (compare:CC
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 0 "ext_register_operand" "")
744               (const_int 8)
745               (const_int 8)) 0)
746           (match_operand:QI 1 "general_operand" "")))]
747   ""
748   "")
750 (define_insn "cmpqi_ext_3_insn"
751   [(set (reg FLAGS_REG)
752         (compare
753           (subreg:QI
754             (zero_extract:SI
755               (match_operand 0 "ext_register_operand" "Q")
756               (const_int 8)
757               (const_int 8)) 0)
758           (match_operand:QI 1 "general_operand" "Qmn")))]
759   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
760   "cmp{b}\t{%1, %h0|%h0, %1}"
761   [(set_attr "type" "icmp")
762    (set_attr "mode" "QI")])
764 (define_insn "cmpqi_ext_3_insn_rex64"
765   [(set (reg FLAGS_REG)
766         (compare
767           (subreg:QI
768             (zero_extract:SI
769               (match_operand 0 "ext_register_operand" "Q")
770               (const_int 8)
771               (const_int 8)) 0)
772           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
773   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
774   "cmp{b}\t{%1, %h0|%h0, %1}"
775   [(set_attr "type" "icmp")
776    (set_attr "mode" "QI")])
778 (define_insn "*cmpqi_ext_4"
779   [(set (reg FLAGS_REG)
780         (compare
781           (subreg:QI
782             (zero_extract:SI
783               (match_operand 0 "ext_register_operand" "Q")
784               (const_int 8)
785               (const_int 8)) 0)
786           (subreg:QI
787             (zero_extract:SI
788               (match_operand 1 "ext_register_operand" "Q")
789               (const_int 8)
790               (const_int 8)) 0)))]
791   "ix86_match_ccmode (insn, CCmode)"
792   "cmp{b}\t{%h1, %h0|%h0, %h1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
796 ;; These implement float point compares.
797 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
798 ;; which would allow mix and match FP modes on the compares.  Which is what
799 ;; the old patterns did, but with many more of them.
801 (define_expand "cmpxf"
802   [(set (reg:CC FLAGS_REG)
803         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
804                     (match_operand:XF 1 "nonmemory_operand" "")))]
805   "TARGET_80387"
807   ix86_compare_op0 = operands[0];
808   ix86_compare_op1 = operands[1];
809   DONE;
812 (define_expand "cmpdf"
813   [(set (reg:CC FLAGS_REG)
814         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
815                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
816   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
818   ix86_compare_op0 = operands[0];
819   ix86_compare_op1 = operands[1];
820   DONE;
823 (define_expand "cmpsf"
824   [(set (reg:CC FLAGS_REG)
825         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
826                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
827   "TARGET_80387 || TARGET_SSE_MATH"
829   ix86_compare_op0 = operands[0];
830   ix86_compare_op1 = operands[1];
831   DONE;
834 ;; FP compares, step 1:
835 ;; Set the FP condition codes.
837 ;; CCFPmode     compare with exceptions
838 ;; CCFPUmode    compare with no exceptions
840 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
841 ;; used to manage the reg stack popping would not be preserved.
843 (define_insn "*cmpfp_0"
844   [(set (match_operand:HI 0 "register_operand" "=a")
845         (unspec:HI
846           [(compare:CCFP
847              (match_operand 1 "register_operand" "f")
848              (match_operand 2 "const0_operand" "X"))]
849         UNSPEC_FNSTSW))]
850   "TARGET_80387
851    && FLOAT_MODE_P (GET_MODE (operands[1]))
852    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
853   "* return output_fp_compare (insn, operands, 0, 0);"
854   [(set_attr "type" "multi")
855    (set_attr "unit" "i387")
856    (set (attr "mode")
857      (cond [(match_operand:SF 1 "" "")
858               (const_string "SF")
859             (match_operand:DF 1 "" "")
860               (const_string "DF")
861            ]
862            (const_string "XF")))])
864 (define_insn "*cmpfp_sf"
865   [(set (match_operand:HI 0 "register_operand" "=a")
866         (unspec:HI
867           [(compare:CCFP
868              (match_operand:SF 1 "register_operand" "f")
869              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
870           UNSPEC_FNSTSW))]
871   "TARGET_80387"
872   "* return output_fp_compare (insn, operands, 0, 0);"
873   [(set_attr "type" "multi")
874    (set_attr "unit" "i387")
875    (set_attr "mode" "SF")])
877 (define_insn "*cmpfp_df"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFP
881              (match_operand:DF 1 "register_operand" "f")
882              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
883           UNSPEC_FNSTSW))]
884   "TARGET_80387"
885   "* return output_fp_compare (insn, operands, 0, 0);"
886   [(set_attr "type" "multi")
887    (set_attr "unit" "i387")
888    (set_attr "mode" "DF")])
890 (define_insn "*cmpfp_xf"
891   [(set (match_operand:HI 0 "register_operand" "=a")
892         (unspec:HI
893           [(compare:CCFP
894              (match_operand:XF 1 "register_operand" "f")
895              (match_operand:XF 2 "register_operand" "f"))]
896           UNSPEC_FNSTSW))]
897   "TARGET_80387"
898   "* return output_fp_compare (insn, operands, 0, 0);"
899   [(set_attr "type" "multi")
900    (set_attr "unit" "i387")
901    (set_attr "mode" "XF")])
903 (define_insn "*cmpfp_u"
904   [(set (match_operand:HI 0 "register_operand" "=a")
905         (unspec:HI
906           [(compare:CCFPU
907              (match_operand 1 "register_operand" "f")
908              (match_operand 2 "register_operand" "f"))]
909           UNSPEC_FNSTSW))]
910   "TARGET_80387
911    && FLOAT_MODE_P (GET_MODE (operands[1]))
912    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
913   "* return output_fp_compare (insn, operands, 0, 1);"
914   [(set_attr "type" "multi")
915    (set_attr "unit" "i387")
916    (set (attr "mode")
917      (cond [(match_operand:SF 1 "" "")
918               (const_string "SF")
919             (match_operand:DF 1 "" "")
920               (const_string "DF")
921            ]
922            (const_string "XF")))])
924 (define_insn "*cmpfp_<mode>"
925   [(set (match_operand:HI 0 "register_operand" "=a")
926         (unspec:HI
927           [(compare:CCFP
928              (match_operand 1 "register_operand" "f")
929              (match_operator 3 "float_operator"
930                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
931           UNSPEC_FNSTSW))]
932   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
933    && FLOAT_MODE_P (GET_MODE (operands[1]))
934    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
935   "* return output_fp_compare (insn, operands, 0, 0);"
936   [(set_attr "type" "multi")
937    (set_attr "unit" "i387")
938    (set_attr "fp_int_src" "true")
939    (set_attr "mode" "<MODE>")])
941 ;; FP compares, step 2
942 ;; Move the fpsw to ax.
944 (define_insn "x86_fnstsw_1"
945   [(set (match_operand:HI 0 "register_operand" "=a")
946         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
947   "TARGET_80387"
948   "fnstsw\t%0"
949   [(set_attr "length" "2")
950    (set_attr "mode" "SI")
951    (set_attr "unit" "i387")])
953 ;; FP compares, step 3
954 ;; Get ax into flags, general case.
956 (define_insn "x86_sahf_1"
957   [(set (reg:CC FLAGS_REG)
958         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
959   "!TARGET_64BIT"
960   "sahf"
961   [(set_attr "length" "1")
962    (set_attr "athlon_decode" "vector")
963    (set_attr "mode" "SI")])
965 ;; Pentium Pro can do steps 1 through 3 in one go.
967 (define_insn "*cmpfp_i_mixed"
968   [(set (reg:CCFP FLAGS_REG)
969         (compare:CCFP (match_operand 0 "register_operand" "f,x")
970                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
971   "TARGET_MIX_SSE_I387
972    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
973    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
974   "* return output_fp_compare (insn, operands, 1, 0);"
975   [(set_attr "type" "fcmp,ssecomi")
976    (set (attr "mode")
977      (if_then_else (match_operand:SF 1 "" "")
978         (const_string "SF")
979         (const_string "DF")))
980    (set_attr "athlon_decode" "vector")])
982 (define_insn "*cmpfp_i_sse"
983   [(set (reg:CCFP FLAGS_REG)
984         (compare:CCFP (match_operand 0 "register_operand" "x")
985                       (match_operand 1 "nonimmediate_operand" "xm")))]
986   "TARGET_SSE_MATH
987    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
988    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
989   "* return output_fp_compare (insn, operands, 1, 0);"
990   [(set_attr "type" "ssecomi")
991    (set (attr "mode")
992      (if_then_else (match_operand:SF 1 "" "")
993         (const_string "SF")
994         (const_string "DF")))
995    (set_attr "athlon_decode" "vector")])
997 (define_insn "*cmpfp_i_i387"
998   [(set (reg:CCFP FLAGS_REG)
999         (compare:CCFP (match_operand 0 "register_operand" "f")
1000                       (match_operand 1 "register_operand" "f")))]
1001   "TARGET_80387 && TARGET_CMOVE
1002    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1003    && FLOAT_MODE_P (GET_MODE (operands[0]))
1004    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005   "* return output_fp_compare (insn, operands, 1, 0);"
1006   [(set_attr "type" "fcmp")
1007    (set (attr "mode")
1008      (cond [(match_operand:SF 1 "" "")
1009               (const_string "SF")
1010             (match_operand:DF 1 "" "")
1011               (const_string "DF")
1012            ]
1013            (const_string "XF")))
1014    (set_attr "athlon_decode" "vector")])
1016 (define_insn "*cmpfp_iu_mixed"
1017   [(set (reg:CCFPU FLAGS_REG)
1018         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1019                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1020   "TARGET_MIX_SSE_I387
1021    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1022    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023   "* return output_fp_compare (insn, operands, 1, 1);"
1024   [(set_attr "type" "fcmp,ssecomi")
1025    (set (attr "mode")
1026      (if_then_else (match_operand:SF 1 "" "")
1027         (const_string "SF")
1028         (const_string "DF")))
1029    (set_attr "athlon_decode" "vector")])
1031 (define_insn "*cmpfp_iu_sse"
1032   [(set (reg:CCFPU FLAGS_REG)
1033         (compare:CCFPU (match_operand 0 "register_operand" "x")
1034                        (match_operand 1 "nonimmediate_operand" "xm")))]
1035   "TARGET_SSE_MATH
1036    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1037    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1038   "* return output_fp_compare (insn, operands, 1, 1);"
1039   [(set_attr "type" "ssecomi")
1040    (set (attr "mode")
1041      (if_then_else (match_operand:SF 1 "" "")
1042         (const_string "SF")
1043         (const_string "DF")))
1044    (set_attr "athlon_decode" "vector")])
1046 (define_insn "*cmpfp_iu_387"
1047   [(set (reg:CCFPU FLAGS_REG)
1048         (compare:CCFPU (match_operand 0 "register_operand" "f")
1049                        (match_operand 1 "register_operand" "f")))]
1050   "TARGET_80387 && TARGET_CMOVE
1051    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1052    && FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054   "* return output_fp_compare (insn, operands, 1, 1);"
1055   [(set_attr "type" "fcmp")
1056    (set (attr "mode")
1057      (cond [(match_operand:SF 1 "" "")
1058               (const_string "SF")
1059             (match_operand:DF 1 "" "")
1060               (const_string "DF")
1061            ]
1062            (const_string "XF")))
1063    (set_attr "athlon_decode" "vector")])
1065 ;; Move instructions.
1067 ;; General case of fullword move.
1069 (define_expand "movsi"
1070   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1071         (match_operand:SI 1 "general_operand" ""))]
1072   ""
1073   "ix86_expand_move (SImode, operands); DONE;")
1075 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1076 ;; general_operand.
1078 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1079 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1080 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1081 ;; targets without our curiosities, and it is just as easy to represent
1082 ;; this differently.
1084 (define_insn "*pushsi2"
1085   [(set (match_operand:SI 0 "push_operand" "=<")
1086         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1087   "!TARGET_64BIT"
1088   "push{l}\t%1"
1089   [(set_attr "type" "push")
1090    (set_attr "mode" "SI")])
1092 ;; For 64BIT abi we always round up to 8 bytes.
1093 (define_insn "*pushsi2_rex64"
1094   [(set (match_operand:SI 0 "push_operand" "=X")
1095         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1096   "TARGET_64BIT"
1097   "push{q}\t%q1"
1098   [(set_attr "type" "push")
1099    (set_attr "mode" "SI")])
1101 (define_insn "*pushsi2_prologue"
1102   [(set (match_operand:SI 0 "push_operand" "=<")
1103         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1104    (clobber (mem:BLK (scratch)))]
1105   "!TARGET_64BIT"
1106   "push{l}\t%1"
1107   [(set_attr "type" "push")
1108    (set_attr "mode" "SI")])
1110 (define_insn "*popsi1_epilogue"
1111   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1112         (mem:SI (reg:SI SP_REG)))
1113    (set (reg:SI SP_REG)
1114         (plus:SI (reg:SI SP_REG) (const_int 4)))
1115    (clobber (mem:BLK (scratch)))]
1116   "!TARGET_64BIT"
1117   "pop{l}\t%0"
1118   [(set_attr "type" "pop")
1119    (set_attr "mode" "SI")])
1121 (define_insn "popsi1"
1122   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1123         (mem:SI (reg:SI SP_REG)))
1124    (set (reg:SI SP_REG)
1125         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1126   "!TARGET_64BIT"
1127   "pop{l}\t%0"
1128   [(set_attr "type" "pop")
1129    (set_attr "mode" "SI")])
1131 (define_insn "*movsi_xor"
1132   [(set (match_operand:SI 0 "register_operand" "=r")
1133         (match_operand:SI 1 "const0_operand" "i"))
1134    (clobber (reg:CC FLAGS_REG))]
1135   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1136   "xor{l}\t{%0, %0|%0, %0}"
1137   [(set_attr "type" "alu1")
1138    (set_attr "mode" "SI")
1139    (set_attr "length_immediate" "0")])
1141 (define_insn "*movsi_or"
1142   [(set (match_operand:SI 0 "register_operand" "=r")
1143         (match_operand:SI 1 "immediate_operand" "i"))
1144    (clobber (reg:CC FLAGS_REG))]
1145   "reload_completed
1146    && operands[1] == constm1_rtx
1147    && (TARGET_PENTIUM || optimize_size)"
1149   operands[1] = constm1_rtx;
1150   return "or{l}\t{%1, %0|%0, %1}";
1152   [(set_attr "type" "alu1")
1153    (set_attr "mode" "SI")
1154    (set_attr "length_immediate" "1")])
1156 (define_insn "*movsi_1"
1157   [(set (match_operand:SI 0 "nonimmediate_operand"
1158                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1159         (match_operand:SI 1 "general_operand"
1160                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1161   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1163   switch (get_attr_type (insn))
1164     {
1165     case TYPE_SSELOG1:
1166       if (get_attr_mode (insn) == MODE_TI)
1167         return "pxor\t%0, %0";
1168       return "xorps\t%0, %0";
1170     case TYPE_SSEMOV:
1171       switch (get_attr_mode (insn))
1172         {
1173         case MODE_TI:
1174           return "movdqa\t{%1, %0|%0, %1}";
1175         case MODE_V4SF:
1176           return "movaps\t{%1, %0|%0, %1}";
1177         case MODE_SI:
1178           return "movd\t{%1, %0|%0, %1}";
1179         case MODE_SF:
1180           return "movss\t{%1, %0|%0, %1}";
1181         default:
1182           gcc_unreachable ();
1183         }
1185     case TYPE_MMXADD:
1186       return "pxor\t%0, %0";
1188     case TYPE_MMXMOV:
1189       if (get_attr_mode (insn) == MODE_DI)
1190         return "movq\t{%1, %0|%0, %1}";
1191       return "movd\t{%1, %0|%0, %1}";
1193     case TYPE_LEA:
1194       return "lea{l}\t{%1, %0|%0, %1}";
1196     default:
1197       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1198       return "mov{l}\t{%1, %0|%0, %1}";
1199     }
1201   [(set (attr "type")
1202      (cond [(eq_attr "alternative" "2")
1203               (const_string "mmxadd")
1204             (eq_attr "alternative" "3,4,5")
1205               (const_string "mmxmov")
1206             (eq_attr "alternative" "6")
1207               (const_string "sselog1")
1208             (eq_attr "alternative" "7,8,9,10,11")
1209               (const_string "ssemov")
1210             (match_operand:DI 1 "pic_32bit_operand" "")
1211               (const_string "lea")
1212            ]
1213            (const_string "imov")))
1214    (set (attr "mode")
1215      (cond [(eq_attr "alternative" "2,3")
1216               (const_string "DI")
1217             (eq_attr "alternative" "6,7")
1218               (if_then_else
1219                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1220                 (const_string "V4SF")
1221                 (const_string "TI"))
1222             (and (eq_attr "alternative" "8,9,10,11")
1223                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1224               (const_string "SF")
1225            ]
1226            (const_string "SI")))])
1228 ;; Stores and loads of ax to arbitrary constant address.
1229 ;; We fake an second form of instruction to force reload to load address
1230 ;; into register when rax is not available
1231 (define_insn "*movabssi_1_rex64"
1232   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1233         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1234   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1235   "@
1236    movabs{l}\t{%1, %P0|%P0, %1}
1237    mov{l}\t{%1, %a0|%a0, %1}"
1238   [(set_attr "type" "imov")
1239    (set_attr "modrm" "0,*")
1240    (set_attr "length_address" "8,0")
1241    (set_attr "length_immediate" "0,*")
1242    (set_attr "memory" "store")
1243    (set_attr "mode" "SI")])
1245 (define_insn "*movabssi_2_rex64"
1246   [(set (match_operand:SI 0 "register_operand" "=a,r")
1247         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1248   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1249   "@
1250    movabs{l}\t{%P1, %0|%0, %P1}
1251    mov{l}\t{%a1, %0|%0, %a1}"
1252   [(set_attr "type" "imov")
1253    (set_attr "modrm" "0,*")
1254    (set_attr "length_address" "8,0")
1255    (set_attr "length_immediate" "0")
1256    (set_attr "memory" "load")
1257    (set_attr "mode" "SI")])
1259 (define_insn "*swapsi"
1260   [(set (match_operand:SI 0 "register_operand" "+r")
1261         (match_operand:SI 1 "register_operand" "+r"))
1262    (set (match_dup 1)
1263         (match_dup 0))]
1264   ""
1265   "xchg{l}\t%1, %0"
1266   [(set_attr "type" "imov")
1267    (set_attr "mode" "SI")
1268    (set_attr "pent_pair" "np")
1269    (set_attr "athlon_decode" "vector")])
1271 (define_expand "movhi"
1272   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1273         (match_operand:HI 1 "general_operand" ""))]
1274   ""
1275   "ix86_expand_move (HImode, operands); DONE;")
1277 (define_insn "*pushhi2"
1278   [(set (match_operand:HI 0 "push_operand" "=X")
1279         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1280   "!TARGET_64BIT"
1281   "push{l}\t%k1"
1282   [(set_attr "type" "push")
1283    (set_attr "mode" "SI")])
1285 ;; For 64BIT abi we always round up to 8 bytes.
1286 (define_insn "*pushhi2_rex64"
1287   [(set (match_operand:HI 0 "push_operand" "=X")
1288         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1289   "TARGET_64BIT"
1290   "push{q}\t%q1"
1291   [(set_attr "type" "push")
1292    (set_attr "mode" "DI")])
1294 (define_insn "*movhi_1"
1295   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1297   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299   switch (get_attr_type (insn))
1300     {
1301     case TYPE_IMOVX:
1302       /* movzwl is faster than movw on p2 due to partial word stalls,
1303          though not as fast as an aligned movl.  */
1304       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1305     default:
1306       if (get_attr_mode (insn) == MODE_SI)
1307         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1308       else
1309         return "mov{w}\t{%1, %0|%0, %1}";
1310     }
1312   [(set (attr "type")
1313      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1314               (const_string "imov")
1315             (and (eq_attr "alternative" "0")
1316                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1317                           (const_int 0))
1318                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1319                           (const_int 0))))
1320               (const_string "imov")
1321             (and (eq_attr "alternative" "1,2")
1322                  (match_operand:HI 1 "aligned_operand" ""))
1323               (const_string "imov")
1324             (and (ne (symbol_ref "TARGET_MOVX")
1325                      (const_int 0))
1326                  (eq_attr "alternative" "0,2"))
1327               (const_string "imovx")
1328            ]
1329            (const_string "imov")))
1330     (set (attr "mode")
1331       (cond [(eq_attr "type" "imovx")
1332                (const_string "SI")
1333              (and (eq_attr "alternative" "1,2")
1334                   (match_operand:HI 1 "aligned_operand" ""))
1335                (const_string "SI")
1336              (and (eq_attr "alternative" "0")
1337                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1338                            (const_int 0))
1339                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1340                            (const_int 0))))
1341                (const_string "SI")
1342             ]
1343             (const_string "HI")))])
1345 ;; Stores and loads of ax to arbitrary constant address.
1346 ;; We fake an second form of instruction to force reload to load address
1347 ;; into register when rax is not available
1348 (define_insn "*movabshi_1_rex64"
1349   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1350         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1351   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1352   "@
1353    movabs{w}\t{%1, %P0|%P0, %1}
1354    mov{w}\t{%1, %a0|%a0, %1}"
1355   [(set_attr "type" "imov")
1356    (set_attr "modrm" "0,*")
1357    (set_attr "length_address" "8,0")
1358    (set_attr "length_immediate" "0,*")
1359    (set_attr "memory" "store")
1360    (set_attr "mode" "HI")])
1362 (define_insn "*movabshi_2_rex64"
1363   [(set (match_operand:HI 0 "register_operand" "=a,r")
1364         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1365   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1366   "@
1367    movabs{w}\t{%P1, %0|%0, %P1}
1368    mov{w}\t{%a1, %0|%0, %a1}"
1369   [(set_attr "type" "imov")
1370    (set_attr "modrm" "0,*")
1371    (set_attr "length_address" "8,0")
1372    (set_attr "length_immediate" "0")
1373    (set_attr "memory" "load")
1374    (set_attr "mode" "HI")])
1376 (define_insn "*swaphi_1"
1377   [(set (match_operand:HI 0 "register_operand" "+r")
1378         (match_operand:HI 1 "register_operand" "+r"))
1379    (set (match_dup 1)
1380         (match_dup 0))]
1381   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1382   "xchg{l}\t%k1, %k0"
1383   [(set_attr "type" "imov")
1384    (set_attr "mode" "SI")
1385    (set_attr "pent_pair" "np")
1386    (set_attr "athlon_decode" "vector")])
1388 (define_insn "*swaphi_2"
1389   [(set (match_operand:HI 0 "register_operand" "+r")
1390         (match_operand:HI 1 "register_operand" "+r"))
1391    (set (match_dup 1)
1392         (match_dup 0))]
1393   "TARGET_PARTIAL_REG_STALL"
1394   "xchg{w}\t%1, %0"
1395   [(set_attr "type" "imov")
1396    (set_attr "mode" "HI")
1397    (set_attr "pent_pair" "np")
1398    (set_attr "athlon_decode" "vector")])
1400 (define_expand "movstricthi"
1401   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1402         (match_operand:HI 1 "general_operand" ""))]
1403   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405   /* Don't generate memory->memory moves, go through a register */
1406   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1407     operands[1] = force_reg (HImode, operands[1]);
1410 (define_insn "*movstricthi_1"
1411   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1412         (match_operand:HI 1 "general_operand" "rn,m"))]
1413   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1414    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1415   "mov{w}\t{%1, %0|%0, %1}"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "HI")])
1419 (define_insn "*movstricthi_xor"
1420   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1421         (match_operand:HI 1 "const0_operand" "i"))
1422    (clobber (reg:CC FLAGS_REG))]
1423   "reload_completed
1424    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1425   "xor{w}\t{%0, %0|%0, %0}"
1426   [(set_attr "type" "alu1")
1427    (set_attr "mode" "HI")
1428    (set_attr "length_immediate" "0")])
1430 (define_expand "movqi"
1431   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1432         (match_operand:QI 1 "general_operand" ""))]
1433   ""
1434   "ix86_expand_move (QImode, operands); DONE;")
1436 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1437 ;; "push a byte".  But actually we use pushl, which has the effect
1438 ;; of rounding the amount pushed up to a word.
1440 (define_insn "*pushqi2"
1441   [(set (match_operand:QI 0 "push_operand" "=X")
1442         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1443   "!TARGET_64BIT"
1444   "push{l}\t%k1"
1445   [(set_attr "type" "push")
1446    (set_attr "mode" "SI")])
1448 ;; For 64BIT abi we always round up to 8 bytes.
1449 (define_insn "*pushqi2_rex64"
1450   [(set (match_operand:QI 0 "push_operand" "=X")
1451         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1452   "TARGET_64BIT"
1453   "push{q}\t%q1"
1454   [(set_attr "type" "push")
1455    (set_attr "mode" "DI")])
1457 ;; Situation is quite tricky about when to choose full sized (SImode) move
1458 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1459 ;; partial register dependency machines (such as AMD Athlon), where QImode
1460 ;; moves issue extra dependency and for partial register stalls machines
1461 ;; that don't use QImode patterns (and QImode move cause stall on the next
1462 ;; instruction).
1464 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1465 ;; register stall machines with, where we use QImode instructions, since
1466 ;; partial register stall can be caused there.  Then we use movzx.
1467 (define_insn "*movqi_1"
1468   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1469         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1470   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1472   switch (get_attr_type (insn))
1473     {
1474     case TYPE_IMOVX:
1475       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1476       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1477     default:
1478       if (get_attr_mode (insn) == MODE_SI)
1479         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1480       else
1481         return "mov{b}\t{%1, %0|%0, %1}";
1482     }
1484   [(set (attr "type")
1485      (cond [(and (eq_attr "alternative" "5")
1486                  (not (match_operand:QI 1 "aligned_operand" "")))
1487               (const_string "imovx")
1488             (ne (symbol_ref "optimize_size") (const_int 0))
1489               (const_string "imov")
1490             (and (eq_attr "alternative" "3")
1491                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1492                           (const_int 0))
1493                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1494                           (const_int 0))))
1495               (const_string "imov")
1496             (eq_attr "alternative" "3,5")
1497               (const_string "imovx")
1498             (and (ne (symbol_ref "TARGET_MOVX")
1499                      (const_int 0))
1500                  (eq_attr "alternative" "2"))
1501               (const_string "imovx")
1502            ]
1503            (const_string "imov")))
1504    (set (attr "mode")
1505       (cond [(eq_attr "alternative" "3,4,5")
1506                (const_string "SI")
1507              (eq_attr "alternative" "6")
1508                (const_string "QI")
1509              (eq_attr "type" "imovx")
1510                (const_string "SI")
1511              (and (eq_attr "type" "imov")
1512                   (and (eq_attr "alternative" "0,1")
1513                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1514                                 (const_int 0))
1515                             (and (eq (symbol_ref "optimize_size")
1516                                      (const_int 0))
1517                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518                                      (const_int 0))))))
1519                (const_string "SI")
1520              ;; Avoid partial register stalls when not using QImode arithmetic
1521              (and (eq_attr "type" "imov")
1522                   (and (eq_attr "alternative" "0,1")
1523                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1524                                 (const_int 0))
1525                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1526                                 (const_int 0)))))
1527                (const_string "SI")
1528            ]
1529            (const_string "QI")))])
1531 (define_expand "reload_outqi"
1532   [(parallel [(match_operand:QI 0 "" "=m")
1533               (match_operand:QI 1 "register_operand" "r")
1534               (match_operand:QI 2 "register_operand" "=&q")])]
1535   ""
1537   rtx op0, op1, op2;
1538   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1540   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1541   if (! q_regs_operand (op1, QImode))
1542     {
1543       emit_insn (gen_movqi (op2, op1));
1544       op1 = op2;
1545     }
1546   emit_insn (gen_movqi (op0, op1));
1547   DONE;
1550 (define_insn "*swapqi_1"
1551   [(set (match_operand:QI 0 "register_operand" "+r")
1552         (match_operand:QI 1 "register_operand" "+r"))
1553    (set (match_dup 1)
1554         (match_dup 0))]
1555   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1556   "xchg{l}\t%k1, %k0"
1557   [(set_attr "type" "imov")
1558    (set_attr "mode" "SI")
1559    (set_attr "pent_pair" "np")
1560    (set_attr "athlon_decode" "vector")])
1562 (define_insn "*swapqi_2"
1563   [(set (match_operand:QI 0 "register_operand" "+q")
1564         (match_operand:QI 1 "register_operand" "+q"))
1565    (set (match_dup 1)
1566         (match_dup 0))]
1567   "TARGET_PARTIAL_REG_STALL"
1568   "xchg{b}\t%1, %0"
1569   [(set_attr "type" "imov")
1570    (set_attr "mode" "QI")
1571    (set_attr "pent_pair" "np")
1572    (set_attr "athlon_decode" "vector")])
1574 (define_expand "movstrictqi"
1575   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1576         (match_operand:QI 1 "general_operand" ""))]
1577   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1579   /* Don't generate memory->memory moves, go through a register.  */
1580   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1581     operands[1] = force_reg (QImode, operands[1]);
1584 (define_insn "*movstrictqi_1"
1585   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1586         (match_operand:QI 1 "general_operand" "*qn,m"))]
1587   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1588    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1589   "mov{b}\t{%1, %0|%0, %1}"
1590   [(set_attr "type" "imov")
1591    (set_attr "mode" "QI")])
1593 (define_insn "*movstrictqi_xor"
1594   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1595         (match_operand:QI 1 "const0_operand" "i"))
1596    (clobber (reg:CC FLAGS_REG))]
1597   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1598   "xor{b}\t{%0, %0|%0, %0}"
1599   [(set_attr "type" "alu1")
1600    (set_attr "mode" "QI")
1601    (set_attr "length_immediate" "0")])
1603 (define_insn "*movsi_extv_1"
1604   [(set (match_operand:SI 0 "register_operand" "=R")
1605         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1606                          (const_int 8)
1607                          (const_int 8)))]
1608   ""
1609   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1610   [(set_attr "type" "imovx")
1611    (set_attr "mode" "SI")])
1613 (define_insn "*movhi_extv_1"
1614   [(set (match_operand:HI 0 "register_operand" "=R")
1615         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1616                          (const_int 8)
1617                          (const_int 8)))]
1618   ""
1619   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1620   [(set_attr "type" "imovx")
1621    (set_attr "mode" "SI")])
1623 (define_insn "*movqi_extv_1"
1624   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1625         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1626                          (const_int 8)
1627                          (const_int 8)))]
1628   "!TARGET_64BIT"
1630   switch (get_attr_type (insn))
1631     {
1632     case TYPE_IMOVX:
1633       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1634     default:
1635       return "mov{b}\t{%h1, %0|%0, %h1}";
1636     }
1638   [(set (attr "type")
1639      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1640                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1641                              (ne (symbol_ref "TARGET_MOVX")
1642                                  (const_int 0))))
1643         (const_string "imovx")
1644         (const_string "imov")))
1645    (set (attr "mode")
1646      (if_then_else (eq_attr "type" "imovx")
1647         (const_string "SI")
1648         (const_string "QI")))])
1650 (define_insn "*movqi_extv_1_rex64"
1651   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1652         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   "TARGET_64BIT"
1657   switch (get_attr_type (insn))
1658     {
1659     case TYPE_IMOVX:
1660       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1661     default:
1662       return "mov{b}\t{%h1, %0|%0, %h1}";
1663     }
1665   [(set (attr "type")
1666      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1667                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1668                              (ne (symbol_ref "TARGET_MOVX")
1669                                  (const_int 0))))
1670         (const_string "imovx")
1671         (const_string "imov")))
1672    (set (attr "mode")
1673      (if_then_else (eq_attr "type" "imovx")
1674         (const_string "SI")
1675         (const_string "QI")))])
1677 ;; Stores and loads of ax to arbitrary constant address.
1678 ;; We fake an second form of instruction to force reload to load address
1679 ;; into register when rax is not available
1680 (define_insn "*movabsqi_1_rex64"
1681   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1682         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1683   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1684   "@
1685    movabs{b}\t{%1, %P0|%P0, %1}
1686    mov{b}\t{%1, %a0|%a0, %1}"
1687   [(set_attr "type" "imov")
1688    (set_attr "modrm" "0,*")
1689    (set_attr "length_address" "8,0")
1690    (set_attr "length_immediate" "0,*")
1691    (set_attr "memory" "store")
1692    (set_attr "mode" "QI")])
1694 (define_insn "*movabsqi_2_rex64"
1695   [(set (match_operand:QI 0 "register_operand" "=a,r")
1696         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1697   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1698   "@
1699    movabs{b}\t{%P1, %0|%0, %P1}
1700    mov{b}\t{%a1, %0|%0, %a1}"
1701   [(set_attr "type" "imov")
1702    (set_attr "modrm" "0,*")
1703    (set_attr "length_address" "8,0")
1704    (set_attr "length_immediate" "0")
1705    (set_attr "memory" "load")
1706    (set_attr "mode" "QI")])
1708 (define_insn "*movdi_extzv_1"
1709   [(set (match_operand:DI 0 "register_operand" "=R")
1710         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1711                          (const_int 8)
1712                          (const_int 8)))]
1713   "TARGET_64BIT"
1714   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1715   [(set_attr "type" "imovx")
1716    (set_attr "mode" "DI")])
1718 (define_insn "*movsi_extzv_1"
1719   [(set (match_operand:SI 0 "register_operand" "=R")
1720         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1721                          (const_int 8)
1722                          (const_int 8)))]
1723   ""
1724   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1725   [(set_attr "type" "imovx")
1726    (set_attr "mode" "SI")])
1728 (define_insn "*movqi_extzv_2"
1729   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1730         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1731                                     (const_int 8)
1732                                     (const_int 8)) 0))]
1733   "!TARGET_64BIT"
1735   switch (get_attr_type (insn))
1736     {
1737     case TYPE_IMOVX:
1738       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1739     default:
1740       return "mov{b}\t{%h1, %0|%0, %h1}";
1741     }
1743   [(set (attr "type")
1744      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1745                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1746                              (ne (symbol_ref "TARGET_MOVX")
1747                                  (const_int 0))))
1748         (const_string "imovx")
1749         (const_string "imov")))
1750    (set (attr "mode")
1751      (if_then_else (eq_attr "type" "imovx")
1752         (const_string "SI")
1753         (const_string "QI")))])
1755 (define_insn "*movqi_extzv_2_rex64"
1756   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1757         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1758                                     (const_int 8)
1759                                     (const_int 8)) 0))]
1760   "TARGET_64BIT"
1762   switch (get_attr_type (insn))
1763     {
1764     case TYPE_IMOVX:
1765       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1766     default:
1767       return "mov{b}\t{%h1, %0|%0, %h1}";
1768     }
1770   [(set (attr "type")
1771      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1772                         (ne (symbol_ref "TARGET_MOVX")
1773                             (const_int 0)))
1774         (const_string "imovx")
1775         (const_string "imov")))
1776    (set (attr "mode")
1777      (if_then_else (eq_attr "type" "imovx")
1778         (const_string "SI")
1779         (const_string "QI")))])
1781 (define_insn "movsi_insv_1"
1782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1783                          (const_int 8)
1784                          (const_int 8))
1785         (match_operand:SI 1 "general_operand" "Qmn"))]
1786   "!TARGET_64BIT"
1787   "mov{b}\t{%b1, %h0|%h0, %b1}"
1788   [(set_attr "type" "imov")
1789    (set_attr "mode" "QI")])
1791 (define_insn "movdi_insv_1_rex64"
1792   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1793                          (const_int 8)
1794                          (const_int 8))
1795         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1796   "TARGET_64BIT"
1797   "mov{b}\t{%b1, %h0|%h0, %b1}"
1798   [(set_attr "type" "imov")
1799    (set_attr "mode" "QI")])
1801 (define_insn "*movqi_insv_2"
1802   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1803                          (const_int 8)
1804                          (const_int 8))
1805         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1806                      (const_int 8)))]
1807   ""
1808   "mov{b}\t{%h1, %h0|%h0, %h1}"
1809   [(set_attr "type" "imov")
1810    (set_attr "mode" "QI")])
1812 (define_expand "movdi"
1813   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1814         (match_operand:DI 1 "general_operand" ""))]
1815   ""
1816   "ix86_expand_move (DImode, operands); DONE;")
1818 (define_insn "*pushdi"
1819   [(set (match_operand:DI 0 "push_operand" "=<")
1820         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1821   "!TARGET_64BIT"
1822   "#")
1824 (define_insn "*pushdi2_rex64"
1825   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1826         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1827   "TARGET_64BIT"
1828   "@
1829    push{q}\t%1
1830    #"
1831   [(set_attr "type" "push,multi")
1832    (set_attr "mode" "DI")])
1834 ;; Convert impossible pushes of immediate to existing instructions.
1835 ;; First try to get scratch register and go through it.  In case this
1836 ;; fails, push sign extended lower part first and then overwrite
1837 ;; upper part by 32bit move.
1838 (define_peephole2
1839   [(match_scratch:DI 2 "r")
1840    (set (match_operand:DI 0 "push_operand" "")
1841         (match_operand:DI 1 "immediate_operand" ""))]
1842   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1843    && !x86_64_immediate_operand (operands[1], DImode)"
1844   [(set (match_dup 2) (match_dup 1))
1845    (set (match_dup 0) (match_dup 2))]
1846   "")
1848 ;; We need to define this as both peepholer and splitter for case
1849 ;; peephole2 pass is not run.
1850 ;; "&& 1" is needed to keep it from matching the previous pattern.
1851 (define_peephole2
1852   [(set (match_operand:DI 0 "push_operand" "")
1853         (match_operand:DI 1 "immediate_operand" ""))]
1854   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1855    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1856   [(set (match_dup 0) (match_dup 1))
1857    (set (match_dup 2) (match_dup 3))]
1858   "split_di (operands + 1, 1, operands + 2, operands + 3);
1859    operands[1] = gen_lowpart (DImode, operands[2]);
1860    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1861                                                     GEN_INT (4)));
1862   ")
1864 (define_split
1865   [(set (match_operand:DI 0 "push_operand" "")
1866         (match_operand:DI 1 "immediate_operand" ""))]
1867   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1868                     ? flow2_completed : reload_completed)
1869    && !symbolic_operand (operands[1], DImode)
1870    && !x86_64_immediate_operand (operands[1], DImode)"
1871   [(set (match_dup 0) (match_dup 1))
1872    (set (match_dup 2) (match_dup 3))]
1873   "split_di (operands + 1, 1, operands + 2, operands + 3);
1874    operands[1] = gen_lowpart (DImode, operands[2]);
1875    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1876                                                     GEN_INT (4)));
1877   ")
1879 (define_insn "*pushdi2_prologue_rex64"
1880   [(set (match_operand:DI 0 "push_operand" "=<")
1881         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1882    (clobber (mem:BLK (scratch)))]
1883   "TARGET_64BIT"
1884   "push{q}\t%1"
1885   [(set_attr "type" "push")
1886    (set_attr "mode" "DI")])
1888 (define_insn "*popdi1_epilogue_rex64"
1889   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1890         (mem:DI (reg:DI SP_REG)))
1891    (set (reg:DI SP_REG)
1892         (plus:DI (reg:DI SP_REG) (const_int 8)))
1893    (clobber (mem:BLK (scratch)))]
1894   "TARGET_64BIT"
1895   "pop{q}\t%0"
1896   [(set_attr "type" "pop")
1897    (set_attr "mode" "DI")])
1899 (define_insn "popdi1"
1900   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1901         (mem:DI (reg:DI SP_REG)))
1902    (set (reg:DI SP_REG)
1903         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1904   "TARGET_64BIT"
1905   "pop{q}\t%0"
1906   [(set_attr "type" "pop")
1907    (set_attr "mode" "DI")])
1909 (define_insn "*movdi_xor_rex64"
1910   [(set (match_operand:DI 0 "register_operand" "=r")
1911         (match_operand:DI 1 "const0_operand" "i"))
1912    (clobber (reg:CC FLAGS_REG))]
1913   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1914    && reload_completed"
1915   "xor{l}\t{%k0, %k0|%k0, %k0}"
1916   [(set_attr "type" "alu1")
1917    (set_attr "mode" "SI")
1918    (set_attr "length_immediate" "0")])
1920 (define_insn "*movdi_or_rex64"
1921   [(set (match_operand:DI 0 "register_operand" "=r")
1922         (match_operand:DI 1 "const_int_operand" "i"))
1923    (clobber (reg:CC FLAGS_REG))]
1924   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1925    && reload_completed
1926    && operands[1] == constm1_rtx"
1928   operands[1] = constm1_rtx;
1929   return "or{q}\t{%1, %0|%0, %1}";
1931   [(set_attr "type" "alu1")
1932    (set_attr "mode" "DI")
1933    (set_attr "length_immediate" "1")])
1935 (define_insn "*movdi_2"
1936   [(set (match_operand:DI 0 "nonimmediate_operand"
1937                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1938         (match_operand:DI 1 "general_operand"
1939                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1940   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1941   "@
1942    #
1943    #
1944    pxor\t%0, %0
1945    movq\t{%1, %0|%0, %1}
1946    movq\t{%1, %0|%0, %1}
1947    pxor\t%0, %0
1948    movq\t{%1, %0|%0, %1}
1949    movdqa\t{%1, %0|%0, %1}
1950    movq\t{%1, %0|%0, %1}
1951    xorps\t%0, %0
1952    movlps\t{%1, %0|%0, %1}
1953    movaps\t{%1, %0|%0, %1}
1954    movlps\t{%1, %0|%0, %1}"
1955   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1956    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958 (define_split
1959   [(set (match_operand:DI 0 "push_operand" "")
1960         (match_operand:DI 1 "general_operand" ""))]
1961   "!TARGET_64BIT && reload_completed
1962    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1963   [(const_int 0)]
1964   "ix86_split_long_move (operands); DONE;")
1966 ;; %%% This multiword shite has got to go.
1967 (define_split
1968   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1969         (match_operand:DI 1 "general_operand" ""))]
1970   "!TARGET_64BIT && reload_completed
1971    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1972    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973   [(const_int 0)]
1974   "ix86_split_long_move (operands); DONE;")
1976 (define_insn "*movdi_1_rex64"
1977   [(set (match_operand:DI 0 "nonimmediate_operand"
1978                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1979         (match_operand:DI 1 "general_operand"
1980                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1981   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983   switch (get_attr_type (insn))
1984     {
1985     case TYPE_SSECVT:
1986       if (which_alternative == 13)
1987         return "movq2dq\t{%1, %0|%0, %1}";
1988       else
1989         return "movdq2q\t{%1, %0|%0, %1}";
1990     case TYPE_SSEMOV:
1991       if (get_attr_mode (insn) == MODE_TI)
1992           return "movdqa\t{%1, %0|%0, %1}";
1993       /* FALLTHRU */
1994     case TYPE_MMXMOV:
1995       /* Moves from and into integer register is done using movd opcode with
1996          REX prefix.  */
1997       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1998           return "movd\t{%1, %0|%0, %1}";
1999       return "movq\t{%1, %0|%0, %1}";
2000     case TYPE_SSELOG1:
2001     case TYPE_MMXADD:
2002       return "pxor\t%0, %0";
2003     case TYPE_MULTI:
2004       return "#";
2005     case TYPE_LEA:
2006       return "lea{q}\t{%a1, %0|%0, %a1}";
2007     default:
2008       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2009       if (get_attr_mode (insn) == MODE_SI)
2010         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011       else if (which_alternative == 2)
2012         return "movabs{q}\t{%1, %0|%0, %1}";
2013       else
2014         return "mov{q}\t{%1, %0|%0, %1}";
2015     }
2017   [(set (attr "type")
2018      (cond [(eq_attr "alternative" "5")
2019               (const_string "mmxadd")
2020             (eq_attr "alternative" "6,7,8")
2021               (const_string "mmxmov")
2022             (eq_attr "alternative" "9")
2023               (const_string "sselog1")
2024             (eq_attr "alternative" "10,11,12")
2025               (const_string "ssemov")
2026             (eq_attr "alternative" "13,14")
2027               (const_string "ssecvt")
2028             (eq_attr "alternative" "4")
2029               (const_string "multi")
2030             (match_operand:DI 1 "pic_32bit_operand" "")
2031               (const_string "lea")
2032            ]
2033            (const_string "imov")))
2034    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2035    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2036    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2038 ;; Stores and loads of ax to arbitrary constant address.
2039 ;; We fake an second form of instruction to force reload to load address
2040 ;; into register when rax is not available
2041 (define_insn "*movabsdi_1_rex64"
2042   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2043         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2044   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2045   "@
2046    movabs{q}\t{%1, %P0|%P0, %1}
2047    mov{q}\t{%1, %a0|%a0, %1}"
2048   [(set_attr "type" "imov")
2049    (set_attr "modrm" "0,*")
2050    (set_attr "length_address" "8,0")
2051    (set_attr "length_immediate" "0,*")
2052    (set_attr "memory" "store")
2053    (set_attr "mode" "DI")])
2055 (define_insn "*movabsdi_2_rex64"
2056   [(set (match_operand:DI 0 "register_operand" "=a,r")
2057         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2058   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2059   "@
2060    movabs{q}\t{%P1, %0|%0, %P1}
2061    mov{q}\t{%a1, %0|%0, %a1}"
2062   [(set_attr "type" "imov")
2063    (set_attr "modrm" "0,*")
2064    (set_attr "length_address" "8,0")
2065    (set_attr "length_immediate" "0")
2066    (set_attr "memory" "load")
2067    (set_attr "mode" "DI")])
2069 ;; Convert impossible stores of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it.  In case this
2071 ;; fails, move by 32bit parts.
2072 (define_peephole2
2073   [(match_scratch:DI 2 "r")
2074    (set (match_operand:DI 0 "memory_operand" "")
2075         (match_operand:DI 1 "immediate_operand" ""))]
2076   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2077    && !x86_64_immediate_operand (operands[1], DImode)"
2078   [(set (match_dup 2) (match_dup 1))
2079    (set (match_dup 0) (match_dup 2))]
2080   "")
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 (define_peephole2
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090   [(set (match_dup 2) (match_dup 3))
2091    (set (match_dup 4) (match_dup 5))]
2092   "split_di (operands, 2, operands + 2, operands + 4);")
2094 (define_split
2095   [(set (match_operand:DI 0 "memory_operand" "")
2096         (match_operand:DI 1 "immediate_operand" ""))]
2097   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2098                     ? flow2_completed : reload_completed)
2099    && !symbolic_operand (operands[1], DImode)
2100    && !x86_64_immediate_operand (operands[1], DImode)"
2101   [(set (match_dup 2) (match_dup 3))
2102    (set (match_dup 4) (match_dup 5))]
2103   "split_di (operands, 2, operands + 2, operands + 4);")
2105 (define_insn "*swapdi_rex64"
2106   [(set (match_operand:DI 0 "register_operand" "+r")
2107         (match_operand:DI 1 "register_operand" "+r"))
2108    (set (match_dup 1)
2109         (match_dup 0))]
2110   "TARGET_64BIT"
2111   "xchg{q}\t%1, %0"
2112   [(set_attr "type" "imov")
2113    (set_attr "mode" "DI")
2114    (set_attr "pent_pair" "np")
2115    (set_attr "athlon_decode" "vector")])
2117 (define_expand "movti"
2118   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2119         (match_operand:TI 1 "nonimmediate_operand" ""))]
2120   "TARGET_SSE || TARGET_64BIT"
2122   if (TARGET_64BIT)
2123     ix86_expand_move (TImode, operands);
2124   else
2125     ix86_expand_vector_move (TImode, operands);
2126   DONE;
2129 (define_insn "*movti_internal"
2130   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2131         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2132   "TARGET_SSE && !TARGET_64BIT
2133    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2135   switch (which_alternative)
2136     {
2137     case 0:
2138       if (get_attr_mode (insn) == MODE_V4SF)
2139         return "xorps\t%0, %0";
2140       else
2141         return "pxor\t%0, %0";
2142     case 1:
2143     case 2:
2144       if (get_attr_mode (insn) == MODE_V4SF)
2145         return "movaps\t{%1, %0|%0, %1}";
2146       else
2147         return "movdqa\t{%1, %0|%0, %1}";
2148     default:
2149       gcc_unreachable ();
2150     }
2152   [(set_attr "type" "sselog1,ssemov,ssemov")
2153    (set (attr "mode")
2154         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2155                     (ne (symbol_ref "optimize_size") (const_int 0)))
2156                  (const_string "V4SF")
2157                (and (eq_attr "alternative" "2")
2158                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2159                         (const_int 0)))
2160                  (const_string "V4SF")]
2161               (const_string "TI")))])
2163 (define_insn "*movti_rex64"
2164   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2165         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2166   "TARGET_64BIT
2167    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169   switch (which_alternative)
2170     {
2171     case 0:
2172     case 1:
2173       return "#";
2174     case 2:
2175       if (get_attr_mode (insn) == MODE_V4SF)
2176         return "xorps\t%0, %0";
2177       else
2178         return "pxor\t%0, %0";
2179     case 3:
2180     case 4:
2181       if (get_attr_mode (insn) == MODE_V4SF)
2182         return "movaps\t{%1, %0|%0, %1}";
2183       else
2184         return "movdqa\t{%1, %0|%0, %1}";
2185     default:
2186       gcc_unreachable ();
2187     }
2189   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2190    (set (attr "mode")
2191         (cond [(eq_attr "alternative" "2,3")
2192                  (if_then_else
2193                    (ne (symbol_ref "optimize_size")
2194                        (const_int 0))
2195                    (const_string "V4SF")
2196                    (const_string "TI"))
2197                (eq_attr "alternative" "4")
2198                  (if_then_else
2199                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2200                             (const_int 0))
2201                         (ne (symbol_ref "optimize_size")
2202                             (const_int 0)))
2203                    (const_string "V4SF")
2204                    (const_string "TI"))]
2205                (const_string "DI")))])
2207 (define_split
2208   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2209         (match_operand:TI 1 "general_operand" ""))]
2210   "reload_completed && !SSE_REG_P (operands[0])
2211    && !SSE_REG_P (operands[1])"
2212   [(const_int 0)]
2213   "ix86_split_long_move (operands); DONE;")
2215 (define_expand "movsf"
2216   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2217         (match_operand:SF 1 "general_operand" ""))]
2218   ""
2219   "ix86_expand_move (SFmode, operands); DONE;")
2221 (define_insn "*pushsf"
2222   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2223         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2224   "!TARGET_64BIT"
2226   /* Anything else should be already split before reg-stack.  */
2227   gcc_assert (which_alternative == 1);
2228   return "push{l}\t%1";
2230   [(set_attr "type" "multi,push,multi")
2231    (set_attr "unit" "i387,*,*")
2232    (set_attr "mode" "SF,SI,SF")])
2234 (define_insn "*pushsf_rex64"
2235   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2236         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2237   "TARGET_64BIT"
2239   /* Anything else should be already split before reg-stack.  */
2240   gcc_assert (which_alternative == 1);
2241   return "push{q}\t%q1";
2243   [(set_attr "type" "multi,push,multi")
2244    (set_attr "unit" "i387,*,*")
2245    (set_attr "mode" "SF,DI,SF")])
2247 (define_split
2248   [(set (match_operand:SF 0 "push_operand" "")
2249         (match_operand:SF 1 "memory_operand" ""))]
2250   "reload_completed
2251    && GET_CODE (operands[1]) == MEM
2252    && constant_pool_reference_p (operands[1])"
2253   [(set (match_dup 0)
2254         (match_dup 1))]
2255   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2258 ;; %%% Kill this when call knows how to work this out.
2259 (define_split
2260   [(set (match_operand:SF 0 "push_operand" "")
2261         (match_operand:SF 1 "any_fp_register_operand" ""))]
2262   "!TARGET_64BIT"
2263   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2264    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266 (define_split
2267   [(set (match_operand:SF 0 "push_operand" "")
2268         (match_operand:SF 1 "any_fp_register_operand" ""))]
2269   "TARGET_64BIT"
2270   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2271    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2273 (define_insn "*movsf_1"
2274   [(set (match_operand:SF 0 "nonimmediate_operand"
2275           "=f,m   ,f,r,m    ,x,x,x,m   ,!*y,!rm,!*y")
2276         (match_operand:SF 1 "general_operand"
2277           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2278   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2279    && (reload_in_progress || reload_completed
2280        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2281        || GET_CODE (operands[1]) != CONST_DOUBLE
2282        || memory_operand (operands[0], SFmode))" 
2284   switch (which_alternative)
2285     {
2286     case 0:
2287       return output_387_reg_move (insn, operands);
2289     case 1:
2290       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2291         return "fstp%z0\t%y0";
2292       else
2293         return "fst%z0\t%y0";
2295     case 2:
2296       return standard_80387_constant_opcode (operands[1]);
2298     case 3:
2299     case 4:
2300       return "mov{l}\t{%1, %0|%0, %1}";
2301     case 5:
2302       if (get_attr_mode (insn) == MODE_TI)
2303         return "pxor\t%0, %0";
2304       else
2305         return "xorps\t%0, %0";
2306     case 6:
2307       if (get_attr_mode (insn) == MODE_V4SF)
2308         return "movaps\t{%1, %0|%0, %1}";
2309       else
2310         return "movss\t{%1, %0|%0, %1}";
2311     case 7:
2312     case 8:
2313       return "movss\t{%1, %0|%0, %1}";
2315     case 9:
2316     case 10:
2317       return "movd\t{%1, %0|%0, %1}";
2319     case 11:
2320       return "movq\t{%1, %0|%0, %1}";
2322     default:
2323       gcc_unreachable ();
2324     }
2326   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2327    (set (attr "mode")
2328         (cond [(eq_attr "alternative" "3,4,9,10")
2329                  (const_string "SI")
2330                (eq_attr "alternative" "5")
2331                  (if_then_else
2332                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2333                                  (const_int 0))
2334                              (ne (symbol_ref "TARGET_SSE2")
2335                                  (const_int 0)))
2336                         (eq (symbol_ref "optimize_size")
2337                             (const_int 0)))
2338                    (const_string "TI")
2339                    (const_string "V4SF"))
2340                /* For architectures resolving dependencies on
2341                   whole SSE registers use APS move to break dependency
2342                   chains, otherwise use short move to avoid extra work. 
2344                   Do the same for architectures resolving dependencies on
2345                   the parts.  While in DF mode it is better to always handle
2346                   just register parts, the SF mode is different due to lack
2347                   of instructions to load just part of the register.  It is
2348                   better to maintain the whole registers in single format
2349                   to avoid problems on using packed logical operations.  */
2350                (eq_attr "alternative" "6")
2351                  (if_then_else
2352                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2353                             (const_int 0))
2354                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2355                             (const_int 0)))
2356                    (const_string "V4SF")
2357                    (const_string "SF"))
2358                (eq_attr "alternative" "11")
2359                  (const_string "DI")]
2360                (const_string "SF")))])
2362 (define_insn "*swapsf"
2363   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2364         (match_operand:SF 1 "fp_register_operand" "+f"))
2365    (set (match_dup 1)
2366         (match_dup 0))]
2367   "reload_completed || TARGET_80387"
2369   if (STACK_TOP_P (operands[0]))
2370     return "fxch\t%1";
2371   else
2372     return "fxch\t%0";
2374   [(set_attr "type" "fxch")
2375    (set_attr "mode" "SF")])
2377 (define_expand "movdf"
2378   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2379         (match_operand:DF 1 "general_operand" ""))]
2380   ""
2381   "ix86_expand_move (DFmode, operands); DONE;")
2383 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2384 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2385 ;; On the average, pushdf using integers can be still shorter.  Allow this
2386 ;; pattern for optimize_size too.
2388 (define_insn "*pushdf_nointeger"
2389   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2390         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2391   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2393   /* This insn should be already split before reg-stack.  */
2394   gcc_unreachable ();
2396   [(set_attr "type" "multi")
2397    (set_attr "unit" "i387,*,*,*")
2398    (set_attr "mode" "DF,SI,SI,DF")])
2400 (define_insn "*pushdf_integer"
2401   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2402         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2403   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2405   /* This insn should be already split before reg-stack.  */
2406   gcc_unreachable ();
2408   [(set_attr "type" "multi")
2409    (set_attr "unit" "i387,*,*")
2410    (set_attr "mode" "DF,SI,DF")])
2412 ;; %%% Kill this when call knows how to work this out.
2413 (define_split
2414   [(set (match_operand:DF 0 "push_operand" "")
2415         (match_operand:DF 1 "any_fp_register_operand" ""))]
2416   "!TARGET_64BIT && reload_completed"
2417   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2418    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2419   "")
2421 (define_split
2422   [(set (match_operand:DF 0 "push_operand" "")
2423         (match_operand:DF 1 "any_fp_register_operand" ""))]
2424   "TARGET_64BIT && reload_completed"
2425   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2426    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2427   "")
2429 (define_split
2430   [(set (match_operand:DF 0 "push_operand" "")
2431         (match_operand:DF 1 "general_operand" ""))]
2432   "reload_completed"
2433   [(const_int 0)]
2434   "ix86_split_long_move (operands); DONE;")
2436 ;; Moving is usually shorter when only FP registers are used. This separate
2437 ;; movdf pattern avoids the use of integer registers for FP operations
2438 ;; when optimizing for size.
2440 (define_insn "*movdf_nointeger"
2441   [(set (match_operand:DF 0 "nonimmediate_operand"
2442                         "=f,m  ,f,*r  ,o  ,Y*x,Y*x,Y*x,m    ")
2443         (match_operand:DF 1 "general_operand"
2444                         "fm,f,G  ,*roF,F*r,C    ,Y*x,mY*x,Y*x"))]
2445   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2446    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2447    && (reload_in_progress || reload_completed
2448        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2449        || GET_CODE (operands[1]) != CONST_DOUBLE
2450        || memory_operand (operands[0], DFmode))" 
2452   switch (which_alternative)
2453     {
2454     case 0:
2455       return output_387_reg_move (insn, operands);
2457     case 1:
2458       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2459         return "fstp%z0\t%y0";
2460       else
2461         return "fst%z0\t%y0";
2463     case 2:
2464       return standard_80387_constant_opcode (operands[1]);
2466     case 3:
2467     case 4:
2468       return "#";
2469     case 5:
2470       switch (get_attr_mode (insn))
2471         {
2472         case MODE_V4SF:
2473           return "xorps\t%0, %0";
2474         case MODE_V2DF:
2475           return "xorpd\t%0, %0";
2476         case MODE_TI:
2477           return "pxor\t%0, %0";
2478         default:
2479           gcc_unreachable ();
2480         }
2481     case 6:
2482     case 7:
2483     case 8:
2484       switch (get_attr_mode (insn))
2485         {
2486         case MODE_V4SF:
2487           return "movaps\t{%1, %0|%0, %1}";
2488         case MODE_V2DF:
2489           return "movapd\t{%1, %0|%0, %1}";
2490         case MODE_TI:
2491           return "movdqa\t{%1, %0|%0, %1}";
2492         case MODE_DI:
2493           return "movq\t{%1, %0|%0, %1}";
2494         case MODE_DF:
2495           return "movsd\t{%1, %0|%0, %1}";
2496         case MODE_V1DF:
2497           return "movlpd\t{%1, %0|%0, %1}";
2498         case MODE_V2SF:
2499           return "movlps\t{%1, %0|%0, %1}";
2500         default:
2501           gcc_unreachable ();
2502         }
2504     default:
2505       gcc_unreachable ();
2506     }
2508   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2509    (set (attr "mode")
2510         (cond [(eq_attr "alternative" "0,1,2")
2511                  (const_string "DF")
2512                (eq_attr "alternative" "3,4")
2513                  (const_string "SI")
2515                /* For SSE1, we have many fewer alternatives.  */
2516                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2517                  (cond [(eq_attr "alternative" "5,6")
2518                           (const_string "V4SF")
2519                        ]
2520                    (const_string "V2SF"))
2522                /* xorps is one byte shorter.  */
2523                (eq_attr "alternative" "5")
2524                  (cond [(ne (symbol_ref "optimize_size")
2525                             (const_int 0))
2526                           (const_string "V4SF")
2527                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2528                             (const_int 0))
2529                           (const_string "TI")
2530                        ]
2531                        (const_string "V2DF"))
2533                /* For architectures resolving dependencies on
2534                   whole SSE registers use APD move to break dependency
2535                   chains, otherwise use short move to avoid extra work.
2537                   movaps encodes one byte shorter.  */
2538                (eq_attr "alternative" "6")
2539                  (cond
2540                    [(ne (symbol_ref "optimize_size")
2541                         (const_int 0))
2542                       (const_string "V4SF")
2543                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2544                         (const_int 0))
2545                       (const_string "V2DF")
2546                    ]
2547                    (const_string "DF"))
2548                /* For architectures resolving dependencies on register
2549                   parts we may avoid extra work to zero out upper part
2550                   of register.  */
2551                (eq_attr "alternative" "7")
2552                  (if_then_else
2553                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2554                        (const_int 0))
2555                    (const_string "V1DF")
2556                    (const_string "DF"))
2557               ]
2558               (const_string "DF")))])
2560 (define_insn "*movdf_integer"
2561   [(set (match_operand:DF 0 "nonimmediate_operand"
2562                 "=f,m   ,f,r,o    ,Y*x,Y*x,Y*x,m")
2563         (match_operand:DF 1 "general_operand"
2564                 "fm,f,G   ,roF,Fr,C     ,Y*x,m     ,Y*x"))]
2565   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2566    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2567    && (reload_in_progress || reload_completed
2568        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2569        || GET_CODE (operands[1]) != CONST_DOUBLE
2570        || memory_operand (operands[0], DFmode))" 
2572   switch (which_alternative)
2573     {
2574     case 0:
2575       return output_387_reg_move (insn, operands);
2577     case 1:
2578       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2579         return "fstp%z0\t%y0";
2580       else
2581         return "fst%z0\t%y0";
2583     case 2:
2584       return standard_80387_constant_opcode (operands[1]);
2586     case 3:
2587     case 4:
2588       return "#";
2590     case 5:
2591       switch (get_attr_mode (insn))
2592         {
2593         case MODE_V4SF:
2594           return "xorps\t%0, %0";
2595         case MODE_V2DF:
2596           return "xorpd\t%0, %0";
2597         case MODE_TI:
2598           return "pxor\t%0, %0";
2599         default:
2600           gcc_unreachable ();
2601         }
2602     case 6:
2603     case 7:
2604     case 8:
2605       switch (get_attr_mode (insn))
2606         {
2607         case MODE_V4SF:
2608           return "movaps\t{%1, %0|%0, %1}";
2609         case MODE_V2DF:
2610           return "movapd\t{%1, %0|%0, %1}";
2611         case MODE_TI:
2612           return "movdqa\t{%1, %0|%0, %1}";
2613         case MODE_DI:
2614           return "movq\t{%1, %0|%0, %1}";
2615         case MODE_DF:
2616           return "movsd\t{%1, %0|%0, %1}";
2617         case MODE_V1DF:
2618           return "movlpd\t{%1, %0|%0, %1}";
2619         case MODE_V2SF:
2620           return "movlps\t{%1, %0|%0, %1}";
2621         default:
2622           gcc_unreachable ();
2623         }
2625     default:
2626       gcc_unreachable();
2627     }
2629   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2630    (set (attr "mode")
2631         (cond [(eq_attr "alternative" "0,1,2")
2632                  (const_string "DF")
2633                (eq_attr "alternative" "3,4")
2634                  (const_string "SI")
2636                /* For SSE1, we have many fewer alternatives.  */
2637                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2638                  (cond [(eq_attr "alternative" "5,6")
2639                           (const_string "V4SF")
2640                        ]
2641                    (const_string "V2SF"))
2643                /* xorps is one byte shorter.  */
2644                (eq_attr "alternative" "5")
2645                  (cond [(ne (symbol_ref "optimize_size")
2646                             (const_int 0))
2647                           (const_string "V4SF")
2648                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2649                             (const_int 0))
2650                           (const_string "TI")
2651                        ]
2652                        (const_string "V2DF"))
2654                /* For architectures resolving dependencies on
2655                   whole SSE registers use APD move to break dependency
2656                   chains, otherwise use short move to avoid extra work.
2658                   movaps encodes one byte shorter.  */
2659                (eq_attr "alternative" "6")
2660                  (cond
2661                    [(ne (symbol_ref "optimize_size")
2662                         (const_int 0))
2663                       (const_string "V4SF")
2664                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2665                         (const_int 0))
2666                       (const_string "V2DF")
2667                    ]
2668                    (const_string "DF"))
2669                /* For architectures resolving dependencies on register
2670                   parts we may avoid extra work to zero out upper part
2671                   of register.  */
2672                (eq_attr "alternative" "7")
2673                  (if_then_else
2674                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2675                        (const_int 0))
2676                    (const_string "V1DF")
2677                    (const_string "DF"))
2678               ]
2679               (const_string "DF")))])
2681 (define_split
2682   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2683         (match_operand:DF 1 "general_operand" ""))]
2684   "reload_completed
2685    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2686    && ! (ANY_FP_REG_P (operands[0]) || 
2687          (GET_CODE (operands[0]) == SUBREG
2688           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2689    && ! (ANY_FP_REG_P (operands[1]) || 
2690          (GET_CODE (operands[1]) == SUBREG
2691           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2692   [(const_int 0)]
2693   "ix86_split_long_move (operands); DONE;")
2695 (define_insn "*swapdf"
2696   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2697         (match_operand:DF 1 "fp_register_operand" "+f"))
2698    (set (match_dup 1)
2699         (match_dup 0))]
2700   "reload_completed || TARGET_80387"
2702   if (STACK_TOP_P (operands[0]))
2703     return "fxch\t%1";
2704   else
2705     return "fxch\t%0";
2707   [(set_attr "type" "fxch")
2708    (set_attr "mode" "DF")])
2710 (define_expand "movxf"
2711   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2712         (match_operand:XF 1 "general_operand" ""))]
2713   ""
2714   "ix86_expand_move (XFmode, operands); DONE;")
2716 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2717 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2718 ;; Pushing using integer instructions is longer except for constants
2719 ;; and direct memory references.
2720 ;; (assuming that any given constant is pushed only once, but this ought to be
2721 ;;  handled elsewhere).
2723 (define_insn "*pushxf_nointeger"
2724   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2725         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2726   "optimize_size"
2728   /* This insn should be already split before reg-stack.  */
2729   gcc_unreachable ();
2731   [(set_attr "type" "multi")
2732    (set_attr "unit" "i387,*,*")
2733    (set_attr "mode" "XF,SI,SI")])
2735 (define_insn "*pushxf_integer"
2736   [(set (match_operand:XF 0 "push_operand" "=<,<")
2737         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2738   "!optimize_size"
2740   /* This insn should be already split before reg-stack.  */
2741   gcc_unreachable ();
2743   [(set_attr "type" "multi")
2744    (set_attr "unit" "i387,*")
2745    (set_attr "mode" "XF,SI")])
2747 (define_split
2748   [(set (match_operand 0 "push_operand" "")
2749         (match_operand 1 "general_operand" ""))]
2750   "reload_completed
2751    && (GET_MODE (operands[0]) == XFmode
2752        || GET_MODE (operands[0]) == DFmode)
2753    && !ANY_FP_REG_P (operands[1])"
2754   [(const_int 0)]
2755   "ix86_split_long_move (operands); DONE;")
2757 (define_split
2758   [(set (match_operand:XF 0 "push_operand" "")
2759         (match_operand:XF 1 "any_fp_register_operand" ""))]
2760   "!TARGET_64BIT"
2761   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2762    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2763   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765 (define_split
2766   [(set (match_operand:XF 0 "push_operand" "")
2767         (match_operand:XF 1 "any_fp_register_operand" ""))]
2768   "TARGET_64BIT"
2769   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2770    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2771   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773 ;; Do not use integer registers when optimizing for size
2774 (define_insn "*movxf_nointeger"
2775   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2776         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2777   "optimize_size
2778    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2779    && (reload_in_progress || reload_completed
2780        || GET_CODE (operands[1]) != CONST_DOUBLE
2781        || memory_operand (operands[0], XFmode))" 
2783   switch (which_alternative)
2784     {
2785     case 0:
2786       return output_387_reg_move (insn, operands);
2788     case 1:
2789       /* There is no non-popping store to memory for XFmode.  So if
2790          we need one, follow the store with a load.  */
2791       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2792         return "fstp%z0\t%y0\;fld%z0\t%y0";
2793       else
2794         return "fstp%z0\t%y0";
2796     case 2:
2797       return standard_80387_constant_opcode (operands[1]);
2799     case 3: case 4:
2800       return "#";
2801     default:
2802       gcc_unreachable ();
2803     }
2805   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2806    (set_attr "mode" "XF,XF,XF,SI,SI")])
2808 (define_insn "*movxf_integer"
2809   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2810         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2811   "!optimize_size
2812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813    && (reload_in_progress || reload_completed
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))" 
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2833     case 3: case 4:
2834       return "#";
2836     default:
2837       gcc_unreachable ();
2838     }
2840   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2841    (set_attr "mode" "XF,XF,XF,SI,SI")])
2843 (define_split
2844   [(set (match_operand 0 "nonimmediate_operand" "")
2845         (match_operand 1 "general_operand" ""))]
2846   "reload_completed
2847    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2848    && GET_MODE (operands[0]) == XFmode
2849    && ! (ANY_FP_REG_P (operands[0]) || 
2850          (GET_CODE (operands[0]) == SUBREG
2851           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2852    && ! (ANY_FP_REG_P (operands[1]) || 
2853          (GET_CODE (operands[1]) == SUBREG
2854           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2855   [(const_int 0)]
2856   "ix86_split_long_move (operands); DONE;")
2858 (define_split
2859   [(set (match_operand 0 "register_operand" "")
2860         (match_operand 1 "memory_operand" ""))]
2861   "reload_completed
2862    && GET_CODE (operands[1]) == MEM
2863    && (GET_MODE (operands[0]) == XFmode
2864        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2865    && constant_pool_reference_p (operands[1])"
2866   [(set (match_dup 0) (match_dup 1))]
2868   rtx c = avoid_constant_pool_reference (operands[1]);
2869   rtx r = operands[0];
2871   if (GET_CODE (r) == SUBREG)
2872     r = SUBREG_REG (r);
2874   if (SSE_REG_P (r))
2875     {
2876       if (!standard_sse_constant_p (c))
2877         FAIL;
2878     }
2879   else if (FP_REG_P (r))
2880     {
2881       if (!standard_80387_constant_p (c))
2882         FAIL;
2883     }
2884   else if (MMX_REG_P (r))
2885     FAIL;
2887   operands[1] = c;
2890 (define_insn "swapxf"
2891   [(set (match_operand:XF 0 "register_operand" "+f")
2892         (match_operand:XF 1 "register_operand" "+f"))
2893    (set (match_dup 1)
2894         (match_dup 0))]
2895   "TARGET_80387"
2897   if (STACK_TOP_P (operands[0]))
2898     return "fxch\t%1";
2899   else
2900     return "fxch\t%0";
2902   [(set_attr "type" "fxch")
2903    (set_attr "mode" "XF")])
2905 (define_expand "movtf"
2906   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2907         (match_operand:TF 1 "nonimmediate_operand" ""))]
2908   "TARGET_64BIT"
2910   ix86_expand_move (TFmode, operands);
2911   DONE;
2914 (define_insn "*movtf_internal"
2915   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2916         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2917   "TARGET_64BIT
2918    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2920   switch (which_alternative)
2921     {
2922     case 0:
2923     case 1:
2924       return "#";
2925     case 2:
2926       if (get_attr_mode (insn) == MODE_V4SF)
2927         return "xorps\t%0, %0";
2928       else
2929         return "pxor\t%0, %0";
2930     case 3:
2931     case 4:
2932       if (get_attr_mode (insn) == MODE_V4SF)
2933         return "movaps\t{%1, %0|%0, %1}";
2934       else
2935         return "movdqa\t{%1, %0|%0, %1}";
2936     default:
2937       gcc_unreachable ();
2938     }
2940   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2941    (set (attr "mode")
2942         (cond [(eq_attr "alternative" "2,3")
2943                  (if_then_else
2944                    (ne (symbol_ref "optimize_size")
2945                        (const_int 0))
2946                    (const_string "V4SF")
2947                    (const_string "TI"))
2948                (eq_attr "alternative" "4")
2949                  (if_then_else
2950                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2951                             (const_int 0))
2952                         (ne (symbol_ref "optimize_size")
2953                             (const_int 0)))
2954                    (const_string "V4SF")
2955                    (const_string "TI"))]
2956                (const_string "DI")))])
2958 (define_split
2959   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2960         (match_operand:TF 1 "general_operand" ""))]
2961   "reload_completed && !SSE_REG_P (operands[0])
2962    && !SSE_REG_P (operands[1])"
2963   [(const_int 0)]
2964   "ix86_split_long_move (operands); DONE;")
2966 ;; Zero extension instructions
2968 (define_expand "zero_extendhisi2"
2969   [(set (match_operand:SI 0 "register_operand" "")
2970      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2971   ""
2973   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2974     {
2975       operands[1] = force_reg (HImode, operands[1]);
2976       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2977       DONE;
2978     }
2981 (define_insn "zero_extendhisi2_and"
2982   [(set (match_operand:SI 0 "register_operand" "=r")
2983      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2984    (clobber (reg:CC FLAGS_REG))]
2985   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2986   "#"
2987   [(set_attr "type" "alu1")
2988    (set_attr "mode" "SI")])
2990 (define_split
2991   [(set (match_operand:SI 0 "register_operand" "")
2992         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2993    (clobber (reg:CC FLAGS_REG))]
2994   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2995   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2996               (clobber (reg:CC FLAGS_REG))])]
2997   "")
2999 (define_insn "*zero_extendhisi2_movzwl"
3000   [(set (match_operand:SI 0 "register_operand" "=r")
3001      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3002   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3003   "movz{wl|x}\t{%1, %0|%0, %1}"
3004   [(set_attr "type" "imovx")
3005    (set_attr "mode" "SI")])
3007 (define_expand "zero_extendqihi2"
3008   [(parallel
3009     [(set (match_operand:HI 0 "register_operand" "")
3010        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3011      (clobber (reg:CC FLAGS_REG))])]
3012   ""
3013   "")
3015 (define_insn "*zero_extendqihi2_and"
3016   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3017      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3018    (clobber (reg:CC FLAGS_REG))]
3019   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3020   "#"
3021   [(set_attr "type" "alu1")
3022    (set_attr "mode" "HI")])
3024 (define_insn "*zero_extendqihi2_movzbw_and"
3025   [(set (match_operand:HI 0 "register_operand" "=r,r")
3026      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3027    (clobber (reg:CC FLAGS_REG))]
3028   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3029   "#"
3030   [(set_attr "type" "imovx,alu1")
3031    (set_attr "mode" "HI")])
3033 ; zero extend to SImode here to avoid partial register stalls
3034 (define_insn "*zero_extendqihi2_movzbl"
3035   [(set (match_operand:HI 0 "register_operand" "=r")
3036      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3037   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3038   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3039   [(set_attr "type" "imovx")
3040    (set_attr "mode" "SI")])
3042 ;; For the movzbw case strip only the clobber
3043 (define_split
3044   [(set (match_operand:HI 0 "register_operand" "")
3045         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3046    (clobber (reg:CC FLAGS_REG))]
3047   "reload_completed 
3048    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3049    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3050   [(set (match_operand:HI 0 "register_operand" "")
3051         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3053 ;; When source and destination does not overlap, clear destination
3054 ;; first and then do the movb
3055 (define_split
3056   [(set (match_operand:HI 0 "register_operand" "")
3057         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3058    (clobber (reg:CC FLAGS_REG))]
3059   "reload_completed
3060    && ANY_QI_REG_P (operands[0])
3061    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3063   [(set (match_dup 0) (const_int 0))
3064    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3065   "operands[2] = gen_lowpart (QImode, operands[0]);")
3067 ;; Rest is handled by single and.
3068 (define_split
3069   [(set (match_operand:HI 0 "register_operand" "")
3070         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3071    (clobber (reg:CC FLAGS_REG))]
3072   "reload_completed
3073    && true_regnum (operands[0]) == true_regnum (operands[1])"
3074   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3075               (clobber (reg:CC FLAGS_REG))])]
3076   "")
3078 (define_expand "zero_extendqisi2"
3079   [(parallel
3080     [(set (match_operand:SI 0 "register_operand" "")
3081        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3082      (clobber (reg:CC FLAGS_REG))])]
3083   ""
3084   "")
3086 (define_insn "*zero_extendqisi2_and"
3087   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3088      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3089    (clobber (reg:CC FLAGS_REG))]
3090   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3091   "#"
3092   [(set_attr "type" "alu1")
3093    (set_attr "mode" "SI")])
3095 (define_insn "*zero_extendqisi2_movzbw_and"
3096   [(set (match_operand:SI 0 "register_operand" "=r,r")
3097      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3098    (clobber (reg:CC FLAGS_REG))]
3099   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3100   "#"
3101   [(set_attr "type" "imovx,alu1")
3102    (set_attr "mode" "SI")])
3104 (define_insn "*zero_extendqisi2_movzbw"
3105   [(set (match_operand:SI 0 "register_operand" "=r")
3106      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3107   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3108   "movz{bl|x}\t{%1, %0|%0, %1}"
3109   [(set_attr "type" "imovx")
3110    (set_attr "mode" "SI")])
3112 ;; For the movzbl case strip only the clobber
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3116    (clobber (reg:CC FLAGS_REG))]
3117   "reload_completed 
3118    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3119    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3120   [(set (match_dup 0)
3121         (zero_extend:SI (match_dup 1)))])
3123 ;; When source and destination does not overlap, clear destination
3124 ;; first and then do the movb
3125 (define_split
3126   [(set (match_operand:SI 0 "register_operand" "")
3127         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3128    (clobber (reg:CC FLAGS_REG))]
3129   "reload_completed
3130    && ANY_QI_REG_P (operands[0])
3131    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3132    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3133    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3134   [(set (match_dup 0) (const_int 0))
3135    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3136   "operands[2] = gen_lowpart (QImode, operands[0]);")
3138 ;; Rest is handled by single and.
3139 (define_split
3140   [(set (match_operand:SI 0 "register_operand" "")
3141         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3142    (clobber (reg:CC FLAGS_REG))]
3143   "reload_completed
3144    && true_regnum (operands[0]) == true_regnum (operands[1])"
3145   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3146               (clobber (reg:CC FLAGS_REG))])]
3147   "")
3149 ;; %%% Kill me once multi-word ops are sane.
3150 (define_expand "zero_extendsidi2"
3151   [(set (match_operand:DI 0 "register_operand" "=r")
3152      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3153   ""
3154   "if (!TARGET_64BIT)
3155      {
3156        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3157        DONE;
3158      }
3159   ")
3161 (define_insn "zero_extendsidi2_32"
3162   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3163         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3164    (clobber (reg:CC FLAGS_REG))]
3165   "!TARGET_64BIT"
3166   "@
3167    #
3168    #
3169    #
3170    movd\t{%1, %0|%0, %1}
3171    movd\t{%1, %0|%0, %1}"
3172   [(set_attr "mode" "SI,SI,SI,DI,TI")
3173    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3175 (define_insn "zero_extendsidi2_rex64"
3176   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3177      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3178   "TARGET_64BIT"
3179   "@
3180    mov\t{%k1, %k0|%k0, %k1}
3181    #
3182    movd\t{%1, %0|%0, %1}
3183    movd\t{%1, %0|%0, %1}"
3184   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3185    (set_attr "mode" "SI,DI,SI,SI")])
3187 (define_split
3188   [(set (match_operand:DI 0 "memory_operand" "")
3189      (zero_extend:DI (match_dup 0)))]
3190   "TARGET_64BIT"
3191   [(set (match_dup 4) (const_int 0))]
3192   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194 (define_split 
3195   [(set (match_operand:DI 0 "register_operand" "")
3196         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3197    (clobber (reg:CC FLAGS_REG))]
3198   "!TARGET_64BIT && reload_completed
3199    && true_regnum (operands[0]) == true_regnum (operands[1])"
3200   [(set (match_dup 4) (const_int 0))]
3201   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203 (define_split 
3204   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3205         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3206    (clobber (reg:CC FLAGS_REG))]
3207   "!TARGET_64BIT && reload_completed
3208    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3209   [(set (match_dup 3) (match_dup 1))
3210    (set (match_dup 4) (const_int 0))]
3211   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213 (define_insn "zero_extendhidi2"
3214   [(set (match_operand:DI 0 "register_operand" "=r")
3215      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3216   "TARGET_64BIT"
3217   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3218   [(set_attr "type" "imovx")
3219    (set_attr "mode" "DI")])
3221 (define_insn "zero_extendqidi2"
3222   [(set (match_operand:DI 0 "register_operand" "=r")
3223      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3224   "TARGET_64BIT"
3225   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3226   [(set_attr "type" "imovx")
3227    (set_attr "mode" "DI")])
3229 ;; Sign extension instructions
3231 (define_expand "extendsidi2"
3232   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3233                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3234               (clobber (reg:CC FLAGS_REG))
3235               (clobber (match_scratch:SI 2 ""))])]
3236   ""
3238   if (TARGET_64BIT)
3239     {
3240       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3241       DONE;
3242     }
3245 (define_insn "*extendsidi2_1"
3246   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3247         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3248    (clobber (reg:CC FLAGS_REG))
3249    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3250   "!TARGET_64BIT"
3251   "#")
3253 (define_insn "extendsidi2_rex64"
3254   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3255         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3256   "TARGET_64BIT"
3257   "@
3258    {cltq|cdqe}
3259    movs{lq|x}\t{%1,%0|%0, %1}"
3260   [(set_attr "type" "imovx")
3261    (set_attr "mode" "DI")
3262    (set_attr "prefix_0f" "0")
3263    (set_attr "modrm" "0,1")])
3265 (define_insn "extendhidi2"
3266   [(set (match_operand:DI 0 "register_operand" "=r")
3267         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3268   "TARGET_64BIT"
3269   "movs{wq|x}\t{%1,%0|%0, %1}"
3270   [(set_attr "type" "imovx")
3271    (set_attr "mode" "DI")])
3273 (define_insn "extendqidi2"
3274   [(set (match_operand:DI 0 "register_operand" "=r")
3275         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3276   "TARGET_64BIT"
3277   "movs{bq|x}\t{%1,%0|%0, %1}"
3278    [(set_attr "type" "imovx")
3279     (set_attr "mode" "DI")])
3281 ;; Extend to memory case when source register does die.
3282 (define_split 
3283   [(set (match_operand:DI 0 "memory_operand" "")
3284         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3285    (clobber (reg:CC FLAGS_REG))
3286    (clobber (match_operand:SI 2 "register_operand" ""))]
3287   "(reload_completed
3288     && dead_or_set_p (insn, operands[1])
3289     && !reg_mentioned_p (operands[1], operands[0]))"
3290   [(set (match_dup 3) (match_dup 1))
3291    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3292               (clobber (reg:CC FLAGS_REG))])
3293    (set (match_dup 4) (match_dup 1))]
3294   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3296 ;; Extend to memory case when source register does not die.
3297 (define_split 
3298   [(set (match_operand:DI 0 "memory_operand" "")
3299         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3300    (clobber (reg:CC FLAGS_REG))
3301    (clobber (match_operand:SI 2 "register_operand" ""))]
3302   "reload_completed"
3303   [(const_int 0)]
3305   split_di (&operands[0], 1, &operands[3], &operands[4]);
3307   emit_move_insn (operands[3], operands[1]);
3309   /* Generate a cltd if possible and doing so it profitable.  */
3310   if (true_regnum (operands[1]) == 0
3311       && true_regnum (operands[2]) == 1
3312       && (optimize_size || TARGET_USE_CLTD))
3313     {
3314       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3315     }
3316   else
3317     {
3318       emit_move_insn (operands[2], operands[1]);
3319       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3320     }
3321   emit_move_insn (operands[4], operands[2]);
3322   DONE;
3325 ;; Extend to register case.  Optimize case where source and destination
3326 ;; registers match and cases where we can use cltd.
3327 (define_split 
3328   [(set (match_operand:DI 0 "register_operand" "")
3329         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3330    (clobber (reg:CC FLAGS_REG))
3331    (clobber (match_scratch:SI 2 ""))]
3332   "reload_completed"
3333   [(const_int 0)]
3335   split_di (&operands[0], 1, &operands[3], &operands[4]);
3337   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3338     emit_move_insn (operands[3], operands[1]);
3340   /* Generate a cltd if possible and doing so it profitable.  */
3341   if (true_regnum (operands[3]) == 0
3342       && (optimize_size || TARGET_USE_CLTD))
3343     {
3344       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3345       DONE;
3346     }
3348   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3349     emit_move_insn (operands[4], operands[1]);
3351   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3352   DONE;
3355 (define_insn "extendhisi2"
3356   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3357         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3358   ""
3360   switch (get_attr_prefix_0f (insn))
3361     {
3362     case 0:
3363       return "{cwtl|cwde}";
3364     default:
3365       return "movs{wl|x}\t{%1,%0|%0, %1}";
3366     }
3368   [(set_attr "type" "imovx")
3369    (set_attr "mode" "SI")
3370    (set (attr "prefix_0f")
3371      ;; movsx is short decodable while cwtl is vector decoded.
3372      (if_then_else (and (eq_attr "cpu" "!k6")
3373                         (eq_attr "alternative" "0"))
3374         (const_string "0")
3375         (const_string "1")))
3376    (set (attr "modrm")
3377      (if_then_else (eq_attr "prefix_0f" "0")
3378         (const_string "0")
3379         (const_string "1")))])
3381 (define_insn "*extendhisi2_zext"
3382   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3383         (zero_extend:DI
3384           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3385   "TARGET_64BIT"
3387   switch (get_attr_prefix_0f (insn))
3388     {
3389     case 0:
3390       return "{cwtl|cwde}";
3391     default:
3392       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3393     }
3395   [(set_attr "type" "imovx")
3396    (set_attr "mode" "SI")
3397    (set (attr "prefix_0f")
3398      ;; movsx is short decodable while cwtl is vector decoded.
3399      (if_then_else (and (eq_attr "cpu" "!k6")
3400                         (eq_attr "alternative" "0"))
3401         (const_string "0")
3402         (const_string "1")))
3403    (set (attr "modrm")
3404      (if_then_else (eq_attr "prefix_0f" "0")
3405         (const_string "0")
3406         (const_string "1")))])
3408 (define_insn "extendqihi2"
3409   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3410         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3411   ""
3413   switch (get_attr_prefix_0f (insn))
3414     {
3415     case 0:
3416       return "{cbtw|cbw}";
3417     default:
3418       return "movs{bw|x}\t{%1,%0|%0, %1}";
3419     }
3421   [(set_attr "type" "imovx")
3422    (set_attr "mode" "HI")
3423    (set (attr "prefix_0f")
3424      ;; movsx is short decodable while cwtl is vector decoded.
3425      (if_then_else (and (eq_attr "cpu" "!k6")
3426                         (eq_attr "alternative" "0"))
3427         (const_string "0")
3428         (const_string "1")))
3429    (set (attr "modrm")
3430      (if_then_else (eq_attr "prefix_0f" "0")
3431         (const_string "0")
3432         (const_string "1")))])
3434 (define_insn "extendqisi2"
3435   [(set (match_operand:SI 0 "register_operand" "=r")
3436         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3437   ""
3438   "movs{bl|x}\t{%1,%0|%0, %1}"
3439    [(set_attr "type" "imovx")
3440     (set_attr "mode" "SI")])
3442 (define_insn "*extendqisi2_zext"
3443   [(set (match_operand:DI 0 "register_operand" "=r")
3444         (zero_extend:DI
3445           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3446   "TARGET_64BIT"
3447   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3448    [(set_attr "type" "imovx")
3449     (set_attr "mode" "SI")])
3451 ;; Conversions between float and double.
3453 ;; These are all no-ops in the model used for the 80387.  So just
3454 ;; emit moves.
3456 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3457 (define_insn "*dummy_extendsfdf2"
3458   [(set (match_operand:DF 0 "push_operand" "=<")
3459         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3460   "0"
3461   "#")
3463 (define_split
3464   [(set (match_operand:DF 0 "push_operand" "")
3465         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3466   "!TARGET_64BIT"
3467   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3468    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470 (define_split
3471   [(set (match_operand:DF 0 "push_operand" "")
3472         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3473   "TARGET_64BIT"
3474   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3475    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3477 (define_insn "*dummy_extendsfxf2"
3478   [(set (match_operand:XF 0 "push_operand" "=<")
3479         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3480   "0"
3481   "#")
3483 (define_split
3484   [(set (match_operand:XF 0 "push_operand" "")
3485         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3486   ""
3487   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3488    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3489   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491 (define_split
3492   [(set (match_operand:XF 0 "push_operand" "")
3493         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494   "TARGET_64BIT"
3495   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3496    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3497   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499 (define_split
3500   [(set (match_operand:XF 0 "push_operand" "")
3501         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3502   ""
3503   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3504    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3505   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507 (define_split
3508   [(set (match_operand:XF 0 "push_operand" "")
3509         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510   "TARGET_64BIT"
3511   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3512    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3513   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3515 (define_expand "extendsfdf2"
3516   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3517         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3518   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3520   /* ??? Needed for compress_float_constant since all fp constants
3521      are LEGITIMATE_CONSTANT_P.  */
3522   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3523     {
3524       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3525           && standard_80387_constant_p (operands[1]) > 0)
3526         {
3527           operands[1] = simplify_const_unary_operation
3528             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3529           emit_move_insn_1 (operands[0], operands[1]);
3530           DONE;
3531         }
3532       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3533     }
3534   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3535     operands[1] = force_reg (SFmode, operands[1]);
3538 (define_insn "*extendsfdf2_mixed"
3539   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3540         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3541   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3542    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3544   switch (which_alternative)
3545     {
3546     case 0:
3547       return output_387_reg_move (insn, operands);
3549     case 1:
3550       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3551         return "fstp%z0\t%y0";
3552       else
3553         return "fst%z0\t%y0";
3555     case 2:
3556       return "cvtss2sd\t{%1, %0|%0, %1}";
3558     default:
3559       gcc_unreachable ();
3560     }
3562   [(set_attr "type" "fmov,fmov,ssecvt")
3563    (set_attr "mode" "SF,XF,DF")])
3565 (define_insn "*extendsfdf2_sse"
3566   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3567         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3568   "TARGET_SSE2 && TARGET_SSE_MATH
3569    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3570   "cvtss2sd\t{%1, %0|%0, %1}"
3571   [(set_attr "type" "ssecvt")
3572    (set_attr "mode" "DF")])
3574 (define_insn "*extendsfdf2_i387"
3575   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3576         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3577   "TARGET_80387
3578    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3580   switch (which_alternative)
3581     {
3582     case 0:
3583       return output_387_reg_move (insn, operands);
3585     case 1:
3586       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3587         return "fstp%z0\t%y0";
3588       else
3589         return "fst%z0\t%y0";
3591     default:
3592       gcc_unreachable ();
3593     }
3595   [(set_attr "type" "fmov")
3596    (set_attr "mode" "SF,XF")])
3598 (define_expand "extendsfxf2"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3600         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3601   "TARGET_80387"
3603   /* ??? Needed for compress_float_constant since all fp constants
3604      are LEGITIMATE_CONSTANT_P.  */
3605   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3606     {
3607       if (standard_80387_constant_p (operands[1]) > 0)
3608         {
3609           operands[1] = simplify_const_unary_operation
3610             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3611           emit_move_insn_1 (operands[0], operands[1]);
3612           DONE;
3613         }
3614       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3615     }
3616   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3617     operands[1] = force_reg (SFmode, operands[1]);
3620 (define_insn "*extendsfxf2_i387"
3621   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3622         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3623   "TARGET_80387
3624    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3626   switch (which_alternative)
3627     {
3628     case 0:
3629       return output_387_reg_move (insn, operands);
3631     case 1:
3632       /* There is no non-popping store to memory for XFmode.  So if
3633          we need one, follow the store with a load.  */
3634       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635         return "fstp%z0\t%y0";
3636       else
3637         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3639     default:
3640       gcc_unreachable ();
3641     }
3643   [(set_attr "type" "fmov")
3644    (set_attr "mode" "SF,XF")])
3646 (define_expand "extenddfxf2"
3647   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3648         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3649   "TARGET_80387"
3651   /* ??? Needed for compress_float_constant since all fp constants
3652      are LEGITIMATE_CONSTANT_P.  */
3653   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3654     {
3655       if (standard_80387_constant_p (operands[1]) > 0)
3656         {
3657           operands[1] = simplify_const_unary_operation
3658             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3659           emit_move_insn_1 (operands[0], operands[1]);
3660           DONE;
3661         }
3662       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3663     }
3664   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3665     operands[1] = force_reg (DFmode, operands[1]);
3668 (define_insn "*extenddfxf2_i387"
3669   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3670         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3671   "TARGET_80387
3672    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3674   switch (which_alternative)
3675     {
3676     case 0:
3677       return output_387_reg_move (insn, operands);
3679     case 1:
3680       /* There is no non-popping store to memory for XFmode.  So if
3681          we need one, follow the store with a load.  */
3682       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3683         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3684       else
3685         return "fstp%z0\t%y0";
3687     default:
3688       gcc_unreachable ();
3689     }
3691   [(set_attr "type" "fmov")
3692    (set_attr "mode" "DF,XF")])
3694 ;; %%% This seems bad bad news.
3695 ;; This cannot output into an f-reg because there is no way to be sure
3696 ;; of truncating in that case.  Otherwise this is just like a simple move
3697 ;; insn.  So we pretend we can output to a reg in order to get better
3698 ;; register preferencing, but we really use a stack slot.
3700 ;; Conversion from DFmode to SFmode.
3702 (define_expand "truncdfsf2"
3703   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3704         (float_truncate:SF
3705           (match_operand:DF 1 "nonimmediate_operand" "")))]
3706   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3708   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3709     operands[1] = force_reg (DFmode, operands[1]);
3711   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3712     ;
3713   else if (flag_unsafe_math_optimizations)
3714     ;
3715   else
3716     {
3717       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3718       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3719       DONE;
3720     }
3723 (define_expand "truncdfsf2_with_temp"
3724   [(parallel [(set (match_operand:SF 0 "" "")
3725                    (float_truncate:SF (match_operand:DF 1 "" "")))
3726               (clobber (match_operand:SF 2 "" ""))])]
3727   "")
3729 (define_insn "*truncdfsf_fast_mixed"
3730   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3731         (float_truncate:SF
3732           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3733   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3735   switch (which_alternative)
3736     {
3737     case 0:
3738       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3739         return "fstp%z0\t%y0";
3740       else
3741         return "fst%z0\t%y0";
3742     case 1:
3743       return output_387_reg_move (insn, operands);
3744     case 2:
3745       return "cvtsd2ss\t{%1, %0|%0, %1}";
3746     default:
3747       gcc_unreachable ();
3748     }
3750   [(set_attr "type" "fmov,fmov,ssecvt")
3751    (set_attr "mode" "SF")])
3753 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3754 ;; because nothing we do here is unsafe.
3755 (define_insn "*truncdfsf_fast_sse"
3756   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3757         (float_truncate:SF
3758           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3759   "TARGET_SSE2 && TARGET_SSE_MATH"
3760   "cvtsd2ss\t{%1, %0|%0, %1}"
3761   [(set_attr "type" "ssecvt")
3762    (set_attr "mode" "SF")])
3764 (define_insn "*truncdfsf_fast_i387"
3765   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3766         (float_truncate:SF
3767           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3768   "TARGET_80387 && flag_unsafe_math_optimizations"
3769   "* return output_387_reg_move (insn, operands);"
3770   [(set_attr "type" "fmov")
3771    (set_attr "mode" "SF")])
3773 (define_insn "*truncdfsf_mixed"
3774   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3775         (float_truncate:SF
3776           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3777    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3778   "TARGET_MIX_SSE_I387"
3780   switch (which_alternative)
3781     {
3782     case 0:
3783       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3784         return "fstp%z0\t%y0";
3785       else
3786         return "fst%z0\t%y0";
3787     case 1:
3788       return "#";
3789     case 2:
3790       return "cvtsd2ss\t{%1, %0|%0, %1}";
3791     default:
3792       gcc_unreachable ();
3793     }
3795   [(set_attr "type" "fmov,multi,ssecvt")
3796    (set_attr "unit" "*,i387,*")
3797    (set_attr "mode" "SF")])
3799 (define_insn "*truncdfsf_i387"
3800   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3801         (float_truncate:SF
3802           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3803    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3804   "TARGET_80387"
3806   switch (which_alternative)
3807     {
3808     case 0:
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";
3813     case 1:
3814       return "#";
3815     default:
3816       gcc_unreachable ();
3817     }
3819   [(set_attr "type" "fmov,multi")
3820    (set_attr "unit" "*,i387")
3821    (set_attr "mode" "SF")])
3823 (define_insn "*truncdfsf2_i387_1"
3824   [(set (match_operand:SF 0 "memory_operand" "=m")
3825         (float_truncate:SF
3826           (match_operand:DF 1 "register_operand" "f")))]
3827   "TARGET_80387
3828    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3829    && !TARGET_MIX_SSE_I387"
3831   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3832     return "fstp%z0\t%y0";
3833   else
3834     return "fst%z0\t%y0";
3836   [(set_attr "type" "fmov")
3837    (set_attr "mode" "SF")])
3839 (define_split
3840   [(set (match_operand:SF 0 "register_operand" "")
3841         (float_truncate:SF
3842          (match_operand:DF 1 "fp_register_operand" "")))
3843    (clobber (match_operand 2 "" ""))]
3844   "reload_completed"
3845   [(set (match_dup 2) (match_dup 1))
3846    (set (match_dup 0) (match_dup 2))]
3848   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3851 ;; Conversion from XFmode to SFmode.
3853 (define_expand "truncxfsf2"
3854   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3855                    (float_truncate:SF
3856                     (match_operand:XF 1 "register_operand" "")))
3857               (clobber (match_dup 2))])]
3858   "TARGET_80387"
3860   if (flag_unsafe_math_optimizations)
3861     {
3862       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3863       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3864       if (reg != operands[0])
3865         emit_move_insn (operands[0], reg);
3866       DONE;
3867     }
3868   else
3869     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3872 (define_insn "*truncxfsf2_mixed"
3873   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3874         (float_truncate:SF
3875          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3876    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3877   "TARGET_MIX_SSE_I387"
3879   gcc_assert (!which_alternative);
3880   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881     return "fstp%z0\t%y0";
3882   else
3883     return "fst%z0\t%y0";
3885   [(set_attr "type" "fmov,multi,multi,multi")
3886    (set_attr "unit" "*,i387,i387,i387")
3887    (set_attr "mode" "SF")])
3889 (define_insn "truncxfsf2_i387_noop"
3890   [(set (match_operand:SF 0 "register_operand" "=f")
3891         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3892   "TARGET_80387 && flag_unsafe_math_optimizations"
3894   return output_387_reg_move (insn, operands);
3896   [(set_attr "type" "fmov")
3897    (set_attr "mode" "SF")])
3899 (define_insn "*truncxfsf2_i387"
3900   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3901         (float_truncate:SF
3902          (match_operand:XF 1 "register_operand" "f,f,f")))
3903    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3904   "TARGET_80387"
3906   gcc_assert (!which_alternative);
3907   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3908     return "fstp%z0\t%y0";
3909    else
3910      return "fst%z0\t%y0";
3912   [(set_attr "type" "fmov,multi,multi")
3913    (set_attr "unit" "*,i387,i387")
3914    (set_attr "mode" "SF")])
3916 (define_insn "*truncxfsf2_i387_1"
3917   [(set (match_operand:SF 0 "memory_operand" "=m")
3918         (float_truncate:SF
3919          (match_operand:XF 1 "register_operand" "f")))]
3920   "TARGET_80387"
3922   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3923     return "fstp%z0\t%y0";
3924   else
3925     return "fst%z0\t%y0";
3927   [(set_attr "type" "fmov")
3928    (set_attr "mode" "SF")])
3930 (define_split
3931   [(set (match_operand:SF 0 "register_operand" "")
3932         (float_truncate:SF
3933          (match_operand:XF 1 "register_operand" "")))
3934    (clobber (match_operand:SF 2 "memory_operand" ""))]
3935   "TARGET_80387 && reload_completed"
3936   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3937    (set (match_dup 0) (match_dup 2))]
3938   "")
3940 (define_split
3941   [(set (match_operand:SF 0 "memory_operand" "")
3942         (float_truncate:SF
3943          (match_operand:XF 1 "register_operand" "")))
3944    (clobber (match_operand:SF 2 "memory_operand" ""))]
3945   "TARGET_80387"
3946   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3947   "")
3949 ;; Conversion from XFmode to DFmode.
3951 (define_expand "truncxfdf2"
3952   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3953                    (float_truncate:DF
3954                     (match_operand:XF 1 "register_operand" "")))
3955               (clobber (match_dup 2))])]
3956   "TARGET_80387"
3958   if (flag_unsafe_math_optimizations)
3959     {
3960       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3961       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3962       if (reg != operands[0])
3963         emit_move_insn (operands[0], reg);
3964       DONE;
3965     }
3966   else
3967     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3970 (define_insn "*truncxfdf2_mixed"
3971   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3972         (float_truncate:DF
3973          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3974    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3975   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3977   gcc_assert (!which_alternative);
3978   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979     return "fstp%z0\t%y0";
3980   else
3981     return "fst%z0\t%y0";
3983   [(set_attr "type" "fmov,multi,multi,multi")
3984    (set_attr "unit" "*,i387,i387,i387")
3985    (set_attr "mode" "DF")])
3987 (define_insn "truncxfdf2_i387_noop"
3988   [(set (match_operand:DF 0 "register_operand" "=f")
3989         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3990   "TARGET_80387 && flag_unsafe_math_optimizations"
3992   return output_387_reg_move (insn, operands);
3994   [(set_attr "type" "fmov")
3995    (set_attr "mode" "DF")])
3997 (define_insn "*truncxfdf2_i387"
3998   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3999         (float_truncate:DF
4000          (match_operand:XF 1 "register_operand" "f,f,f")))
4001    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4002   "TARGET_80387"
4004   gcc_assert (!which_alternative);
4005   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4006     return "fstp%z0\t%y0";
4007   else
4008     return "fst%z0\t%y0";
4010   [(set_attr "type" "fmov,multi,multi")
4011    (set_attr "unit" "*,i387,i387")
4012    (set_attr "mode" "DF")])
4014 (define_insn "*truncxfdf2_i387_1"
4015   [(set (match_operand:DF 0 "memory_operand" "=m")
4016         (float_truncate:DF
4017           (match_operand:XF 1 "register_operand" "f")))]
4018   "TARGET_80387"
4020   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4021     return "fstp%z0\t%y0";
4022   else
4023     return "fst%z0\t%y0";
4025   [(set_attr "type" "fmov")
4026    (set_attr "mode" "DF")])
4028 (define_split
4029   [(set (match_operand:DF 0 "register_operand" "")
4030         (float_truncate:DF
4031          (match_operand:XF 1 "register_operand" "")))
4032    (clobber (match_operand:DF 2 "memory_operand" ""))]
4033   "TARGET_80387 && reload_completed"
4034   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4035    (set (match_dup 0) (match_dup 2))]
4036   "")
4038 (define_split
4039   [(set (match_operand:DF 0 "memory_operand" "")
4040         (float_truncate:DF
4041          (match_operand:XF 1 "register_operand" "")))
4042    (clobber (match_operand:DF 2 "memory_operand" ""))]
4043   "TARGET_80387"
4044   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4045   "")
4047 ;; Signed conversion to DImode.
4049 (define_expand "fix_truncxfdi2"
4050   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4051                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4052               (clobber (reg:CC FLAGS_REG))])]
4053   "TARGET_80387"
4055   if (TARGET_FISTTP)
4056    {
4057      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4058      DONE;
4059    }
4062 (define_expand "fix_trunc<mode>di2"
4063   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4064                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4065               (clobber (reg:CC FLAGS_REG))])]
4066   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4068   if (TARGET_FISTTP
4069       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4070    {
4071      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4072      DONE;
4073    }
4074   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4075    {
4076      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4077      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4078      if (out != operands[0])
4079         emit_move_insn (operands[0], out);
4080      DONE;
4081    }
4084 ;; Signed conversion to SImode.
4086 (define_expand "fix_truncxfsi2"
4087   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4088                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4089               (clobber (reg:CC FLAGS_REG))])]
4090   "TARGET_80387"
4092   if (TARGET_FISTTP)
4093    {
4094      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4095      DONE;
4096    }
4099 (define_expand "fix_trunc<mode>si2"
4100   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4101                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4102               (clobber (reg:CC FLAGS_REG))])]
4103   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4105   if (TARGET_FISTTP
4106       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4107    {
4108      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4109      DONE;
4110    }
4111   if (SSE_FLOAT_MODE_P (<MODE>mode))
4112    {
4113      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4114      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4115      if (out != operands[0])
4116         emit_move_insn (operands[0], out);
4117      DONE;
4118    }
4121 ;; Signed conversion to HImode.
4123 (define_expand "fix_trunc<mode>hi2"
4124   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4125                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4126               (clobber (reg:CC FLAGS_REG))])]
4127   "TARGET_80387
4128    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4130   if (TARGET_FISTTP)
4131    {
4132      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4133      DONE;
4134    }
4137 ;; When SSE is available, it is always faster to use it!
4138 (define_insn "fix_truncsfdi_sse"
4139   [(set (match_operand:DI 0 "register_operand" "=r,r")
4140         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4141   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142   "cvttss2si{q}\t{%1, %0|%0, %1}"
4143   [(set_attr "type" "sseicvt")
4144    (set_attr "mode" "SF")
4145    (set_attr "athlon_decode" "double,vector")])
4147 (define_insn "fix_truncdfdi_sse"
4148   [(set (match_operand:DI 0 "register_operand" "=r,r")
4149         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4150   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4151   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4152   [(set_attr "type" "sseicvt")
4153    (set_attr "mode" "DF")
4154    (set_attr "athlon_decode" "double,vector")])
4156 (define_insn "fix_truncsfsi_sse"
4157   [(set (match_operand:SI 0 "register_operand" "=r,r")
4158         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4159   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4160   "cvttss2si\t{%1, %0|%0, %1}"
4161   [(set_attr "type" "sseicvt")
4162    (set_attr "mode" "DF")
4163    (set_attr "athlon_decode" "double,vector")])
4165 (define_insn "fix_truncdfsi_sse"
4166   [(set (match_operand:SI 0 "register_operand" "=r,r")
4167         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4168   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4169   "cvttsd2si\t{%1, %0|%0, %1}"
4170   [(set_attr "type" "sseicvt")
4171    (set_attr "mode" "DF")
4172    (set_attr "athlon_decode" "double,vector")])
4174 ;; Avoid vector decoded forms of the instruction.
4175 (define_peephole2
4176   [(match_scratch:DF 2 "Y")
4177    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4178         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4179   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4180   [(set (match_dup 2) (match_dup 1))
4181    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4182   "")
4184 (define_peephole2
4185   [(match_scratch:SF 2 "x")
4186    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4187         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4188   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4189   [(set (match_dup 2) (match_dup 1))
4190    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4191   "")
4193 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4194   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4195         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4196   "TARGET_FISTTP
4197    && FLOAT_MODE_P (GET_MODE (operands[1]))
4198    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4199          && (TARGET_64BIT || <MODE>mode != DImode))
4200         && TARGET_SSE_MATH)
4201    && !(reload_completed || reload_in_progress)"
4202   "#"
4203   "&& 1"
4204   [(const_int 0)]
4206   if (memory_operand (operands[0], VOIDmode))
4207     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4208   else
4209     {
4210       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4211       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4212                                                             operands[1],
4213                                                             operands[2]));
4214     }
4215   DONE;
4217   [(set_attr "type" "fisttp")
4218    (set_attr "mode" "<MODE>")])
4220 (define_insn "fix_trunc<mode>_i387_fisttp"
4221   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4222         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4223    (clobber (match_scratch:XF 2 "=&1f"))]
4224   "TARGET_FISTTP
4225    && FLOAT_MODE_P (GET_MODE (operands[1]))
4226    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4227          && (TARGET_64BIT || <MODE>mode != DImode))
4228         && TARGET_SSE_MATH)"
4229   "* return output_fix_trunc (insn, operands, 1);"
4230   [(set_attr "type" "fisttp")
4231    (set_attr "mode" "<MODE>")])
4233 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4234   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4235         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4236    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4237    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4238   "TARGET_FISTTP
4239    && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4241         && (TARGET_64BIT || <MODE>mode != DImode))
4242         && TARGET_SSE_MATH)"
4243   "#"
4244   [(set_attr "type" "fisttp")
4245    (set_attr "mode" "<MODE>")])
4247 (define_split
4248   [(set (match_operand:X87MODEI 0 "register_operand" "")
4249         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4250    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4251    (clobber (match_scratch 3 ""))]
4252   "reload_completed"
4253   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4254               (clobber (match_dup 3))])
4255    (set (match_dup 0) (match_dup 2))]
4256   "")
4258 (define_split
4259   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4260         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4261    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4262    (clobber (match_scratch 3 ""))]
4263   "reload_completed"
4264   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4265               (clobber (match_dup 3))])]
4266   "")
4268 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4269 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4270 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4271 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4272 ;; function in i386.c.
4273 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4274   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4275         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4276    (clobber (reg:CC FLAGS_REG))]
4277   "TARGET_80387 && !TARGET_FISTTP
4278    && FLOAT_MODE_P (GET_MODE (operands[1]))
4279    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4280          && (TARGET_64BIT || <MODE>mode != DImode))
4281    && !(reload_completed || reload_in_progress)"
4282   "#"
4283   "&& 1"
4284   [(const_int 0)]
4286   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4288   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4289   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4290   if (memory_operand (operands[0], VOIDmode))
4291     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4292                                          operands[2], operands[3]));
4293   else
4294     {
4295       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4296       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4297                                                      operands[2], operands[3],
4298                                                      operands[4]));
4299     }
4300   DONE;
4302   [(set_attr "type" "fistp")
4303    (set_attr "i387_cw" "trunc")
4304    (set_attr "mode" "<MODE>")])
4306 (define_insn "fix_truncdi_i387"
4307   [(set (match_operand:DI 0 "memory_operand" "=m")
4308         (fix:DI (match_operand 1 "register_operand" "f")))
4309    (use (match_operand:HI 2 "memory_operand" "m"))
4310    (use (match_operand:HI 3 "memory_operand" "m"))
4311    (clobber (match_scratch:XF 4 "=&1f"))]
4312   "TARGET_80387 && !TARGET_FISTTP
4313    && FLOAT_MODE_P (GET_MODE (operands[1]))
4314    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4315   "* return output_fix_trunc (insn, operands, 0);"
4316   [(set_attr "type" "fistp")
4317    (set_attr "i387_cw" "trunc")
4318    (set_attr "mode" "DI")])
4320 (define_insn "fix_truncdi_i387_with_temp"
4321   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4322         (fix:DI (match_operand 1 "register_operand" "f,f")))
4323    (use (match_operand:HI 2 "memory_operand" "m,m"))
4324    (use (match_operand:HI 3 "memory_operand" "m,m"))
4325    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4326    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4327   "TARGET_80387 && !TARGET_FISTTP
4328    && FLOAT_MODE_P (GET_MODE (operands[1]))
4329    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4330   "#"
4331   [(set_attr "type" "fistp")
4332    (set_attr "i387_cw" "trunc")
4333    (set_attr "mode" "DI")])
4335 (define_split 
4336   [(set (match_operand:DI 0 "register_operand" "")
4337         (fix:DI (match_operand 1 "register_operand" "")))
4338    (use (match_operand:HI 2 "memory_operand" ""))
4339    (use (match_operand:HI 3 "memory_operand" ""))
4340    (clobber (match_operand:DI 4 "memory_operand" ""))
4341    (clobber (match_scratch 5 ""))]
4342   "reload_completed"
4343   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4344               (use (match_dup 2))
4345               (use (match_dup 3))
4346               (clobber (match_dup 5))])
4347    (set (match_dup 0) (match_dup 4))]
4348   "")
4350 (define_split 
4351   [(set (match_operand:DI 0 "memory_operand" "")
4352         (fix:DI (match_operand 1 "register_operand" "")))
4353    (use (match_operand:HI 2 "memory_operand" ""))
4354    (use (match_operand:HI 3 "memory_operand" ""))
4355    (clobber (match_operand:DI 4 "memory_operand" ""))
4356    (clobber (match_scratch 5 ""))]
4357   "reload_completed"
4358   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4359               (use (match_dup 2))
4360               (use (match_dup 3))
4361               (clobber (match_dup 5))])]
4362   "")
4364 (define_insn "fix_trunc<mode>_i387"
4365   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4366         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4367    (use (match_operand:HI 2 "memory_operand" "m"))
4368    (use (match_operand:HI 3 "memory_operand" "m"))]
4369   "TARGET_80387 && !TARGET_FISTTP
4370    && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4372   "* return output_fix_trunc (insn, operands, 0);"
4373   [(set_attr "type" "fistp")
4374    (set_attr "i387_cw" "trunc")
4375    (set_attr "mode" "<MODE>")])
4377 (define_insn "fix_trunc<mode>_i387_with_temp"
4378   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4379         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4380    (use (match_operand:HI 2 "memory_operand" "m,m"))
4381    (use (match_operand:HI 3 "memory_operand" "m,m"))
4382    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4383   "TARGET_80387 && !TARGET_FISTTP
4384    && FLOAT_MODE_P (GET_MODE (operands[1]))
4385    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4386   "#"
4387   [(set_attr "type" "fistp")
4388    (set_attr "i387_cw" "trunc")
4389    (set_attr "mode" "<MODE>")])
4391 (define_split 
4392   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4393         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4394    (use (match_operand:HI 2 "memory_operand" ""))
4395    (use (match_operand:HI 3 "memory_operand" ""))
4396    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4397   "reload_completed"
4398   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4399               (use (match_dup 2))
4400               (use (match_dup 3))])
4401    (set (match_dup 0) (match_dup 4))]
4402   "")
4404 (define_split 
4405   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4406         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4407    (use (match_operand:HI 2 "memory_operand" ""))
4408    (use (match_operand:HI 3 "memory_operand" ""))
4409    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4410   "reload_completed"
4411   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4412               (use (match_dup 2))
4413               (use (match_dup 3))])]
4414   "")
4416 (define_insn "x86_fnstcw_1"
4417   [(set (match_operand:HI 0 "memory_operand" "=m")
4418         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4419   "TARGET_80387"
4420   "fnstcw\t%0"
4421   [(set_attr "length" "2")
4422    (set_attr "mode" "HI")
4423    (set_attr "unit" "i387")])
4425 (define_insn "x86_fldcw_1"
4426   [(set (reg:HI FPSR_REG)
4427         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428   "TARGET_80387"
4429   "fldcw\t%0"
4430   [(set_attr "length" "2")
4431    (set_attr "mode" "HI")
4432    (set_attr "unit" "i387")
4433    (set_attr "athlon_decode" "vector")])
4435 ;; Conversion between fixed point and floating point.
4437 ;; Even though we only accept memory inputs, the backend _really_
4438 ;; wants to be able to do this between registers.
4440 (define_expand "floathisf2"
4441   [(set (match_operand:SF 0 "register_operand" "")
4442         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4443   "TARGET_80387 || TARGET_SSE_MATH"
4445   if (TARGET_SSE_MATH)
4446     {
4447       emit_insn (gen_floatsisf2 (operands[0],
4448                                  convert_to_mode (SImode, operands[1], 0)));
4449       DONE;
4450     }
4453 (define_insn "*floathisf2_i387"
4454   [(set (match_operand:SF 0 "register_operand" "=f,f")
4455         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4456   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4457   "@
4458    fild%z1\t%1
4459    #"
4460   [(set_attr "type" "fmov,multi")
4461    (set_attr "mode" "SF")
4462    (set_attr "unit" "*,i387")
4463    (set_attr "fp_int_src" "true")])
4465 (define_expand "floatsisf2"
4466   [(set (match_operand:SF 0 "register_operand" "")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4468   "TARGET_80387 || TARGET_SSE_MATH"
4469   "")
4471 (define_insn "*floatsisf2_mixed"
4472   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4473         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4474   "TARGET_MIX_SSE_I387"
4475   "@
4476    fild%z1\t%1
4477    #
4478    cvtsi2ss\t{%1, %0|%0, %1}
4479    cvtsi2ss\t{%1, %0|%0, %1}"
4480   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4481    (set_attr "mode" "SF")
4482    (set_attr "unit" "*,i387,*,*")
4483    (set_attr "athlon_decode" "*,*,vector,double")
4484    (set_attr "fp_int_src" "true")])
4486 (define_insn "*floatsisf2_sse"
4487   [(set (match_operand:SF 0 "register_operand" "=x,x")
4488         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4489   "TARGET_SSE_MATH"
4490   "cvtsi2ss\t{%1, %0|%0, %1}"
4491   [(set_attr "type" "sseicvt")
4492    (set_attr "mode" "SF")
4493    (set_attr "athlon_decode" "vector,double")
4494    (set_attr "fp_int_src" "true")])
4496 (define_insn "*floatsisf2_i387"
4497   [(set (match_operand:SF 0 "register_operand" "=f,f")
4498         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4499   "TARGET_80387"
4500   "@
4501    fild%z1\t%1
4502    #"
4503   [(set_attr "type" "fmov,multi")
4504    (set_attr "mode" "SF")
4505    (set_attr "unit" "*,i387")
4506    (set_attr "fp_int_src" "true")])
4508 (define_expand "floatdisf2"
4509   [(set (match_operand:SF 0 "register_operand" "")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4511   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4512   "")
4514 (define_insn "*floatdisf2_mixed"
4515   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4516         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4517   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4518   "@
4519    fild%z1\t%1
4520    #
4521    cvtsi2ss{q}\t{%1, %0|%0, %1}
4522    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4523   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4524    (set_attr "mode" "SF")
4525    (set_attr "unit" "*,i387,*,*")
4526    (set_attr "athlon_decode" "*,*,vector,double")
4527    (set_attr "fp_int_src" "true")])
4529 (define_insn "*floatdisf2_sse"
4530   [(set (match_operand:SF 0 "register_operand" "=x,x")
4531         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4532   "TARGET_64BIT && TARGET_SSE_MATH"
4533   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4534   [(set_attr "type" "sseicvt")
4535    (set_attr "mode" "SF")
4536    (set_attr "athlon_decode" "vector,double")
4537    (set_attr "fp_int_src" "true")])
4539 (define_insn "*floatdisf2_i387"
4540   [(set (match_operand:SF 0 "register_operand" "=f,f")
4541         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4542   "TARGET_80387"
4543   "@
4544    fild%z1\t%1
4545    #"
4546   [(set_attr "type" "fmov,multi")
4547    (set_attr "mode" "SF")
4548    (set_attr "unit" "*,i387")
4549    (set_attr "fp_int_src" "true")])
4551 (define_expand "floathidf2"
4552   [(set (match_operand:DF 0 "register_operand" "")
4553         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4554   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4556   if (TARGET_SSE2 && TARGET_SSE_MATH)
4557     {
4558       emit_insn (gen_floatsidf2 (operands[0],
4559                                  convert_to_mode (SImode, operands[1], 0)));
4560       DONE;
4561     }
4564 (define_insn "*floathidf2_i387"
4565   [(set (match_operand:DF 0 "register_operand" "=f,f")
4566         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4567   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4568   "@
4569    fild%z1\t%1
4570    #"
4571   [(set_attr "type" "fmov,multi")
4572    (set_attr "mode" "DF")
4573    (set_attr "unit" "*,i387")
4574    (set_attr "fp_int_src" "true")])
4576 (define_expand "floatsidf2"
4577   [(set (match_operand:DF 0 "register_operand" "")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4579   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4580   "")
4582 (define_insn "*floatsidf2_mixed"
4583   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4584         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4585   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4586   "@
4587    fild%z1\t%1
4588    #
4589    cvtsi2sd\t{%1, %0|%0, %1}
4590    cvtsi2sd\t{%1, %0|%0, %1}"
4591   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4592    (set_attr "mode" "DF")
4593    (set_attr "unit" "*,i387,*,*")
4594    (set_attr "athlon_decode" "*,*,double,direct")
4595    (set_attr "fp_int_src" "true")])
4597 (define_insn "*floatsidf2_sse"
4598   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4599         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4600   "TARGET_SSE2 && TARGET_SSE_MATH"
4601   "cvtsi2sd\t{%1, %0|%0, %1}"
4602   [(set_attr "type" "sseicvt")
4603    (set_attr "mode" "DF")
4604    (set_attr "athlon_decode" "double,direct")
4605    (set_attr "fp_int_src" "true")])
4607 (define_insn "*floatsidf2_i387"
4608   [(set (match_operand:DF 0 "register_operand" "=f,f")
4609         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4610   "TARGET_80387"
4611   "@
4612    fild%z1\t%1
4613    #"
4614   [(set_attr "type" "fmov,multi")
4615    (set_attr "mode" "DF")
4616    (set_attr "unit" "*,i387")
4617    (set_attr "fp_int_src" "true")])
4619 (define_expand "floatdidf2"
4620   [(set (match_operand:DF 0 "register_operand" "")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4622   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4623   "")
4625 (define_insn "*floatdidf2_mixed"
4626   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4627         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4628   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4629   "@
4630    fild%z1\t%1
4631    #
4632    cvtsi2sd{q}\t{%1, %0|%0, %1}
4633    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4634   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4635    (set_attr "mode" "DF")
4636    (set_attr "unit" "*,i387,*,*")
4637    (set_attr "athlon_decode" "*,*,double,direct")
4638    (set_attr "fp_int_src" "true")])
4640 (define_insn "*floatdidf2_sse"
4641   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4642         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4643   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4644   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4645   [(set_attr "type" "sseicvt")
4646    (set_attr "mode" "DF")
4647    (set_attr "athlon_decode" "double,direct")
4648    (set_attr "fp_int_src" "true")])
4650 (define_insn "*floatdidf2_i387"
4651   [(set (match_operand:DF 0 "register_operand" "=f,f")
4652         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4653   "TARGET_80387"
4654   "@
4655    fild%z1\t%1
4656    #"
4657   [(set_attr "type" "fmov,multi")
4658    (set_attr "mode" "DF")
4659    (set_attr "unit" "*,i387")
4660    (set_attr "fp_int_src" "true")])
4662 (define_insn "floathixf2"
4663   [(set (match_operand:XF 0 "register_operand" "=f,f")
4664         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "XF")
4671    (set_attr "unit" "*,i387")
4672    (set_attr "fp_int_src" "true")])
4674 (define_insn "floatsixf2"
4675   [(set (match_operand:XF 0 "register_operand" "=f,f")
4676         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4677   "TARGET_80387"
4678   "@
4679    fild%z1\t%1
4680    #"
4681   [(set_attr "type" "fmov,multi")
4682    (set_attr "mode" "XF")
4683    (set_attr "unit" "*,i387")
4684    (set_attr "fp_int_src" "true")])
4686 (define_insn "floatdixf2"
4687   [(set (match_operand:XF 0 "register_operand" "=f,f")
4688         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4689   "TARGET_80387"
4690   "@
4691    fild%z1\t%1
4692    #"
4693   [(set_attr "type" "fmov,multi")
4694    (set_attr "mode" "XF")
4695    (set_attr "unit" "*,i387")
4696    (set_attr "fp_int_src" "true")])
4698 ;; %%% Kill these when reload knows how to do it.
4699 (define_split
4700   [(set (match_operand 0 "fp_register_operand" "")
4701         (float (match_operand 1 "register_operand" "")))]
4702   "reload_completed
4703    && TARGET_80387
4704    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4705   [(const_int 0)]
4707   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4708   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4709   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4710   ix86_free_from_memory (GET_MODE (operands[1]));
4711   DONE;
4714 (define_expand "floatunssisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:SI 1 "register_operand" ""))]
4717   "!TARGET_64BIT && TARGET_SSE_MATH"
4718   "x86_emit_floatuns (operands); DONE;")
4720 (define_expand "floatunsdisf2"
4721   [(use (match_operand:SF 0 "register_operand" ""))
4722    (use (match_operand:DI 1 "register_operand" ""))]
4723   "TARGET_64BIT && TARGET_SSE_MATH"
4724   "x86_emit_floatuns (operands); DONE;")
4726 (define_expand "floatunsdidf2"
4727   [(use (match_operand:DF 0 "register_operand" ""))
4728    (use (match_operand:DI 1 "register_operand" ""))]
4729   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4730   "x86_emit_floatuns (operands); DONE;")
4732 ;; SSE extract/set expanders
4735 ;; Add instructions
4737 ;; %%% splits for addditi3
4739 (define_expand "addti3"
4740   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4741         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4742                  (match_operand:TI 2 "x86_64_general_operand" "")))
4743    (clobber (reg:CC FLAGS_REG))]
4744   "TARGET_64BIT"
4745   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4747 (define_insn "*addti3_1"
4748   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4749         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4750                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4753   "#")
4755 (define_split
4756   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4757         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4758                  (match_operand:TI 2 "general_operand" "")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "TARGET_64BIT && reload_completed"
4761   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4762                                           UNSPEC_ADD_CARRY))
4763               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4764    (parallel [(set (match_dup 3)
4765                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4766                                      (match_dup 4))
4767                             (match_dup 5)))
4768               (clobber (reg:CC FLAGS_REG))])]
4769   "split_ti (operands+0, 1, operands+0, operands+3);
4770    split_ti (operands+1, 1, operands+1, operands+4);
4771    split_ti (operands+2, 1, operands+2, operands+5);")
4773 ;; %%% splits for addsidi3
4774 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4775 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4776 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4778 (define_expand "adddi3"
4779   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4780         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4781                  (match_operand:DI 2 "x86_64_general_operand" "")))
4782    (clobber (reg:CC FLAGS_REG))]
4783   ""
4784   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4786 (define_insn "*adddi3_1"
4787   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4788         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4789                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4790    (clobber (reg:CC FLAGS_REG))]
4791   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792   "#")
4794 (define_split
4795   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4797                  (match_operand:DI 2 "general_operand" "")))
4798    (clobber (reg:CC FLAGS_REG))]
4799   "!TARGET_64BIT && reload_completed"
4800   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4801                                           UNSPEC_ADD_CARRY))
4802               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4803    (parallel [(set (match_dup 3)
4804                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4805                                      (match_dup 4))
4806                             (match_dup 5)))
4807               (clobber (reg:CC FLAGS_REG))])]
4808   "split_di (operands+0, 1, operands+0, operands+3);
4809    split_di (operands+1, 1, operands+1, operands+4);
4810    split_di (operands+2, 1, operands+2, operands+5);")
4812 (define_insn "adddi3_carry_rex64"
4813   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4814           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4815                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4816                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4817    (clobber (reg:CC FLAGS_REG))]
4818   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4819   "adc{q}\t{%2, %0|%0, %2}"
4820   [(set_attr "type" "alu")
4821    (set_attr "pent_pair" "pu")
4822    (set_attr "mode" "DI")])
4824 (define_insn "*adddi3_cc_rex64"
4825   [(set (reg:CC FLAGS_REG)
4826         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4827                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4828                    UNSPEC_ADD_CARRY))
4829    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4830         (plus:DI (match_dup 1) (match_dup 2)))]
4831   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4832   "add{q}\t{%2, %0|%0, %2}"
4833   [(set_attr "type" "alu")
4834    (set_attr "mode" "DI")])
4836 (define_insn "addqi3_carry"
4837   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4838           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4839                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4840                    (match_operand:QI 2 "general_operand" "qi,qm")))
4841    (clobber (reg:CC FLAGS_REG))]
4842   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4843   "adc{b}\t{%2, %0|%0, %2}"
4844   [(set_attr "type" "alu")
4845    (set_attr "pent_pair" "pu")
4846    (set_attr "mode" "QI")])
4848 (define_insn "addhi3_carry"
4849   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4850           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4851                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4852                    (match_operand:HI 2 "general_operand" "ri,rm")))
4853    (clobber (reg:CC FLAGS_REG))]
4854   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4855   "adc{w}\t{%2, %0|%0, %2}"
4856   [(set_attr "type" "alu")
4857    (set_attr "pent_pair" "pu")
4858    (set_attr "mode" "HI")])
4860 (define_insn "addsi3_carry"
4861   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4862           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4863                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4864                    (match_operand:SI 2 "general_operand" "ri,rm")))
4865    (clobber (reg:CC FLAGS_REG))]
4866   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4867   "adc{l}\t{%2, %0|%0, %2}"
4868   [(set_attr "type" "alu")
4869    (set_attr "pent_pair" "pu")
4870    (set_attr "mode" "SI")])
4872 (define_insn "*addsi3_carry_zext"
4873   [(set (match_operand:DI 0 "register_operand" "=r")
4874           (zero_extend:DI 
4875             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4876                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4877                      (match_operand:SI 2 "general_operand" "rim"))))
4878    (clobber (reg:CC FLAGS_REG))]
4879   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4880   "adc{l}\t{%2, %k0|%k0, %2}"
4881   [(set_attr "type" "alu")
4882    (set_attr "pent_pair" "pu")
4883    (set_attr "mode" "SI")])
4885 (define_insn "*addsi3_cc"
4886   [(set (reg:CC FLAGS_REG)
4887         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4888                     (match_operand:SI 2 "general_operand" "ri,rm")]
4889                    UNSPEC_ADD_CARRY))
4890    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4891         (plus:SI (match_dup 1) (match_dup 2)))]
4892   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4893   "add{l}\t{%2, %0|%0, %2}"
4894   [(set_attr "type" "alu")
4895    (set_attr "mode" "SI")])
4897 (define_insn "addqi3_cc"
4898   [(set (reg:CC FLAGS_REG)
4899         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4900                     (match_operand:QI 2 "general_operand" "qi,qm")]
4901                    UNSPEC_ADD_CARRY))
4902    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4903         (plus:QI (match_dup 1) (match_dup 2)))]
4904   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4905   "add{b}\t{%2, %0|%0, %2}"
4906   [(set_attr "type" "alu")
4907    (set_attr "mode" "QI")])
4909 (define_expand "addsi3"
4910   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4911                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4912                             (match_operand:SI 2 "general_operand" "")))
4913               (clobber (reg:CC FLAGS_REG))])]
4914   ""
4915   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4917 (define_insn "*lea_1"
4918   [(set (match_operand:SI 0 "register_operand" "=r")
4919         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4920   "!TARGET_64BIT"
4921   "lea{l}\t{%a1, %0|%0, %a1}"
4922   [(set_attr "type" "lea")
4923    (set_attr "mode" "SI")])
4925 (define_insn "*lea_1_rex64"
4926   [(set (match_operand:SI 0 "register_operand" "=r")
4927         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4928   "TARGET_64BIT"
4929   "lea{l}\t{%a1, %0|%0, %a1}"
4930   [(set_attr "type" "lea")
4931    (set_attr "mode" "SI")])
4933 (define_insn "*lea_1_zext"
4934   [(set (match_operand:DI 0 "register_operand" "=r")
4935         (zero_extend:DI
4936          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4937   "TARGET_64BIT"
4938   "lea{l}\t{%a1, %k0|%k0, %a1}"
4939   [(set_attr "type" "lea")
4940    (set_attr "mode" "SI")])
4942 (define_insn "*lea_2_rex64"
4943   [(set (match_operand:DI 0 "register_operand" "=r")
4944         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4945   "TARGET_64BIT"
4946   "lea{q}\t{%a1, %0|%0, %a1}"
4947   [(set_attr "type" "lea")
4948    (set_attr "mode" "DI")])
4950 ;; The lea patterns for non-Pmodes needs to be matched by several
4951 ;; insns converted to real lea by splitters.
4953 (define_insn_and_split "*lea_general_1"
4954   [(set (match_operand 0 "register_operand" "=r")
4955         (plus (plus (match_operand 1 "index_register_operand" "l")
4956                     (match_operand 2 "register_operand" "r"))
4957               (match_operand 3 "immediate_operand" "i")))]
4958   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4959     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4960    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4961    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4962    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4963    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4964        || GET_MODE (operands[3]) == VOIDmode)"
4965   "#"
4966   "&& reload_completed"
4967   [(const_int 0)]
4969   rtx pat;
4970   operands[0] = gen_lowpart (SImode, operands[0]);
4971   operands[1] = gen_lowpart (Pmode, operands[1]);
4972   operands[2] = gen_lowpart (Pmode, operands[2]);
4973   operands[3] = gen_lowpart (Pmode, operands[3]);
4974   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4975                       operands[3]);
4976   if (Pmode != SImode)
4977     pat = gen_rtx_SUBREG (SImode, pat, 0);
4978   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4979   DONE;
4981   [(set_attr "type" "lea")
4982    (set_attr "mode" "SI")])
4984 (define_insn_and_split "*lea_general_1_zext"
4985   [(set (match_operand:DI 0 "register_operand" "=r")
4986         (zero_extend:DI
4987           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4988                             (match_operand:SI 2 "register_operand" "r"))
4989                    (match_operand:SI 3 "immediate_operand" "i"))))]
4990   "TARGET_64BIT"
4991   "#"
4992   "&& reload_completed"
4993   [(set (match_dup 0)
4994         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4995                                                      (match_dup 2))
4996                                             (match_dup 3)) 0)))]
4998   operands[1] = gen_lowpart (Pmode, operands[1]);
4999   operands[2] = gen_lowpart (Pmode, operands[2]);
5000   operands[3] = gen_lowpart (Pmode, operands[3]);
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "SI")])
5005 (define_insn_and_split "*lea_general_2"
5006   [(set (match_operand 0 "register_operand" "=r")
5007         (plus (mult (match_operand 1 "index_register_operand" "l")
5008                     (match_operand 2 "const248_operand" "i"))
5009               (match_operand 3 "nonmemory_operand" "ri")))]
5010   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5011     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5012    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5013    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5014    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5015        || GET_MODE (operands[3]) == VOIDmode)"
5016   "#"
5017   "&& reload_completed"
5018   [(const_int 0)]
5020   rtx pat;
5021   operands[0] = gen_lowpart (SImode, operands[0]);
5022   operands[1] = gen_lowpart (Pmode, operands[1]);
5023   operands[3] = gen_lowpart (Pmode, operands[3]);
5024   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5025                       operands[3]);
5026   if (Pmode != SImode)
5027     pat = gen_rtx_SUBREG (SImode, pat, 0);
5028   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5029   DONE;
5031   [(set_attr "type" "lea")
5032    (set_attr "mode" "SI")])
5034 (define_insn_and_split "*lea_general_2_zext"
5035   [(set (match_operand:DI 0 "register_operand" "=r")
5036         (zero_extend:DI
5037           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5038                             (match_operand:SI 2 "const248_operand" "n"))
5039                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5040   "TARGET_64BIT"
5041   "#"
5042   "&& reload_completed"
5043   [(set (match_dup 0)
5044         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5045                                                      (match_dup 2))
5046                                             (match_dup 3)) 0)))]
5048   operands[1] = gen_lowpart (Pmode, operands[1]);
5049   operands[3] = gen_lowpart (Pmode, operands[3]);
5051   [(set_attr "type" "lea")
5052    (set_attr "mode" "SI")])
5054 (define_insn_and_split "*lea_general_3"
5055   [(set (match_operand 0 "register_operand" "=r")
5056         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5057                           (match_operand 2 "const248_operand" "i"))
5058                     (match_operand 3 "register_operand" "r"))
5059               (match_operand 4 "immediate_operand" "i")))]
5060   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5061     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5062    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5063    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5064    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5065   "#"
5066   "&& reload_completed"
5067   [(const_int 0)]
5069   rtx pat;
5070   operands[0] = gen_lowpart (SImode, operands[0]);
5071   operands[1] = gen_lowpart (Pmode, operands[1]);
5072   operands[3] = gen_lowpart (Pmode, operands[3]);
5073   operands[4] = gen_lowpart (Pmode, operands[4]);
5074   pat = gen_rtx_PLUS (Pmode,
5075                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5076                                                          operands[2]),
5077                                     operands[3]),
5078                       operands[4]);
5079   if (Pmode != SImode)
5080     pat = gen_rtx_SUBREG (SImode, pat, 0);
5081   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5082   DONE;
5084   [(set_attr "type" "lea")
5085    (set_attr "mode" "SI")])
5087 (define_insn_and_split "*lea_general_3_zext"
5088   [(set (match_operand:DI 0 "register_operand" "=r")
5089         (zero_extend:DI
5090           (plus:SI (plus:SI (mult:SI
5091                               (match_operand:SI 1 "index_register_operand" "l")
5092                               (match_operand:SI 2 "const248_operand" "n"))
5093                             (match_operand:SI 3 "register_operand" "r"))
5094                    (match_operand:SI 4 "immediate_operand" "i"))))]
5095   "TARGET_64BIT"
5096   "#"
5097   "&& reload_completed"
5098   [(set (match_dup 0)
5099         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5100                                                               (match_dup 2))
5101                                                      (match_dup 3))
5102                                             (match_dup 4)) 0)))]
5104   operands[1] = gen_lowpart (Pmode, operands[1]);
5105   operands[3] = gen_lowpart (Pmode, operands[3]);
5106   operands[4] = gen_lowpart (Pmode, operands[4]);
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "SI")])
5111 (define_insn "*adddi_1_rex64"
5112   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5113         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5114                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5115    (clobber (reg:CC FLAGS_REG))]
5116   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5118   switch (get_attr_type (insn))
5119     {
5120     case TYPE_LEA:
5121       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5122       return "lea{q}\t{%a2, %0|%0, %a2}";
5124     case TYPE_INCDEC:
5125       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5126       if (operands[2] == const1_rtx)
5127         return "inc{q}\t%0";
5128       else
5129         {
5130           gcc_assert (operands[2] == constm1_rtx);
5131           return "dec{q}\t%0";
5132         }
5134     default:
5135       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5137       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5138          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5139       if (GET_CODE (operands[2]) == CONST_INT
5140           /* Avoid overflows.  */
5141           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5142           && (INTVAL (operands[2]) == 128
5143               || (INTVAL (operands[2]) < 0
5144                   && INTVAL (operands[2]) != -128)))
5145         {
5146           operands[2] = GEN_INT (-INTVAL (operands[2]));
5147           return "sub{q}\t{%2, %0|%0, %2}";
5148         }
5149       return "add{q}\t{%2, %0|%0, %2}";
5150     }
5152   [(set (attr "type")
5153      (cond [(eq_attr "alternative" "2")
5154               (const_string "lea")
5155             ; Current assemblers are broken and do not allow @GOTOFF in
5156             ; ought but a memory context.
5157             (match_operand:DI 2 "pic_symbolic_operand" "")
5158               (const_string "lea")
5159             (match_operand:DI 2 "incdec_operand" "")
5160               (const_string "incdec")
5161            ]
5162            (const_string "alu")))
5163    (set_attr "mode" "DI")])
5165 ;; Convert lea to the lea pattern to avoid flags dependency.
5166 (define_split
5167   [(set (match_operand:DI 0 "register_operand" "")
5168         (plus:DI (match_operand:DI 1 "register_operand" "")
5169                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5170    (clobber (reg:CC FLAGS_REG))]
5171   "TARGET_64BIT && reload_completed
5172    && true_regnum (operands[0]) != true_regnum (operands[1])"
5173   [(set (match_dup 0)
5174         (plus:DI (match_dup 1)
5175                  (match_dup 2)))]
5176   "")
5178 (define_insn "*adddi_2_rex64"
5179   [(set (reg FLAGS_REG)
5180         (compare
5181           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5182                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5183           (const_int 0)))                       
5184    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5185         (plus:DI (match_dup 1) (match_dup 2)))]
5186   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5187    && ix86_binary_operator_ok (PLUS, DImode, operands)
5188    /* Current assemblers are broken and do not allow @GOTOFF in
5189       ought but a memory context.  */
5190    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5192   switch (get_attr_type (insn))
5193     {
5194     case TYPE_INCDEC:
5195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5196       if (operands[2] == const1_rtx)
5197         return "inc{q}\t%0";
5198       else
5199         {
5200           gcc_assert (operands[2] == constm1_rtx);
5201           return "dec{q}\t%0";
5202         }
5204     default:
5205       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5206       /* ???? We ought to handle there the 32bit case too
5207          - do we need new constraint?  */
5208       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5209          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5210       if (GET_CODE (operands[2]) == CONST_INT
5211           /* Avoid overflows.  */
5212           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5213           && (INTVAL (operands[2]) == 128
5214               || (INTVAL (operands[2]) < 0
5215                   && INTVAL (operands[2]) != -128)))
5216         {
5217           operands[2] = GEN_INT (-INTVAL (operands[2]));
5218           return "sub{q}\t{%2, %0|%0, %2}";
5219         }
5220       return "add{q}\t{%2, %0|%0, %2}";
5221     }
5223   [(set (attr "type")
5224      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5225         (const_string "incdec")
5226         (const_string "alu")))
5227    (set_attr "mode" "DI")])
5229 (define_insn "*adddi_3_rex64"
5230   [(set (reg FLAGS_REG)
5231         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5232                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5233    (clobber (match_scratch:DI 0 "=r"))]
5234   "TARGET_64BIT
5235    && ix86_match_ccmode (insn, CCZmode)
5236    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5237    /* Current assemblers are broken and do not allow @GOTOFF in
5238       ought but a memory context.  */
5239    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5241   switch (get_attr_type (insn))
5242     {
5243     case TYPE_INCDEC:
5244       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5245       if (operands[2] == const1_rtx)
5246         return "inc{q}\t%0";
5247       else
5248         {
5249           gcc_assert (operands[2] == constm1_rtx);
5250           return "dec{q}\t%0";
5251         }
5253     default:
5254       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5255       /* ???? We ought to handle there the 32bit case too
5256          - do we need new constraint?  */
5257       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5258          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5259       if (GET_CODE (operands[2]) == CONST_INT
5260           /* Avoid overflows.  */
5261           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5262           && (INTVAL (operands[2]) == 128
5263               || (INTVAL (operands[2]) < 0
5264                   && INTVAL (operands[2]) != -128)))
5265         {
5266           operands[2] = GEN_INT (-INTVAL (operands[2]));
5267           return "sub{q}\t{%2, %0|%0, %2}";
5268         }
5269       return "add{q}\t{%2, %0|%0, %2}";
5270     }
5272   [(set (attr "type")
5273      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5274         (const_string "incdec")
5275         (const_string "alu")))
5276    (set_attr "mode" "DI")])
5278 ; For comparisons against 1, -1 and 128, we may generate better code
5279 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5280 ; is matched then.  We can't accept general immediate, because for
5281 ; case of overflows,  the result is messed up.
5282 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5283 ; when negated.
5284 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5285 ; only for comparisons not depending on it.
5286 (define_insn "*adddi_4_rex64"
5287   [(set (reg FLAGS_REG)
5288         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5289                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5290    (clobber (match_scratch:DI 0 "=rm"))]
5291   "TARGET_64BIT
5292    &&  ix86_match_ccmode (insn, CCGCmode)"
5294   switch (get_attr_type (insn))
5295     {
5296     case TYPE_INCDEC:
5297       if (operands[2] == constm1_rtx)
5298         return "inc{q}\t%0";
5299       else
5300         {
5301           gcc_assert (operands[2] == const1_rtx);
5302           return "dec{q}\t%0";
5303         }
5305     default:
5306       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5307       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5308          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5309       if ((INTVAL (operands[2]) == -128
5310            || (INTVAL (operands[2]) > 0
5311                && INTVAL (operands[2]) != 128))
5312           /* Avoid overflows.  */
5313           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5314         return "sub{q}\t{%2, %0|%0, %2}";
5315       operands[2] = GEN_INT (-INTVAL (operands[2]));
5316       return "add{q}\t{%2, %0|%0, %2}";
5317     }
5319   [(set (attr "type")
5320      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5321         (const_string "incdec")
5322         (const_string "alu")))
5323    (set_attr "mode" "DI")])
5325 (define_insn "*adddi_5_rex64"
5326   [(set (reg FLAGS_REG)
5327         (compare
5328           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5329                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5330           (const_int 0)))                       
5331    (clobber (match_scratch:DI 0 "=r"))]
5332   "TARGET_64BIT
5333    && ix86_match_ccmode (insn, CCGOCmode)
5334    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5335    /* Current assemblers are broken and do not allow @GOTOFF in
5336       ought but a memory context.  */
5337    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5339   switch (get_attr_type (insn))
5340     {
5341     case TYPE_INCDEC:
5342       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5343       if (operands[2] == const1_rtx)
5344         return "inc{q}\t%0";
5345       else
5346         {
5347           gcc_assert (operands[2] == constm1_rtx);
5348           return "dec{q}\t%0";
5349         }
5351     default:
5352       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5353       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5354          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5355       if (GET_CODE (operands[2]) == CONST_INT
5356           /* Avoid overflows.  */
5357           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5358           && (INTVAL (operands[2]) == 128
5359               || (INTVAL (operands[2]) < 0
5360                   && INTVAL (operands[2]) != -128)))
5361         {
5362           operands[2] = GEN_INT (-INTVAL (operands[2]));
5363           return "sub{q}\t{%2, %0|%0, %2}";
5364         }
5365       return "add{q}\t{%2, %0|%0, %2}";
5366     }
5368   [(set (attr "type")
5369      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5370         (const_string "incdec")
5371         (const_string "alu")))
5372    (set_attr "mode" "DI")])
5375 (define_insn "*addsi_1"
5376   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5377         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5378                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5379    (clobber (reg:CC FLAGS_REG))]
5380   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5382   switch (get_attr_type (insn))
5383     {
5384     case TYPE_LEA:
5385       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5386       return "lea{l}\t{%a2, %0|%0, %a2}";
5388     case TYPE_INCDEC:
5389       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5390       if (operands[2] == const1_rtx)
5391         return "inc{l}\t%0";
5392       else
5393         {
5394           gcc_assert (operands[2] == constm1_rtx);
5395           return "dec{l}\t%0";
5396         }
5398     default:
5399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5402          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5403       if (GET_CODE (operands[2]) == CONST_INT
5404           && (INTVAL (operands[2]) == 128
5405               || (INTVAL (operands[2]) < 0
5406                   && INTVAL (operands[2]) != -128)))
5407         {
5408           operands[2] = GEN_INT (-INTVAL (operands[2]));
5409           return "sub{l}\t{%2, %0|%0, %2}";
5410         }
5411       return "add{l}\t{%2, %0|%0, %2}";
5412     }
5414   [(set (attr "type")
5415      (cond [(eq_attr "alternative" "2")
5416               (const_string "lea")
5417             ; Current assemblers are broken and do not allow @GOTOFF in
5418             ; ought but a memory context.
5419             (match_operand:SI 2 "pic_symbolic_operand" "")
5420               (const_string "lea")
5421             (match_operand:SI 2 "incdec_operand" "")
5422               (const_string "incdec")
5423            ]
5424            (const_string "alu")))
5425    (set_attr "mode" "SI")])
5427 ;; Convert lea to the lea pattern to avoid flags dependency.
5428 (define_split
5429   [(set (match_operand 0 "register_operand" "")
5430         (plus (match_operand 1 "register_operand" "")
5431               (match_operand 2 "nonmemory_operand" "")))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "reload_completed
5434    && true_regnum (operands[0]) != true_regnum (operands[1])"
5435   [(const_int 0)]
5437   rtx pat;
5438   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5439      may confuse gen_lowpart.  */
5440   if (GET_MODE (operands[0]) != Pmode)
5441     {
5442       operands[1] = gen_lowpart (Pmode, operands[1]);
5443       operands[2] = gen_lowpart (Pmode, operands[2]);
5444     }
5445   operands[0] = gen_lowpart (SImode, operands[0]);
5446   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5447   if (Pmode != SImode)
5448     pat = gen_rtx_SUBREG (SImode, pat, 0);
5449   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5450   DONE;
5453 ;; It may seem that nonimmediate operand is proper one for operand 1.
5454 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5455 ;; we take care in ix86_binary_operator_ok to not allow two memory
5456 ;; operands so proper swapping will be done in reload.  This allow
5457 ;; patterns constructed from addsi_1 to match.
5458 (define_insn "addsi_1_zext"
5459   [(set (match_operand:DI 0 "register_operand" "=r,r")
5460         (zero_extend:DI
5461           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5462                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5463    (clobber (reg:CC FLAGS_REG))]
5464   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5466   switch (get_attr_type (insn))
5467     {
5468     case TYPE_LEA:
5469       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5470       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5472     case TYPE_INCDEC:
5473       if (operands[2] == const1_rtx)
5474         return "inc{l}\t%k0";
5475       else
5476         {
5477           gcc_assert (operands[2] == constm1_rtx);
5478           return "dec{l}\t%k0";
5479         }
5481     default:
5482       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5483          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5484       if (GET_CODE (operands[2]) == CONST_INT
5485           && (INTVAL (operands[2]) == 128
5486               || (INTVAL (operands[2]) < 0
5487                   && INTVAL (operands[2]) != -128)))
5488         {
5489           operands[2] = GEN_INT (-INTVAL (operands[2]));
5490           return "sub{l}\t{%2, %k0|%k0, %2}";
5491         }
5492       return "add{l}\t{%2, %k0|%k0, %2}";
5493     }
5495   [(set (attr "type")
5496      (cond [(eq_attr "alternative" "1")
5497               (const_string "lea")
5498             ; Current assemblers are broken and do not allow @GOTOFF in
5499             ; ought but a memory context.
5500             (match_operand:SI 2 "pic_symbolic_operand" "")
5501               (const_string "lea")
5502             (match_operand:SI 2 "incdec_operand" "")
5503               (const_string "incdec")
5504            ]
5505            (const_string "alu")))
5506    (set_attr "mode" "SI")])
5508 ;; Convert lea to the lea pattern to avoid flags dependency.
5509 (define_split
5510   [(set (match_operand:DI 0 "register_operand" "")
5511         (zero_extend:DI
5512           (plus:SI (match_operand:SI 1 "register_operand" "")
5513                    (match_operand:SI 2 "nonmemory_operand" ""))))
5514    (clobber (reg:CC FLAGS_REG))]
5515   "TARGET_64BIT && reload_completed
5516    && true_regnum (operands[0]) != true_regnum (operands[1])"
5517   [(set (match_dup 0)
5518         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5520   operands[1] = gen_lowpart (Pmode, operands[1]);
5521   operands[2] = gen_lowpart (Pmode, operands[2]);
5524 (define_insn "*addsi_2"
5525   [(set (reg FLAGS_REG)
5526         (compare
5527           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5528                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5529           (const_int 0)))                       
5530    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5531         (plus:SI (match_dup 1) (match_dup 2)))]
5532   "ix86_match_ccmode (insn, CCGOCmode)
5533    && ix86_binary_operator_ok (PLUS, SImode, operands)
5534    /* Current assemblers are broken and do not allow @GOTOFF in
5535       ought but a memory context.  */
5536    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5538   switch (get_attr_type (insn))
5539     {
5540     case TYPE_INCDEC:
5541       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5542       if (operands[2] == const1_rtx)
5543         return "inc{l}\t%0";
5544       else
5545         {
5546           gcc_assert (operands[2] == constm1_rtx);
5547           return "dec{l}\t%0";
5548         }
5550     default:
5551       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5552       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5553          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5554       if (GET_CODE (operands[2]) == CONST_INT
5555           && (INTVAL (operands[2]) == 128
5556               || (INTVAL (operands[2]) < 0
5557                   && INTVAL (operands[2]) != -128)))
5558         {
5559           operands[2] = GEN_INT (-INTVAL (operands[2]));
5560           return "sub{l}\t{%2, %0|%0, %2}";
5561         }
5562       return "add{l}\t{%2, %0|%0, %2}";
5563     }
5565   [(set (attr "type")
5566      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5567         (const_string "incdec")
5568         (const_string "alu")))
5569    (set_attr "mode" "SI")])
5571 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5572 (define_insn "*addsi_2_zext"
5573   [(set (reg FLAGS_REG)
5574         (compare
5575           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5576                    (match_operand:SI 2 "general_operand" "rmni"))
5577           (const_int 0)))                       
5578    (set (match_operand:DI 0 "register_operand" "=r")
5579         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5581    && ix86_binary_operator_ok (PLUS, SImode, operands)
5582    /* Current assemblers are broken and do not allow @GOTOFF in
5583       ought but a memory context.  */
5584    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586   switch (get_attr_type (insn))
5587     {
5588     case TYPE_INCDEC:
5589       if (operands[2] == const1_rtx)
5590         return "inc{l}\t%k0";
5591       else
5592         {
5593           gcc_assert (operands[2] == constm1_rtx);
5594           return "dec{l}\t%k0";
5595         }
5597     default:
5598       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5599          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5600       if (GET_CODE (operands[2]) == CONST_INT
5601           && (INTVAL (operands[2]) == 128
5602               || (INTVAL (operands[2]) < 0
5603                   && INTVAL (operands[2]) != -128)))
5604         {
5605           operands[2] = GEN_INT (-INTVAL (operands[2]));
5606           return "sub{l}\t{%2, %k0|%k0, %2}";
5607         }
5608       return "add{l}\t{%2, %k0|%k0, %2}";
5609     }
5611   [(set (attr "type")
5612      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5613         (const_string "incdec")
5614         (const_string "alu")))
5615    (set_attr "mode" "SI")])
5617 (define_insn "*addsi_3"
5618   [(set (reg FLAGS_REG)
5619         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5620                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5621    (clobber (match_scratch:SI 0 "=r"))]
5622   "ix86_match_ccmode (insn, CCZmode)
5623    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5624    /* Current assemblers are broken and do not allow @GOTOFF in
5625       ought but a memory context.  */
5626    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5628   switch (get_attr_type (insn))
5629     {
5630     case TYPE_INCDEC:
5631       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632       if (operands[2] == const1_rtx)
5633         return "inc{l}\t%0";
5634       else
5635         {
5636           gcc_assert (operands[2] == constm1_rtx);
5637           return "dec{l}\t%0";
5638         }
5640     default:
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5643          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5644       if (GET_CODE (operands[2]) == CONST_INT
5645           && (INTVAL (operands[2]) == 128
5646               || (INTVAL (operands[2]) < 0
5647                   && INTVAL (operands[2]) != -128)))
5648         {
5649           operands[2] = GEN_INT (-INTVAL (operands[2]));
5650           return "sub{l}\t{%2, %0|%0, %2}";
5651         }
5652       return "add{l}\t{%2, %0|%0, %2}";
5653     }
5655   [(set (attr "type")
5656      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5657         (const_string "incdec")
5658         (const_string "alu")))
5659    (set_attr "mode" "SI")])
5661 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5662 (define_insn "*addsi_3_zext"
5663   [(set (reg FLAGS_REG)
5664         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5665                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5666    (set (match_operand:DI 0 "register_operand" "=r")
5667         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5668   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5669    && ix86_binary_operator_ok (PLUS, SImode, operands)
5670    /* Current assemblers are broken and do not allow @GOTOFF in
5671       ought but a memory context.  */
5672    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674   switch (get_attr_type (insn))
5675     {
5676     case TYPE_INCDEC:
5677       if (operands[2] == const1_rtx)
5678         return "inc{l}\t%k0";
5679       else
5680         {
5681           gcc_assert (operands[2] == constm1_rtx);
5682           return "dec{l}\t%k0";
5683         }
5685     default:
5686       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5687          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5688       if (GET_CODE (operands[2]) == CONST_INT
5689           && (INTVAL (operands[2]) == 128
5690               || (INTVAL (operands[2]) < 0
5691                   && INTVAL (operands[2]) != -128)))
5692         {
5693           operands[2] = GEN_INT (-INTVAL (operands[2]));
5694           return "sub{l}\t{%2, %k0|%k0, %2}";
5695         }
5696       return "add{l}\t{%2, %k0|%k0, %2}";
5697     }
5699   [(set (attr "type")
5700      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5701         (const_string "incdec")
5702         (const_string "alu")))
5703    (set_attr "mode" "SI")])
5705 ; For comparisons against 1, -1 and 128, we may generate better code
5706 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5707 ; is matched then.  We can't accept general immediate, because for
5708 ; case of overflows,  the result is messed up.
5709 ; This pattern also don't hold of 0x80000000, since the value overflows
5710 ; when negated.
5711 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5712 ; only for comparisons not depending on it.
5713 (define_insn "*addsi_4"
5714   [(set (reg FLAGS_REG)
5715         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5716                  (match_operand:SI 2 "const_int_operand" "n")))
5717    (clobber (match_scratch:SI 0 "=rm"))]
5718   "ix86_match_ccmode (insn, CCGCmode)
5719    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5721   switch (get_attr_type (insn))
5722     {
5723     case TYPE_INCDEC:
5724       if (operands[2] == constm1_rtx)
5725         return "inc{l}\t%0";
5726       else
5727         {
5728           gcc_assert (operands[2] == const1_rtx);
5729           return "dec{l}\t%0";
5730         }
5732     default:
5733       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5735          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5736       if ((INTVAL (operands[2]) == -128
5737            || (INTVAL (operands[2]) > 0
5738                && INTVAL (operands[2]) != 128)))
5739         return "sub{l}\t{%2, %0|%0, %2}";
5740       operands[2] = GEN_INT (-INTVAL (operands[2]));
5741       return "add{l}\t{%2, %0|%0, %2}";
5742     }
5744   [(set (attr "type")
5745      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5746         (const_string "incdec")
5747         (const_string "alu")))
5748    (set_attr "mode" "SI")])
5750 (define_insn "*addsi_5"
5751   [(set (reg FLAGS_REG)
5752         (compare
5753           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5754                    (match_operand:SI 2 "general_operand" "rmni"))
5755           (const_int 0)))                       
5756    (clobber (match_scratch:SI 0 "=r"))]
5757   "ix86_match_ccmode (insn, CCGOCmode)
5758    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5759    /* Current assemblers are broken and do not allow @GOTOFF in
5760       ought but a memory context.  */
5761    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5763   switch (get_attr_type (insn))
5764     {
5765     case TYPE_INCDEC:
5766       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5767       if (operands[2] == const1_rtx)
5768         return "inc{l}\t%0";
5769       else
5770         {
5771           gcc_assert (operands[2] == constm1_rtx);
5772           return "dec{l}\t%0";
5773         }
5775     default:
5776       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5777       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5778          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5779       if (GET_CODE (operands[2]) == CONST_INT
5780           && (INTVAL (operands[2]) == 128
5781               || (INTVAL (operands[2]) < 0
5782                   && INTVAL (operands[2]) != -128)))
5783         {
5784           operands[2] = GEN_INT (-INTVAL (operands[2]));
5785           return "sub{l}\t{%2, %0|%0, %2}";
5786         }
5787       return "add{l}\t{%2, %0|%0, %2}";
5788     }
5790   [(set (attr "type")
5791      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5792         (const_string "incdec")
5793         (const_string "alu")))
5794    (set_attr "mode" "SI")])
5796 (define_expand "addhi3"
5797   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5798                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5799                             (match_operand:HI 2 "general_operand" "")))
5800               (clobber (reg:CC FLAGS_REG))])]
5801   "TARGET_HIMODE_MATH"
5802   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5804 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5805 ;; type optimizations enabled by define-splits.  This is not important
5806 ;; for PII, and in fact harmful because of partial register stalls.
5808 (define_insn "*addhi_1_lea"
5809   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5810         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5811                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5812    (clobber (reg:CC FLAGS_REG))]
5813   "!TARGET_PARTIAL_REG_STALL
5814    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5816   switch (get_attr_type (insn))
5817     {
5818     case TYPE_LEA:
5819       return "#";
5820     case TYPE_INCDEC:
5821       if (operands[2] == const1_rtx)
5822         return "inc{w}\t%0";
5823       else
5824         {
5825           gcc_assert (operands[2] == constm1_rtx);
5826           return "dec{w}\t%0";
5827         }
5829     default:
5830       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5831          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5832       if (GET_CODE (operands[2]) == CONST_INT
5833           && (INTVAL (operands[2]) == 128
5834               || (INTVAL (operands[2]) < 0
5835                   && INTVAL (operands[2]) != -128)))
5836         {
5837           operands[2] = GEN_INT (-INTVAL (operands[2]));
5838           return "sub{w}\t{%2, %0|%0, %2}";
5839         }
5840       return "add{w}\t{%2, %0|%0, %2}";
5841     }
5843   [(set (attr "type")
5844      (if_then_else (eq_attr "alternative" "2")
5845         (const_string "lea")
5846         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5847            (const_string "incdec")
5848            (const_string "alu"))))
5849    (set_attr "mode" "HI,HI,SI")])
5851 (define_insn "*addhi_1"
5852   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5853         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5854                  (match_operand:HI 2 "general_operand" "ri,rm")))
5855    (clobber (reg:CC FLAGS_REG))]
5856   "TARGET_PARTIAL_REG_STALL
5857    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5859   switch (get_attr_type (insn))
5860     {
5861     case TYPE_INCDEC:
5862       if (operands[2] == const1_rtx)
5863         return "inc{w}\t%0";
5864       else
5865         {
5866           gcc_assert (operands[2] == constm1_rtx);
5867           return "dec{w}\t%0";
5868         }
5870     default:
5871       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5872          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5873       if (GET_CODE (operands[2]) == CONST_INT
5874           && (INTVAL (operands[2]) == 128
5875               || (INTVAL (operands[2]) < 0
5876                   && INTVAL (operands[2]) != -128)))
5877         {
5878           operands[2] = GEN_INT (-INTVAL (operands[2]));
5879           return "sub{w}\t{%2, %0|%0, %2}";
5880         }
5881       return "add{w}\t{%2, %0|%0, %2}";
5882     }
5884   [(set (attr "type")
5885      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5886         (const_string "incdec")
5887         (const_string "alu")))
5888    (set_attr "mode" "HI")])
5890 (define_insn "*addhi_2"
5891   [(set (reg FLAGS_REG)
5892         (compare
5893           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5894                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5895           (const_int 0)))                       
5896    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5897         (plus:HI (match_dup 1) (match_dup 2)))]
5898   "ix86_match_ccmode (insn, CCGOCmode)
5899    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{w}\t%0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{w}\t%0";
5910         }
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (GET_CODE (operands[2]) == CONST_INT
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{w}\t{%2, %0|%0, %2}";
5922         }
5923       return "add{w}\t{%2, %0|%0, %2}";
5924     }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "HI")])
5932 (define_insn "*addhi_3"
5933   [(set (reg FLAGS_REG)
5934         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5935                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5936    (clobber (match_scratch:HI 0 "=r"))]
5937   "ix86_match_ccmode (insn, CCZmode)
5938    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5940   switch (get_attr_type (insn))
5941     {
5942     case TYPE_INCDEC:
5943       if (operands[2] == const1_rtx)
5944         return "inc{w}\t%0";
5945       else
5946         {
5947           gcc_assert (operands[2] == constm1_rtx);
5948           return "dec{w}\t%0";
5949         }
5951     default:
5952       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5953          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5954       if (GET_CODE (operands[2]) == CONST_INT
5955           && (INTVAL (operands[2]) == 128
5956               || (INTVAL (operands[2]) < 0
5957                   && INTVAL (operands[2]) != -128)))
5958         {
5959           operands[2] = GEN_INT (-INTVAL (operands[2]));
5960           return "sub{w}\t{%2, %0|%0, %2}";
5961         }
5962       return "add{w}\t{%2, %0|%0, %2}";
5963     }
5965   [(set (attr "type")
5966      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967         (const_string "incdec")
5968         (const_string "alu")))
5969    (set_attr "mode" "HI")])
5971 ; See comments above addsi_4 for details.
5972 (define_insn "*addhi_4"
5973   [(set (reg FLAGS_REG)
5974         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5975                  (match_operand:HI 2 "const_int_operand" "n")))
5976    (clobber (match_scratch:HI 0 "=rm"))]
5977   "ix86_match_ccmode (insn, CCGCmode)
5978    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5980   switch (get_attr_type (insn))
5981     {
5982     case TYPE_INCDEC:
5983       if (operands[2] == constm1_rtx)
5984         return "inc{w}\t%0";
5985       else
5986         {
5987           gcc_assert (operands[2] == const1_rtx);
5988           return "dec{w}\t%0";
5989         }
5991     default:
5992       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5993       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5994          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5995       if ((INTVAL (operands[2]) == -128
5996            || (INTVAL (operands[2]) > 0
5997                && INTVAL (operands[2]) != 128)))
5998         return "sub{w}\t{%2, %0|%0, %2}";
5999       operands[2] = GEN_INT (-INTVAL (operands[2]));
6000       return "add{w}\t{%2, %0|%0, %2}";
6001     }
6003   [(set (attr "type")
6004      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6005         (const_string "incdec")
6006         (const_string "alu")))
6007    (set_attr "mode" "SI")])
6010 (define_insn "*addhi_5"
6011   [(set (reg FLAGS_REG)
6012         (compare
6013           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6014                    (match_operand:HI 2 "general_operand" "rmni"))
6015           (const_int 0)))                       
6016    (clobber (match_scratch:HI 0 "=r"))]
6017   "ix86_match_ccmode (insn, CCGOCmode)
6018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6020   switch (get_attr_type (insn))
6021     {
6022     case TYPE_INCDEC:
6023       if (operands[2] == const1_rtx)
6024         return "inc{w}\t%0";
6025       else
6026         {
6027           gcc_assert (operands[2] == constm1_rtx);
6028           return "dec{w}\t%0";
6029         }
6031     default:
6032       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6034       if (GET_CODE (operands[2]) == CONST_INT
6035           && (INTVAL (operands[2]) == 128
6036               || (INTVAL (operands[2]) < 0
6037                   && INTVAL (operands[2]) != -128)))
6038         {
6039           operands[2] = GEN_INT (-INTVAL (operands[2]));
6040           return "sub{w}\t{%2, %0|%0, %2}";
6041         }
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "HI")])
6051 (define_expand "addqi3"
6052   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6053                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6054                             (match_operand:QI 2 "general_operand" "")))
6055               (clobber (reg:CC FLAGS_REG))])]
6056   "TARGET_QIMODE_MATH"
6057   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6059 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6060 (define_insn "*addqi_1_lea"
6061   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6062         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6063                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6064    (clobber (reg:CC FLAGS_REG))]
6065   "!TARGET_PARTIAL_REG_STALL
6066    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6068   int widen = (which_alternative == 2);
6069   switch (get_attr_type (insn))
6070     {
6071     case TYPE_LEA:
6072       return "#";
6073     case TYPE_INCDEC:
6074       if (operands[2] == const1_rtx)
6075         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6076       else
6077         {
6078           gcc_assert (operands[2] == constm1_rtx);
6079           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6080         }
6082     default:
6083       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6084          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6085       if (GET_CODE (operands[2]) == CONST_INT
6086           && (INTVAL (operands[2]) == 128
6087               || (INTVAL (operands[2]) < 0
6088                   && INTVAL (operands[2]) != -128)))
6089         {
6090           operands[2] = GEN_INT (-INTVAL (operands[2]));
6091           if (widen)
6092             return "sub{l}\t{%2, %k0|%k0, %2}";
6093           else
6094             return "sub{b}\t{%2, %0|%0, %2}";
6095         }
6096       if (widen)
6097         return "add{l}\t{%k2, %k0|%k0, %k2}";
6098       else
6099         return "add{b}\t{%2, %0|%0, %2}";
6100     }
6102   [(set (attr "type")
6103      (if_then_else (eq_attr "alternative" "3")
6104         (const_string "lea")
6105         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6106            (const_string "incdec")
6107            (const_string "alu"))))
6108    (set_attr "mode" "QI,QI,SI,SI")])
6110 (define_insn "*addqi_1"
6111   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6112         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6113                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6114    (clobber (reg:CC FLAGS_REG))]
6115   "TARGET_PARTIAL_REG_STALL
6116    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6118   int widen = (which_alternative == 2);
6119   switch (get_attr_type (insn))
6120     {
6121     case TYPE_INCDEC:
6122       if (operands[2] == const1_rtx)
6123         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6124       else
6125         {
6126           gcc_assert (operands[2] == constm1_rtx);
6127           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6128         }
6130     default:
6131       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6132          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6133       if (GET_CODE (operands[2]) == CONST_INT
6134           && (INTVAL (operands[2]) == 128
6135               || (INTVAL (operands[2]) < 0
6136                   && INTVAL (operands[2]) != -128)))
6137         {
6138           operands[2] = GEN_INT (-INTVAL (operands[2]));
6139           if (widen)
6140             return "sub{l}\t{%2, %k0|%k0, %2}";
6141           else
6142             return "sub{b}\t{%2, %0|%0, %2}";
6143         }
6144       if (widen)
6145         return "add{l}\t{%k2, %k0|%k0, %k2}";
6146       else
6147         return "add{b}\t{%2, %0|%0, %2}";
6148     }
6150   [(set (attr "type")
6151      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6152         (const_string "incdec")
6153         (const_string "alu")))
6154    (set_attr "mode" "QI,QI,SI")])
6156 (define_insn "*addqi_1_slp"
6157   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6158         (plus:QI (match_dup 0)
6159                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6160    (clobber (reg:CC FLAGS_REG))]
6161   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6162    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[1] == const1_rtx)
6168         return "inc{b}\t%0";
6169       else
6170         {
6171           gcc_assert (operands[1] == constm1_rtx);
6172           return "dec{b}\t%0";
6173         }
6175     default:
6176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6177       if (GET_CODE (operands[1]) == CONST_INT
6178           && INTVAL (operands[1]) < 0)
6179         {
6180           operands[1] = GEN_INT (-INTVAL (operands[1]));
6181           return "sub{b}\t{%1, %0|%0, %1}";
6182         }
6183       return "add{b}\t{%1, %0|%0, %1}";
6184     }
6186   [(set (attr "type")
6187      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6188         (const_string "incdec")
6189         (const_string "alu1")))
6190    (set (attr "memory")
6191      (if_then_else (match_operand 1 "memory_operand" "")
6192         (const_string "load")
6193         (const_string "none")))
6194    (set_attr "mode" "QI")])
6196 (define_insn "*addqi_2"
6197   [(set (reg FLAGS_REG)
6198         (compare
6199           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6200                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6201           (const_int 0)))
6202    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6203         (plus:QI (match_dup 1) (match_dup 2)))]
6204   "ix86_match_ccmode (insn, CCGOCmode)
6205    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6207   switch (get_attr_type (insn))
6208     {
6209     case TYPE_INCDEC:
6210       if (operands[2] == const1_rtx)
6211         return "inc{b}\t%0";
6212       else
6213         {
6214           gcc_assert (operands[2] == constm1_rtx
6215                       || (GET_CODE (operands[2]) == CONST_INT
6216                           && INTVAL (operands[2]) == 255));
6217           return "dec{b}\t%0";
6218         }
6220     default:
6221       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6222       if (GET_CODE (operands[2]) == CONST_INT
6223           && INTVAL (operands[2]) < 0)
6224         {
6225           operands[2] = GEN_INT (-INTVAL (operands[2]));
6226           return "sub{b}\t{%2, %0|%0, %2}";
6227         }
6228       return "add{b}\t{%2, %0|%0, %2}";
6229     }
6231   [(set (attr "type")
6232      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6233         (const_string "incdec")
6234         (const_string "alu")))
6235    (set_attr "mode" "QI")])
6237 (define_insn "*addqi_3"
6238   [(set (reg FLAGS_REG)
6239         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6240                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6241    (clobber (match_scratch:QI 0 "=q"))]
6242   "ix86_match_ccmode (insn, CCZmode)
6243    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6245   switch (get_attr_type (insn))
6246     {
6247     case TYPE_INCDEC:
6248       if (operands[2] == const1_rtx)
6249         return "inc{b}\t%0";
6250       else
6251         {
6252           gcc_assert (operands[2] == constm1_rtx
6253                       || (GET_CODE (operands[2]) == CONST_INT
6254                           && INTVAL (operands[2]) == 255));
6255           return "dec{b}\t%0";
6256         }
6258     default:
6259       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6260       if (GET_CODE (operands[2]) == CONST_INT
6261           && INTVAL (operands[2]) < 0)
6262         {
6263           operands[2] = GEN_INT (-INTVAL (operands[2]));
6264           return "sub{b}\t{%2, %0|%0, %2}";
6265         }
6266       return "add{b}\t{%2, %0|%0, %2}";
6267     }
6269   [(set (attr "type")
6270      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6271         (const_string "incdec")
6272         (const_string "alu")))
6273    (set_attr "mode" "QI")])
6275 ; See comments above addsi_4 for details.
6276 (define_insn "*addqi_4"
6277   [(set (reg FLAGS_REG)
6278         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6279                  (match_operand:QI 2 "const_int_operand" "n")))
6280    (clobber (match_scratch:QI 0 "=qm"))]
6281   "ix86_match_ccmode (insn, CCGCmode)
6282    && (INTVAL (operands[2]) & 0xff) != 0x80"
6284   switch (get_attr_type (insn))
6285     {
6286     case TYPE_INCDEC:
6287       if (operands[2] == constm1_rtx
6288           || (GET_CODE (operands[2]) == CONST_INT
6289               && INTVAL (operands[2]) == 255))
6290         return "inc{b}\t%0";
6291       else
6292         {
6293           gcc_assert (operands[2] == const1_rtx);
6294           return "dec{b}\t%0";
6295         }
6297     default:
6298       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6299       if (INTVAL (operands[2]) < 0)
6300         {
6301           operands[2] = GEN_INT (-INTVAL (operands[2]));
6302           return "add{b}\t{%2, %0|%0, %2}";
6303         }
6304       return "sub{b}\t{%2, %0|%0, %2}";
6305     }
6307   [(set (attr "type")
6308      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6309         (const_string "incdec")
6310         (const_string "alu")))
6311    (set_attr "mode" "QI")])
6314 (define_insn "*addqi_5"
6315   [(set (reg FLAGS_REG)
6316         (compare
6317           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6318                    (match_operand:QI 2 "general_operand" "qmni"))
6319           (const_int 0)))
6320    (clobber (match_scratch:QI 0 "=q"))]
6321   "ix86_match_ccmode (insn, CCGOCmode)
6322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6324   switch (get_attr_type (insn))
6325     {
6326     case TYPE_INCDEC:
6327       if (operands[2] == const1_rtx)
6328         return "inc{b}\t%0";
6329       else
6330         {
6331           gcc_assert (operands[2] == constm1_rtx
6332                       || (GET_CODE (operands[2]) == CONST_INT
6333                           && INTVAL (operands[2]) == 255));
6334           return "dec{b}\t%0";
6335         }
6337     default:
6338       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6339       if (GET_CODE (operands[2]) == CONST_INT
6340           && INTVAL (operands[2]) < 0)
6341         {
6342           operands[2] = GEN_INT (-INTVAL (operands[2]));
6343           return "sub{b}\t{%2, %0|%0, %2}";
6344         }
6345       return "add{b}\t{%2, %0|%0, %2}";
6346     }
6348   [(set (attr "type")
6349      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6350         (const_string "incdec")
6351         (const_string "alu")))
6352    (set_attr "mode" "QI")])
6355 (define_insn "addqi_ext_1"
6356   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6357                          (const_int 8)
6358                          (const_int 8))
6359         (plus:SI
6360           (zero_extract:SI
6361             (match_operand 1 "ext_register_operand" "0")
6362             (const_int 8)
6363             (const_int 8))
6364           (match_operand:QI 2 "general_operand" "Qmn")))
6365    (clobber (reg:CC FLAGS_REG))]
6366   "!TARGET_64BIT"
6368   switch (get_attr_type (insn))
6369     {
6370     case TYPE_INCDEC:
6371       if (operands[2] == const1_rtx)
6372         return "inc{b}\t%h0";
6373       else
6374         {
6375           gcc_assert (operands[2] == constm1_rtx
6376                       || (GET_CODE (operands[2]) == CONST_INT
6377                           && INTVAL (operands[2]) == 255));
6378           return "dec{b}\t%h0";
6379         }
6381     default:
6382       return "add{b}\t{%2, %h0|%h0, %2}";
6383     }
6385   [(set (attr "type")
6386      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387         (const_string "incdec")
6388         (const_string "alu")))
6389    (set_attr "mode" "QI")])
6391 (define_insn "*addqi_ext_1_rex64"
6392   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6393                          (const_int 8)
6394                          (const_int 8))
6395         (plus:SI
6396           (zero_extract:SI
6397             (match_operand 1 "ext_register_operand" "0")
6398             (const_int 8)
6399             (const_int 8))
6400           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6401    (clobber (reg:CC FLAGS_REG))]
6402   "TARGET_64BIT"
6404   switch (get_attr_type (insn))
6405     {
6406     case TYPE_INCDEC:
6407       if (operands[2] == const1_rtx)
6408         return "inc{b}\t%h0";
6409       else
6410         {
6411           gcc_assert (operands[2] == constm1_rtx
6412                       || (GET_CODE (operands[2]) == CONST_INT
6413                           && INTVAL (operands[2]) == 255));
6414           return "dec{b}\t%h0";
6415         }
6417     default:
6418       return "add{b}\t{%2, %h0|%h0, %2}";
6419     }
6421   [(set (attr "type")
6422      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6423         (const_string "incdec")
6424         (const_string "alu")))
6425    (set_attr "mode" "QI")])
6427 (define_insn "*addqi_ext_2"
6428   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6429                          (const_int 8)
6430                          (const_int 8))
6431         (plus:SI
6432           (zero_extract:SI
6433             (match_operand 1 "ext_register_operand" "%0")
6434             (const_int 8)
6435             (const_int 8))
6436           (zero_extract:SI
6437             (match_operand 2 "ext_register_operand" "Q")
6438             (const_int 8)
6439             (const_int 8))))
6440    (clobber (reg:CC FLAGS_REG))]
6441   ""
6442   "add{b}\t{%h2, %h0|%h0, %h2}"
6443   [(set_attr "type" "alu")
6444    (set_attr "mode" "QI")])
6446 ;; The patterns that match these are at the end of this file.
6448 (define_expand "addxf3"
6449   [(set (match_operand:XF 0 "register_operand" "")
6450         (plus:XF (match_operand:XF 1 "register_operand" "")
6451                  (match_operand:XF 2 "register_operand" "")))]
6452   "TARGET_80387"
6453   "")
6455 (define_expand "adddf3"
6456   [(set (match_operand:DF 0 "register_operand" "")
6457         (plus:DF (match_operand:DF 1 "register_operand" "")
6458                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6459   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6460   "")
6462 (define_expand "addsf3"
6463   [(set (match_operand:SF 0 "register_operand" "")
6464         (plus:SF (match_operand:SF 1 "register_operand" "")
6465                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6466   "TARGET_80387 || TARGET_SSE_MATH"
6467   "")
6469 ;; Subtract instructions
6471 ;; %%% splits for subditi3
6473 (define_expand "subti3"
6474   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6475                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6476                              (match_operand:TI 2 "x86_64_general_operand" "")))
6477               (clobber (reg:CC FLAGS_REG))])]
6478   "TARGET_64BIT"
6479   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6481 (define_insn "*subti3_1"
6482   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6483         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6484                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6485    (clobber (reg:CC FLAGS_REG))]
6486   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6487   "#")
6489 (define_split
6490   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6491         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6492                   (match_operand:TI 2 "general_operand" "")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "TARGET_64BIT && reload_completed"
6495   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6496               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6497    (parallel [(set (match_dup 3)
6498                    (minus:DI (match_dup 4)
6499                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6500                                       (match_dup 5))))
6501               (clobber (reg:CC FLAGS_REG))])]
6502   "split_ti (operands+0, 1, operands+0, operands+3);
6503    split_ti (operands+1, 1, operands+1, operands+4);
6504    split_ti (operands+2, 1, operands+2, operands+5);")
6506 ;; %%% splits for subsidi3
6508 (define_expand "subdi3"
6509   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6510                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6511                              (match_operand:DI 2 "x86_64_general_operand" "")))
6512               (clobber (reg:CC FLAGS_REG))])]
6513   ""
6514   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6516 (define_insn "*subdi3_1"
6517   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6518         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6519                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6520    (clobber (reg:CC FLAGS_REG))]
6521   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6522   "#")
6524 (define_split
6525   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6526         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6527                   (match_operand:DI 2 "general_operand" "")))
6528    (clobber (reg:CC FLAGS_REG))]
6529   "!TARGET_64BIT && reload_completed"
6530   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6531               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6532    (parallel [(set (match_dup 3)
6533                    (minus:SI (match_dup 4)
6534                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6535                                       (match_dup 5))))
6536               (clobber (reg:CC FLAGS_REG))])]
6537   "split_di (operands+0, 1, operands+0, operands+3);
6538    split_di (operands+1, 1, operands+1, operands+4);
6539    split_di (operands+2, 1, operands+2, operands+5);")
6541 (define_insn "subdi3_carry_rex64"
6542   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6544             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6545                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6546    (clobber (reg:CC FLAGS_REG))]
6547   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6548   "sbb{q}\t{%2, %0|%0, %2}"
6549   [(set_attr "type" "alu")
6550    (set_attr "pent_pair" "pu")
6551    (set_attr "mode" "DI")])
6553 (define_insn "*subdi_1_rex64"
6554   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6556                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6557    (clobber (reg:CC FLAGS_REG))]
6558   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6559   "sub{q}\t{%2, %0|%0, %2}"
6560   [(set_attr "type" "alu")
6561    (set_attr "mode" "DI")])
6563 (define_insn "*subdi_2_rex64"
6564   [(set (reg FLAGS_REG)
6565         (compare
6566           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6567                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6568           (const_int 0)))
6569    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6570         (minus:DI (match_dup 1) (match_dup 2)))]
6571   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6572    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6573   "sub{q}\t{%2, %0|%0, %2}"
6574   [(set_attr "type" "alu")
6575    (set_attr "mode" "DI")])
6577 (define_insn "*subdi_3_rex63"
6578   [(set (reg FLAGS_REG)
6579         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6580                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6581    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6582         (minus:DI (match_dup 1) (match_dup 2)))]
6583   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6584    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6585   "sub{q}\t{%2, %0|%0, %2}"
6586   [(set_attr "type" "alu")
6587    (set_attr "mode" "DI")])
6589 (define_insn "subqi3_carry"
6590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6591           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6592             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6593                (match_operand:QI 2 "general_operand" "qi,qm"))))
6594    (clobber (reg:CC FLAGS_REG))]
6595   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6596   "sbb{b}\t{%2, %0|%0, %2}"
6597   [(set_attr "type" "alu")
6598    (set_attr "pent_pair" "pu")
6599    (set_attr "mode" "QI")])
6601 (define_insn "subhi3_carry"
6602   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6603           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6604             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6605                (match_operand:HI 2 "general_operand" "ri,rm"))))
6606    (clobber (reg:CC FLAGS_REG))]
6607   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6608   "sbb{w}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "pent_pair" "pu")
6611    (set_attr "mode" "HI")])
6613 (define_insn "subsi3_carry"
6614   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6616             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6617                (match_operand:SI 2 "general_operand" "ri,rm"))))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6620   "sbb{l}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "pent_pair" "pu")
6623    (set_attr "mode" "SI")])
6625 (define_insn "subsi3_carry_zext"
6626   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6627           (zero_extend:DI
6628             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6629               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6630                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6631    (clobber (reg:CC FLAGS_REG))]
6632   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6633   "sbb{l}\t{%2, %k0|%k0, %2}"
6634   [(set_attr "type" "alu")
6635    (set_attr "pent_pair" "pu")
6636    (set_attr "mode" "SI")])
6638 (define_expand "subsi3"
6639   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6640                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6641                              (match_operand:SI 2 "general_operand" "")))
6642               (clobber (reg:CC FLAGS_REG))])]
6643   ""
6644   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6646 (define_insn "*subsi_1"
6647   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6648         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6649                   (match_operand:SI 2 "general_operand" "ri,rm")))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6652   "sub{l}\t{%2, %0|%0, %2}"
6653   [(set_attr "type" "alu")
6654    (set_attr "mode" "SI")])
6656 (define_insn "*subsi_1_zext"
6657   [(set (match_operand:DI 0 "register_operand" "=r")
6658         (zero_extend:DI
6659           (minus:SI (match_operand:SI 1 "register_operand" "0")
6660                     (match_operand:SI 2 "general_operand" "rim"))))
6661    (clobber (reg:CC FLAGS_REG))]
6662   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663   "sub{l}\t{%2, %k0|%k0, %2}"
6664   [(set_attr "type" "alu")
6665    (set_attr "mode" "SI")])
6667 (define_insn "*subsi_2"
6668   [(set (reg FLAGS_REG)
6669         (compare
6670           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6671                     (match_operand:SI 2 "general_operand" "ri,rm"))
6672           (const_int 0)))
6673    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6674         (minus:SI (match_dup 1) (match_dup 2)))]
6675   "ix86_match_ccmode (insn, CCGOCmode)
6676    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6677   "sub{l}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "mode" "SI")])
6681 (define_insn "*subsi_2_zext"
6682   [(set (reg FLAGS_REG)
6683         (compare
6684           (minus:SI (match_operand:SI 1 "register_operand" "0")
6685                     (match_operand:SI 2 "general_operand" "rim"))
6686           (const_int 0)))
6687    (set (match_operand:DI 0 "register_operand" "=r")
6688         (zero_extend:DI
6689           (minus:SI (match_dup 1)
6690                     (match_dup 2))))]
6691   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6692    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693   "sub{l}\t{%2, %k0|%k0, %2}"
6694   [(set_attr "type" "alu")
6695    (set_attr "mode" "SI")])
6697 (define_insn "*subsi_3"
6698   [(set (reg FLAGS_REG)
6699         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6700                  (match_operand:SI 2 "general_operand" "ri,rm")))
6701    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:SI (match_dup 1) (match_dup 2)))]
6703   "ix86_match_ccmode (insn, CCmode)
6704    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705   "sub{l}\t{%2, %0|%0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "SI")])
6709 (define_insn "*subsi_3_zext"
6710   [(set (reg FLAGS_REG)
6711         (compare (match_operand:SI 1 "register_operand" "0")
6712                  (match_operand:SI 2 "general_operand" "rim")))
6713    (set (match_operand:DI 0 "register_operand" "=r")
6714         (zero_extend:DI
6715           (minus:SI (match_dup 1)
6716                     (match_dup 2))))]
6717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6718    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719   "sub{q}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "DI")])
6723 (define_expand "subhi3"
6724   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6725                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6726                              (match_operand:HI 2 "general_operand" "")))
6727               (clobber (reg:CC FLAGS_REG))])]
6728   "TARGET_HIMODE_MATH"
6729   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6731 (define_insn "*subhi_1"
6732   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6734                   (match_operand:HI 2 "general_operand" "ri,rm")))
6735    (clobber (reg:CC FLAGS_REG))]
6736   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6737   "sub{w}\t{%2, %0|%0, %2}"
6738   [(set_attr "type" "alu")
6739    (set_attr "mode" "HI")])
6741 (define_insn "*subhi_2"
6742   [(set (reg FLAGS_REG)
6743         (compare
6744           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6745                     (match_operand:HI 2 "general_operand" "ri,rm"))
6746           (const_int 0)))
6747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6748         (minus:HI (match_dup 1) (match_dup 2)))]
6749   "ix86_match_ccmode (insn, CCGOCmode)
6750    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6751   "sub{w}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "mode" "HI")])
6755 (define_insn "*subhi_3"
6756   [(set (reg FLAGS_REG)
6757         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6758                  (match_operand:HI 2 "general_operand" "ri,rm")))
6759    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6760         (minus:HI (match_dup 1) (match_dup 2)))]
6761   "ix86_match_ccmode (insn, CCmode)
6762    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6763   "sub{w}\t{%2, %0|%0, %2}"
6764   [(set_attr "type" "alu")
6765    (set_attr "mode" "HI")])
6767 (define_expand "subqi3"
6768   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6769                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6770                              (match_operand:QI 2 "general_operand" "")))
6771               (clobber (reg:CC FLAGS_REG))])]
6772   "TARGET_QIMODE_MATH"
6773   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6775 (define_insn "*subqi_1"
6776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6777         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6778                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6781   "sub{b}\t{%2, %0|%0, %2}"
6782   [(set_attr "type" "alu")
6783    (set_attr "mode" "QI")])
6785 (define_insn "*subqi_1_slp"
6786   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6787         (minus:QI (match_dup 0)
6788                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6789    (clobber (reg:CC FLAGS_REG))]
6790   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6791    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6792   "sub{b}\t{%1, %0|%0, %1}"
6793   [(set_attr "type" "alu1")
6794    (set_attr "mode" "QI")])
6796 (define_insn "*subqi_2"
6797   [(set (reg FLAGS_REG)
6798         (compare
6799           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6800                     (match_operand:QI 2 "general_operand" "qi,qm"))
6801           (const_int 0)))
6802    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6803         (minus:HI (match_dup 1) (match_dup 2)))]
6804   "ix86_match_ccmode (insn, CCGOCmode)
6805    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6806   "sub{b}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "QI")])
6810 (define_insn "*subqi_3"
6811   [(set (reg FLAGS_REG)
6812         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6813                  (match_operand:QI 2 "general_operand" "qi,qm")))
6814    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6815         (minus:HI (match_dup 1) (match_dup 2)))]
6816   "ix86_match_ccmode (insn, CCmode)
6817    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6818   "sub{b}\t{%2, %0|%0, %2}"
6819   [(set_attr "type" "alu")
6820    (set_attr "mode" "QI")])
6822 ;; The patterns that match these are at the end of this file.
6824 (define_expand "subxf3"
6825   [(set (match_operand:XF 0 "register_operand" "")
6826         (minus:XF (match_operand:XF 1 "register_operand" "")
6827                   (match_operand:XF 2 "register_operand" "")))]
6828   "TARGET_80387"
6829   "")
6831 (define_expand "subdf3"
6832   [(set (match_operand:DF 0 "register_operand" "")
6833         (minus:DF (match_operand:DF 1 "register_operand" "")
6834                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6835   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6836   "")
6838 (define_expand "subsf3"
6839   [(set (match_operand:SF 0 "register_operand" "")
6840         (minus:SF (match_operand:SF 1 "register_operand" "")
6841                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6842   "TARGET_80387 || TARGET_SSE_MATH"
6843   "")
6845 ;; Multiply instructions
6847 (define_expand "muldi3"
6848   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6849                    (mult:DI (match_operand:DI 1 "register_operand" "")
6850                             (match_operand:DI 2 "x86_64_general_operand" "")))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   "TARGET_64BIT"
6853   "")
6855 (define_insn "*muldi3_1_rex64"
6856   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6857         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6858                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "TARGET_64BIT
6861    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6862   "@
6863    imul{q}\t{%2, %1, %0|%0, %1, %2}
6864    imul{q}\t{%2, %1, %0|%0, %1, %2}
6865    imul{q}\t{%2, %0|%0, %2}"
6866   [(set_attr "type" "imul")
6867    (set_attr "prefix_0f" "0,0,1")
6868    (set (attr "athlon_decode")
6869         (cond [(eq_attr "cpu" "athlon")
6870                   (const_string "vector")
6871                (eq_attr "alternative" "1")
6872                   (const_string "vector")
6873                (and (eq_attr "alternative" "2")
6874                     (match_operand 1 "memory_operand" ""))
6875                   (const_string "vector")]
6876               (const_string "direct")))
6877    (set_attr "mode" "DI")])
6879 (define_expand "mulsi3"
6880   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6881                    (mult:SI (match_operand:SI 1 "register_operand" "")
6882                             (match_operand:SI 2 "general_operand" "")))
6883               (clobber (reg:CC FLAGS_REG))])]
6884   ""
6885   "")
6887 (define_insn "*mulsi3_1"
6888   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6889         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6890                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6891    (clobber (reg:CC FLAGS_REG))]
6892   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6893   "@
6894    imul{l}\t{%2, %1, %0|%0, %1, %2}
6895    imul{l}\t{%2, %1, %0|%0, %1, %2}
6896    imul{l}\t{%2, %0|%0, %2}"
6897   [(set_attr "type" "imul")
6898    (set_attr "prefix_0f" "0,0,1")
6899    (set (attr "athlon_decode")
6900         (cond [(eq_attr "cpu" "athlon")
6901                   (const_string "vector")
6902                (eq_attr "alternative" "1")
6903                   (const_string "vector")
6904                (and (eq_attr "alternative" "2")
6905                     (match_operand 1 "memory_operand" ""))
6906                   (const_string "vector")]
6907               (const_string "direct")))
6908    (set_attr "mode" "SI")])
6910 (define_insn "*mulsi3_1_zext"
6911   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6912         (zero_extend:DI
6913           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6914                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "TARGET_64BIT
6917    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6918   "@
6919    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6920    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921    imul{l}\t{%2, %k0|%k0, %2}"
6922   [(set_attr "type" "imul")
6923    (set_attr "prefix_0f" "0,0,1")
6924    (set (attr "athlon_decode")
6925         (cond [(eq_attr "cpu" "athlon")
6926                   (const_string "vector")
6927                (eq_attr "alternative" "1")
6928                   (const_string "vector")
6929                (and (eq_attr "alternative" "2")
6930                     (match_operand 1 "memory_operand" ""))
6931                   (const_string "vector")]
6932               (const_string "direct")))
6933    (set_attr "mode" "SI")])
6935 (define_expand "mulhi3"
6936   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6937                    (mult:HI (match_operand:HI 1 "register_operand" "")
6938                             (match_operand:HI 2 "general_operand" "")))
6939               (clobber (reg:CC FLAGS_REG))])]
6940   "TARGET_HIMODE_MATH"
6941   "")
6943 (define_insn "*mulhi3_1"
6944   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6945         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6946                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6947    (clobber (reg:CC FLAGS_REG))]
6948   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6949   "@
6950    imul{w}\t{%2, %1, %0|%0, %1, %2}
6951    imul{w}\t{%2, %1, %0|%0, %1, %2}
6952    imul{w}\t{%2, %0|%0, %2}"
6953   [(set_attr "type" "imul")
6954    (set_attr "prefix_0f" "0,0,1")
6955    (set (attr "athlon_decode")
6956         (cond [(eq_attr "cpu" "athlon")
6957                   (const_string "vector")
6958                (eq_attr "alternative" "1,2")
6959                   (const_string "vector")]
6960               (const_string "direct")))
6961    (set_attr "mode" "HI")])
6963 (define_expand "mulqi3"
6964   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6965                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6966                             (match_operand:QI 2 "register_operand" "")))
6967               (clobber (reg:CC FLAGS_REG))])]
6968   "TARGET_QIMODE_MATH"
6969   "")
6971 (define_insn "*mulqi3_1"
6972   [(set (match_operand:QI 0 "register_operand" "=a")
6973         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6974                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6975    (clobber (reg:CC FLAGS_REG))]
6976   "TARGET_QIMODE_MATH
6977    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6978   "mul{b}\t%2"
6979   [(set_attr "type" "imul")
6980    (set_attr "length_immediate" "0")
6981    (set (attr "athlon_decode")
6982      (if_then_else (eq_attr "cpu" "athlon")
6983         (const_string "vector")
6984         (const_string "direct")))
6985    (set_attr "mode" "QI")])
6987 (define_expand "umulqihi3"
6988   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6989                    (mult:HI (zero_extend:HI
6990                               (match_operand:QI 1 "nonimmediate_operand" ""))
6991                             (zero_extend:HI
6992                               (match_operand:QI 2 "register_operand" ""))))
6993               (clobber (reg:CC FLAGS_REG))])]
6994   "TARGET_QIMODE_MATH"
6995   "")
6997 (define_insn "*umulqihi3_1"
6998   [(set (match_operand:HI 0 "register_operand" "=a")
6999         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7000                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7001    (clobber (reg:CC FLAGS_REG))]
7002   "TARGET_QIMODE_MATH
7003    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7004   "mul{b}\t%2"
7005   [(set_attr "type" "imul")
7006    (set_attr "length_immediate" "0")
7007    (set (attr "athlon_decode")
7008      (if_then_else (eq_attr "cpu" "athlon")
7009         (const_string "vector")
7010         (const_string "direct")))
7011    (set_attr "mode" "QI")])
7013 (define_expand "mulqihi3"
7014   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7015                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7016                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7017               (clobber (reg:CC FLAGS_REG))])]
7018   "TARGET_QIMODE_MATH"
7019   "")
7021 (define_insn "*mulqihi3_insn"
7022   [(set (match_operand:HI 0 "register_operand" "=a")
7023         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7024                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7025    (clobber (reg:CC FLAGS_REG))]
7026   "TARGET_QIMODE_MATH
7027    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7028   "imul{b}\t%2"
7029   [(set_attr "type" "imul")
7030    (set_attr "length_immediate" "0")
7031    (set (attr "athlon_decode")
7032      (if_then_else (eq_attr "cpu" "athlon")
7033         (const_string "vector")
7034         (const_string "direct")))
7035    (set_attr "mode" "QI")])
7037 (define_expand "umulditi3"
7038   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7039                    (mult:TI (zero_extend:TI
7040                               (match_operand:DI 1 "nonimmediate_operand" ""))
7041                             (zero_extend:TI
7042                               (match_operand:DI 2 "register_operand" ""))))
7043               (clobber (reg:CC FLAGS_REG))])]
7044   "TARGET_64BIT"
7045   "")
7047 (define_insn "*umulditi3_insn"
7048   [(set (match_operand:TI 0 "register_operand" "=A")
7049         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7050                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7051    (clobber (reg:CC FLAGS_REG))]
7052   "TARGET_64BIT
7053    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054   "mul{q}\t%2"
7055   [(set_attr "type" "imul")
7056    (set_attr "length_immediate" "0")
7057    (set (attr "athlon_decode")
7058      (if_then_else (eq_attr "cpu" "athlon")
7059         (const_string "vector")
7060         (const_string "double")))
7061    (set_attr "mode" "DI")])
7063 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7064 (define_expand "umulsidi3"
7065   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7066                    (mult:DI (zero_extend:DI
7067                               (match_operand:SI 1 "nonimmediate_operand" ""))
7068                             (zero_extend:DI
7069                               (match_operand:SI 2 "register_operand" ""))))
7070               (clobber (reg:CC FLAGS_REG))])]
7071   "!TARGET_64BIT"
7072   "")
7074 (define_insn "*umulsidi3_insn"
7075   [(set (match_operand:DI 0 "register_operand" "=A")
7076         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7077                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7078    (clobber (reg:CC FLAGS_REG))]
7079   "!TARGET_64BIT
7080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081   "mul{l}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "length_immediate" "0")
7084    (set (attr "athlon_decode")
7085      (if_then_else (eq_attr "cpu" "athlon")
7086         (const_string "vector")
7087         (const_string "double")))
7088    (set_attr "mode" "SI")])
7090 (define_expand "mulditi3"
7091   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7092                    (mult:TI (sign_extend:TI
7093                               (match_operand:DI 1 "nonimmediate_operand" ""))
7094                             (sign_extend:TI
7095                               (match_operand:DI 2 "register_operand" ""))))
7096               (clobber (reg:CC FLAGS_REG))])]
7097   "TARGET_64BIT"
7098   "")
7100 (define_insn "*mulditi3_insn"
7101   [(set (match_operand:TI 0 "register_operand" "=A")
7102         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7103                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "TARGET_64BIT
7106    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107   "imul{q}\t%2"
7108   [(set_attr "type" "imul")
7109    (set_attr "length_immediate" "0")
7110    (set (attr "athlon_decode")
7111      (if_then_else (eq_attr "cpu" "athlon")
7112         (const_string "vector")
7113         (const_string "double")))
7114    (set_attr "mode" "DI")])
7116 (define_expand "mulsidi3"
7117   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7118                    (mult:DI (sign_extend:DI
7119                               (match_operand:SI 1 "nonimmediate_operand" ""))
7120                             (sign_extend:DI
7121                               (match_operand:SI 2 "register_operand" ""))))
7122               (clobber (reg:CC FLAGS_REG))])]
7123   "!TARGET_64BIT"
7124   "")
7126 (define_insn "*mulsidi3_insn"
7127   [(set (match_operand:DI 0 "register_operand" "=A")
7128         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7129                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "!TARGET_64BIT
7132    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7133   "imul{l}\t%2"
7134   [(set_attr "type" "imul")
7135    (set_attr "length_immediate" "0")
7136    (set (attr "athlon_decode")
7137      (if_then_else (eq_attr "cpu" "athlon")
7138         (const_string "vector")
7139         (const_string "double")))
7140    (set_attr "mode" "SI")])
7142 (define_expand "umuldi3_highpart"
7143   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7144                    (truncate:DI
7145                      (lshiftrt:TI
7146                        (mult:TI (zero_extend:TI
7147                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7148                                 (zero_extend:TI
7149                                   (match_operand:DI 2 "register_operand" "")))
7150                        (const_int 64))))
7151               (clobber (match_scratch:DI 3 ""))
7152               (clobber (reg:CC FLAGS_REG))])]
7153   "TARGET_64BIT"
7154   "")
7156 (define_insn "*umuldi3_highpart_rex64"
7157   [(set (match_operand:DI 0 "register_operand" "=d")
7158         (truncate:DI
7159           (lshiftrt:TI
7160             (mult:TI (zero_extend:TI
7161                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7162                      (zero_extend:TI
7163                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7164             (const_int 64))))
7165    (clobber (match_scratch:DI 3 "=1"))
7166    (clobber (reg:CC FLAGS_REG))]
7167   "TARGET_64BIT
7168    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7169   "mul{q}\t%2"
7170   [(set_attr "type" "imul")
7171    (set_attr "length_immediate" "0")
7172    (set (attr "athlon_decode")
7173      (if_then_else (eq_attr "cpu" "athlon")
7174         (const_string "vector")
7175         (const_string "double")))
7176    (set_attr "mode" "DI")])
7178 (define_expand "umulsi3_highpart"
7179   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7180                    (truncate:SI
7181                      (lshiftrt:DI
7182                        (mult:DI (zero_extend:DI
7183                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7184                                 (zero_extend:DI
7185                                   (match_operand:SI 2 "register_operand" "")))
7186                        (const_int 32))))
7187               (clobber (match_scratch:SI 3 ""))
7188               (clobber (reg:CC FLAGS_REG))])]
7189   ""
7190   "")
7192 (define_insn "*umulsi3_highpart_insn"
7193   [(set (match_operand:SI 0 "register_operand" "=d")
7194         (truncate:SI
7195           (lshiftrt:DI
7196             (mult:DI (zero_extend:DI
7197                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7198                      (zero_extend:DI
7199                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7200             (const_int 32))))
7201    (clobber (match_scratch:SI 3 "=1"))
7202    (clobber (reg:CC FLAGS_REG))]
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_insn "*umulsi3_highpart_zext"
7214   [(set (match_operand:DI 0 "register_operand" "=d")
7215         (zero_extend:DI (truncate:SI
7216           (lshiftrt:DI
7217             (mult:DI (zero_extend:DI
7218                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7219                      (zero_extend:DI
7220                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7221             (const_int 32)))))
7222    (clobber (match_scratch:SI 3 "=1"))
7223    (clobber (reg:CC FLAGS_REG))]
7224   "TARGET_64BIT
7225    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7226   "mul{l}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "SI")])
7235 (define_expand "smuldi3_highpart"
7236   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7237                    (truncate:DI
7238                      (lshiftrt:TI
7239                        (mult:TI (sign_extend:TI
7240                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7241                                 (sign_extend:TI
7242                                   (match_operand:DI 2 "register_operand" "")))
7243                        (const_int 64))))
7244               (clobber (match_scratch:DI 3 ""))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   "TARGET_64BIT"
7247   "")
7249 (define_insn "*smuldi3_highpart_rex64"
7250   [(set (match_operand:DI 0 "register_operand" "=d")
7251         (truncate:DI
7252           (lshiftrt:TI
7253             (mult:TI (sign_extend:TI
7254                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7255                      (sign_extend:TI
7256                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7257             (const_int 64))))
7258    (clobber (match_scratch:DI 3 "=1"))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "TARGET_64BIT
7261    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7262   "imul{q}\t%2"
7263   [(set_attr "type" "imul")
7264    (set (attr "athlon_decode")
7265      (if_then_else (eq_attr "cpu" "athlon")
7266         (const_string "vector")
7267         (const_string "double")))
7268    (set_attr "mode" "DI")])
7270 (define_expand "smulsi3_highpart"
7271   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7272                    (truncate:SI
7273                      (lshiftrt:DI
7274                        (mult:DI (sign_extend:DI
7275                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7276                                 (sign_extend:DI
7277                                   (match_operand:SI 2 "register_operand" "")))
7278                        (const_int 32))))
7279               (clobber (match_scratch:SI 3 ""))
7280               (clobber (reg:CC FLAGS_REG))])]
7281   ""
7282   "")
7284 (define_insn "*smulsi3_highpart_insn"
7285   [(set (match_operand:SI 0 "register_operand" "=d")
7286         (truncate:SI
7287           (lshiftrt:DI
7288             (mult:DI (sign_extend:DI
7289                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7290                      (sign_extend:DI
7291                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7292             (const_int 32))))
7293    (clobber (match_scratch:SI 3 "=1"))
7294    (clobber (reg:CC FLAGS_REG))]
7295   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7296   "imul{l}\t%2"
7297   [(set_attr "type" "imul")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "double")))
7302    (set_attr "mode" "SI")])
7304 (define_insn "*smulsi3_highpart_zext"
7305   [(set (match_operand:DI 0 "register_operand" "=d")
7306         (zero_extend:DI (truncate:SI
7307           (lshiftrt:DI
7308             (mult:DI (sign_extend:DI
7309                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7310                      (sign_extend:DI
7311                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7312             (const_int 32)))))
7313    (clobber (match_scratch:SI 3 "=1"))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT
7316    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317   "imul{l}\t%2"
7318   [(set_attr "type" "imul")
7319    (set (attr "athlon_decode")
7320      (if_then_else (eq_attr "cpu" "athlon")
7321         (const_string "vector")
7322         (const_string "double")))
7323    (set_attr "mode" "SI")])
7325 ;; The patterns that match these are at the end of this file.
7327 (define_expand "mulxf3"
7328   [(set (match_operand:XF 0 "register_operand" "")
7329         (mult:XF (match_operand:XF 1 "register_operand" "")
7330                  (match_operand:XF 2 "register_operand" "")))]
7331   "TARGET_80387"
7332   "")
7334 (define_expand "muldf3"
7335   [(set (match_operand:DF 0 "register_operand" "")
7336         (mult:DF (match_operand:DF 1 "register_operand" "")
7337                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7338   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7339   "")
7341 (define_expand "mulsf3"
7342   [(set (match_operand:SF 0 "register_operand" "")
7343         (mult:SF (match_operand:SF 1 "register_operand" "")
7344                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7345   "TARGET_80387 || TARGET_SSE_MATH"
7346   "")
7348 ;; Divide instructions
7350 (define_insn "divqi3"
7351   [(set (match_operand:QI 0 "register_operand" "=a")
7352         (div:QI (match_operand:HI 1 "register_operand" "0")
7353                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7354    (clobber (reg:CC FLAGS_REG))]
7355   "TARGET_QIMODE_MATH"
7356   "idiv{b}\t%2"
7357   [(set_attr "type" "idiv")
7358    (set_attr "mode" "QI")])
7360 (define_insn "udivqi3"
7361   [(set (match_operand:QI 0 "register_operand" "=a")
7362         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7363                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7364    (clobber (reg:CC FLAGS_REG))]
7365   "TARGET_QIMODE_MATH"
7366   "div{b}\t%2"
7367   [(set_attr "type" "idiv")
7368    (set_attr "mode" "QI")])
7370 ;; The patterns that match these are at the end of this file.
7372 (define_expand "divxf3"
7373   [(set (match_operand:XF 0 "register_operand" "")
7374         (div:XF (match_operand:XF 1 "register_operand" "")
7375                 (match_operand:XF 2 "register_operand" "")))]
7376   "TARGET_80387"
7377   "")
7379 (define_expand "divdf3"
7380   [(set (match_operand:DF 0 "register_operand" "")
7381         (div:DF (match_operand:DF 1 "register_operand" "")
7382                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7383    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7384    "")
7386 (define_expand "divsf3"
7387   [(set (match_operand:SF 0 "register_operand" "")
7388         (div:SF (match_operand:SF 1 "register_operand" "")
7389                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7390   "TARGET_80387 || TARGET_SSE_MATH"
7391   "")
7393 ;; Remainder instructions.
7395 (define_expand "divmoddi4"
7396   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7397                    (div:DI (match_operand:DI 1 "register_operand" "")
7398                            (match_operand:DI 2 "nonimmediate_operand" "")))
7399               (set (match_operand:DI 3 "register_operand" "")
7400                    (mod:DI (match_dup 1) (match_dup 2)))
7401               (clobber (reg:CC FLAGS_REG))])]
7402   "TARGET_64BIT"
7403   "")
7405 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7406 ;; Penalize eax case slightly because it results in worse scheduling
7407 ;; of code.
7408 (define_insn "*divmoddi4_nocltd_rex64"
7409   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7410         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7411                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7412    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7413         (mod:DI (match_dup 2) (match_dup 3)))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7416   "#"
7417   [(set_attr "type" "multi")])
7419 (define_insn "*divmoddi4_cltd_rex64"
7420   [(set (match_operand:DI 0 "register_operand" "=a")
7421         (div:DI (match_operand:DI 2 "register_operand" "a")
7422                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7423    (set (match_operand:DI 1 "register_operand" "=&d")
7424         (mod:DI (match_dup 2) (match_dup 3)))
7425    (clobber (reg:CC FLAGS_REG))]
7426   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7427   "#"
7428   [(set_attr "type" "multi")])
7430 (define_insn "*divmoddi_noext_rex64"
7431   [(set (match_operand:DI 0 "register_operand" "=a")
7432         (div:DI (match_operand:DI 1 "register_operand" "0")
7433                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7434    (set (match_operand:DI 3 "register_operand" "=d")
7435         (mod:DI (match_dup 1) (match_dup 2)))
7436    (use (match_operand:DI 4 "register_operand" "3"))
7437    (clobber (reg:CC FLAGS_REG))]
7438   "TARGET_64BIT"
7439   "idiv{q}\t%2"
7440   [(set_attr "type" "idiv")
7441    (set_attr "mode" "DI")])
7443 (define_split
7444   [(set (match_operand:DI 0 "register_operand" "")
7445         (div:DI (match_operand:DI 1 "register_operand" "")
7446                 (match_operand:DI 2 "nonimmediate_operand" "")))
7447    (set (match_operand:DI 3 "register_operand" "")
7448         (mod:DI (match_dup 1) (match_dup 2)))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT && reload_completed"
7451   [(parallel [(set (match_dup 3)
7452                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7453               (clobber (reg:CC FLAGS_REG))])
7454    (parallel [(set (match_dup 0)
7455                    (div:DI (reg:DI 0) (match_dup 2)))
7456               (set (match_dup 3)
7457                    (mod:DI (reg:DI 0) (match_dup 2)))
7458               (use (match_dup 3))
7459               (clobber (reg:CC FLAGS_REG))])]
7461   /* Avoid use of cltd in favor of a mov+shift.  */
7462   if (!TARGET_USE_CLTD && !optimize_size)
7463     {
7464       if (true_regnum (operands[1]))
7465         emit_move_insn (operands[0], operands[1]);
7466       else
7467         emit_move_insn (operands[3], operands[1]);
7468       operands[4] = operands[3];
7469     }
7470   else
7471     {
7472       gcc_assert (!true_regnum (operands[1]));
7473       operands[4] = operands[1];
7474     }
7478 (define_expand "divmodsi4"
7479   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7480                    (div:SI (match_operand:SI 1 "register_operand" "")
7481                            (match_operand:SI 2 "nonimmediate_operand" "")))
7482               (set (match_operand:SI 3 "register_operand" "")
7483                    (mod:SI (match_dup 1) (match_dup 2)))
7484               (clobber (reg:CC FLAGS_REG))])]
7485   ""
7486   "")
7488 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7489 ;; Penalize eax case slightly because it results in worse scheduling
7490 ;; of code.
7491 (define_insn "*divmodsi4_nocltd"
7492   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7493         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7494                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7495    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7496         (mod:SI (match_dup 2) (match_dup 3)))
7497    (clobber (reg:CC FLAGS_REG))]
7498   "!optimize_size && !TARGET_USE_CLTD"
7499   "#"
7500   [(set_attr "type" "multi")])
7502 (define_insn "*divmodsi4_cltd"
7503   [(set (match_operand:SI 0 "register_operand" "=a")
7504         (div:SI (match_operand:SI 2 "register_operand" "a")
7505                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7506    (set (match_operand:SI 1 "register_operand" "=&d")
7507         (mod:SI (match_dup 2) (match_dup 3)))
7508    (clobber (reg:CC FLAGS_REG))]
7509   "optimize_size || TARGET_USE_CLTD"
7510   "#"
7511   [(set_attr "type" "multi")])
7513 (define_insn "*divmodsi_noext"
7514   [(set (match_operand:SI 0 "register_operand" "=a")
7515         (div:SI (match_operand:SI 1 "register_operand" "0")
7516                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7517    (set (match_operand:SI 3 "register_operand" "=d")
7518         (mod:SI (match_dup 1) (match_dup 2)))
7519    (use (match_operand:SI 4 "register_operand" "3"))
7520    (clobber (reg:CC FLAGS_REG))]
7521   ""
7522   "idiv{l}\t%2"
7523   [(set_attr "type" "idiv")
7524    (set_attr "mode" "SI")])
7526 (define_split
7527   [(set (match_operand:SI 0 "register_operand" "")
7528         (div:SI (match_operand:SI 1 "register_operand" "")
7529                 (match_operand:SI 2 "nonimmediate_operand" "")))
7530    (set (match_operand:SI 3 "register_operand" "")
7531         (mod:SI (match_dup 1) (match_dup 2)))
7532    (clobber (reg:CC FLAGS_REG))]
7533   "reload_completed"
7534   [(parallel [(set (match_dup 3)
7535                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7536               (clobber (reg:CC FLAGS_REG))])
7537    (parallel [(set (match_dup 0)
7538                    (div:SI (reg:SI 0) (match_dup 2)))
7539               (set (match_dup 3)
7540                    (mod:SI (reg:SI 0) (match_dup 2)))
7541               (use (match_dup 3))
7542               (clobber (reg:CC FLAGS_REG))])]
7544   /* Avoid use of cltd in favor of a mov+shift.  */
7545   if (!TARGET_USE_CLTD && !optimize_size)
7546     {
7547       if (true_regnum (operands[1]))
7548         emit_move_insn (operands[0], operands[1]);
7549       else
7550         emit_move_insn (operands[3], operands[1]);
7551       operands[4] = operands[3];
7552     }
7553   else
7554     {
7555       gcc_assert (!true_regnum (operands[1]));
7556       operands[4] = operands[1];
7557     }
7559 ;; %%% Split me.
7560 (define_insn "divmodhi4"
7561   [(set (match_operand:HI 0 "register_operand" "=a")
7562         (div:HI (match_operand:HI 1 "register_operand" "0")
7563                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7564    (set (match_operand:HI 3 "register_operand" "=&d")
7565         (mod:HI (match_dup 1) (match_dup 2)))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_HIMODE_MATH"
7568   "cwtd\;idiv{w}\t%2"
7569   [(set_attr "type" "multi")
7570    (set_attr "length_immediate" "0")
7571    (set_attr "mode" "SI")])
7573 (define_insn "udivmoddi4"
7574   [(set (match_operand:DI 0 "register_operand" "=a")
7575         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7576                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7577    (set (match_operand:DI 3 "register_operand" "=&d")
7578         (umod:DI (match_dup 1) (match_dup 2)))
7579    (clobber (reg:CC FLAGS_REG))]
7580   "TARGET_64BIT"
7581   "xor{q}\t%3, %3\;div{q}\t%2"
7582   [(set_attr "type" "multi")
7583    (set_attr "length_immediate" "0")
7584    (set_attr "mode" "DI")])
7586 (define_insn "*udivmoddi4_noext"
7587   [(set (match_operand:DI 0 "register_operand" "=a")
7588         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7589                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7590    (set (match_operand:DI 3 "register_operand" "=d")
7591         (umod:DI (match_dup 1) (match_dup 2)))
7592    (use (match_dup 3))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "TARGET_64BIT"
7595   "div{q}\t%2"
7596   [(set_attr "type" "idiv")
7597    (set_attr "mode" "DI")])
7599 (define_split
7600   [(set (match_operand:DI 0 "register_operand" "")
7601         (udiv:DI (match_operand:DI 1 "register_operand" "")
7602                  (match_operand:DI 2 "nonimmediate_operand" "")))
7603    (set (match_operand:DI 3 "register_operand" "")
7604         (umod:DI (match_dup 1) (match_dup 2)))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "TARGET_64BIT && reload_completed"
7607   [(set (match_dup 3) (const_int 0))
7608    (parallel [(set (match_dup 0)
7609                    (udiv:DI (match_dup 1) (match_dup 2)))
7610               (set (match_dup 3)
7611                    (umod:DI (match_dup 1) (match_dup 2)))
7612               (use (match_dup 3))
7613               (clobber (reg:CC FLAGS_REG))])]
7614   "")
7616 (define_insn "udivmodsi4"
7617   [(set (match_operand:SI 0 "register_operand" "=a")
7618         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7619                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7620    (set (match_operand:SI 3 "register_operand" "=&d")
7621         (umod:SI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   ""
7624   "xor{l}\t%3, %3\;div{l}\t%2"
7625   [(set_attr "type" "multi")
7626    (set_attr "length_immediate" "0")
7627    (set_attr "mode" "SI")])
7629 (define_insn "*udivmodsi4_noext"
7630   [(set (match_operand:SI 0 "register_operand" "=a")
7631         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7632                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7633    (set (match_operand:SI 3 "register_operand" "=d")
7634         (umod:SI (match_dup 1) (match_dup 2)))
7635    (use (match_dup 3))
7636    (clobber (reg:CC FLAGS_REG))]
7637   ""
7638   "div{l}\t%2"
7639   [(set_attr "type" "idiv")
7640    (set_attr "mode" "SI")])
7642 (define_split
7643   [(set (match_operand:SI 0 "register_operand" "")
7644         (udiv:SI (match_operand:SI 1 "register_operand" "")
7645                  (match_operand:SI 2 "nonimmediate_operand" "")))
7646    (set (match_operand:SI 3 "register_operand" "")
7647         (umod:SI (match_dup 1) (match_dup 2)))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "reload_completed"
7650   [(set (match_dup 3) (const_int 0))
7651    (parallel [(set (match_dup 0)
7652                    (udiv:SI (match_dup 1) (match_dup 2)))
7653               (set (match_dup 3)
7654                    (umod:SI (match_dup 1) (match_dup 2)))
7655               (use (match_dup 3))
7656               (clobber (reg:CC FLAGS_REG))])]
7657   "")
7659 (define_expand "udivmodhi4"
7660   [(set (match_dup 4) (const_int 0))
7661    (parallel [(set (match_operand:HI 0 "register_operand" "")
7662                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7663                             (match_operand:HI 2 "nonimmediate_operand" "")))
7664               (set (match_operand:HI 3 "register_operand" "")
7665                    (umod:HI (match_dup 1) (match_dup 2)))
7666               (use (match_dup 4))
7667               (clobber (reg:CC FLAGS_REG))])]
7668   "TARGET_HIMODE_MATH"
7669   "operands[4] = gen_reg_rtx (HImode);")
7671 (define_insn "*udivmodhi_noext"
7672   [(set (match_operand:HI 0 "register_operand" "=a")
7673         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7674                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7675    (set (match_operand:HI 3 "register_operand" "=d")
7676         (umod:HI (match_dup 1) (match_dup 2)))
7677    (use (match_operand:HI 4 "register_operand" "3"))
7678    (clobber (reg:CC FLAGS_REG))]
7679   ""
7680   "div{w}\t%2"
7681   [(set_attr "type" "idiv")
7682    (set_attr "mode" "HI")])
7684 ;; We cannot use div/idiv for double division, because it causes
7685 ;; "division by zero" on the overflow and that's not what we expect
7686 ;; from truncate.  Because true (non truncating) double division is
7687 ;; never generated, we can't create this insn anyway.
7689 ;(define_insn ""
7690 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7691 ;       (truncate:SI
7692 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7693 ;                  (zero_extend:DI
7694 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7695 ;   (set (match_operand:SI 3 "register_operand" "=d")
7696 ;       (truncate:SI
7697 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7698 ;   (clobber (reg:CC FLAGS_REG))]
7699 ;  ""
7700 ;  "div{l}\t{%2, %0|%0, %2}"
7701 ;  [(set_attr "type" "idiv")])
7703 ;;- Logical AND instructions
7705 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7706 ;; Note that this excludes ah.
7708 (define_insn "*testdi_1_rex64"
7709   [(set (reg FLAGS_REG)
7710         (compare
7711           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7712                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7713           (const_int 0)))]
7714   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7715    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7716   "@
7717    test{l}\t{%k1, %k0|%k0, %k1}
7718    test{l}\t{%k1, %k0|%k0, %k1}
7719    test{q}\t{%1, %0|%0, %1}
7720    test{q}\t{%1, %0|%0, %1}
7721    test{q}\t{%1, %0|%0, %1}"
7722   [(set_attr "type" "test")
7723    (set_attr "modrm" "0,1,0,1,1")
7724    (set_attr "mode" "SI,SI,DI,DI,DI")
7725    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7727 (define_insn "testsi_1"
7728   [(set (reg FLAGS_REG)
7729         (compare
7730           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7731                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7732           (const_int 0)))]
7733   "ix86_match_ccmode (insn, CCNOmode)
7734    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7735   "test{l}\t{%1, %0|%0, %1}"
7736   [(set_attr "type" "test")
7737    (set_attr "modrm" "0,1,1")
7738    (set_attr "mode" "SI")
7739    (set_attr "pent_pair" "uv,np,uv")])
7741 (define_expand "testsi_ccno_1"
7742   [(set (reg:CCNO FLAGS_REG)
7743         (compare:CCNO
7744           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7745                   (match_operand:SI 1 "nonmemory_operand" ""))
7746           (const_int 0)))]
7747   ""
7748   "")
7750 (define_insn "*testhi_1"
7751   [(set (reg FLAGS_REG)
7752         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7753                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7754                  (const_int 0)))]
7755   "ix86_match_ccmode (insn, CCNOmode)
7756    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7757   "test{w}\t{%1, %0|%0, %1}"
7758   [(set_attr "type" "test")
7759    (set_attr "modrm" "0,1,1")
7760    (set_attr "mode" "HI")
7761    (set_attr "pent_pair" "uv,np,uv")])
7763 (define_expand "testqi_ccz_1"
7764   [(set (reg:CCZ FLAGS_REG)
7765         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7766                              (match_operand:QI 1 "nonmemory_operand" ""))
7767                  (const_int 0)))]
7768   ""
7769   "")
7771 (define_insn "*testqi_1_maybe_si"
7772   [(set (reg FLAGS_REG)
7773         (compare
7774           (and:QI
7775             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7776             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7777           (const_int 0)))]
7778    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7779     && ix86_match_ccmode (insn,
7780                          GET_CODE (operands[1]) == CONST_INT
7781                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7783   if (which_alternative == 3)
7784     {
7785       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7786         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7787       return "test{l}\t{%1, %k0|%k0, %1}";
7788     }
7789   return "test{b}\t{%1, %0|%0, %1}";
7791   [(set_attr "type" "test")
7792    (set_attr "modrm" "0,1,1,1")
7793    (set_attr "mode" "QI,QI,QI,SI")
7794    (set_attr "pent_pair" "uv,np,uv,np")])
7796 (define_insn "*testqi_1"
7797   [(set (reg FLAGS_REG)
7798         (compare
7799           (and:QI
7800             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7801             (match_operand:QI 1 "general_operand" "n,n,qn"))
7802           (const_int 0)))]
7803   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7804    && ix86_match_ccmode (insn, CCNOmode)"
7805   "test{b}\t{%1, %0|%0, %1}"
7806   [(set_attr "type" "test")
7807    (set_attr "modrm" "0,1,1")
7808    (set_attr "mode" "QI")
7809    (set_attr "pent_pair" "uv,np,uv")])
7811 (define_expand "testqi_ext_ccno_0"
7812   [(set (reg:CCNO FLAGS_REG)
7813         (compare:CCNO
7814           (and:SI
7815             (zero_extract:SI
7816               (match_operand 0 "ext_register_operand" "")
7817               (const_int 8)
7818               (const_int 8))
7819             (match_operand 1 "const_int_operand" ""))
7820           (const_int 0)))]
7821   ""
7822   "")
7824 (define_insn "*testqi_ext_0"
7825   [(set (reg FLAGS_REG)
7826         (compare
7827           (and:SI
7828             (zero_extract:SI
7829               (match_operand 0 "ext_register_operand" "Q")
7830               (const_int 8)
7831               (const_int 8))
7832             (match_operand 1 "const_int_operand" "n"))
7833           (const_int 0)))]
7834   "ix86_match_ccmode (insn, CCNOmode)"
7835   "test{b}\t{%1, %h0|%h0, %1}"
7836   [(set_attr "type" "test")
7837    (set_attr "mode" "QI")
7838    (set_attr "length_immediate" "1")
7839    (set_attr "pent_pair" "np")])
7841 (define_insn "*testqi_ext_1"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (zero_extend:SI
7850               (match_operand:QI 1 "general_operand" "Qm")))
7851           (const_int 0)))]
7852   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7853    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7854   "test{b}\t{%1, %h0|%h0, %1}"
7855   [(set_attr "type" "test")
7856    (set_attr "mode" "QI")])
7858 (define_insn "*testqi_ext_1_rex64"
7859   [(set (reg FLAGS_REG)
7860         (compare
7861           (and:SI
7862             (zero_extract:SI
7863               (match_operand 0 "ext_register_operand" "Q")
7864               (const_int 8)
7865               (const_int 8))
7866             (zero_extend:SI
7867               (match_operand:QI 1 "register_operand" "Q")))
7868           (const_int 0)))]
7869   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7870   "test{b}\t{%1, %h0|%h0, %1}"
7871   [(set_attr "type" "test")
7872    (set_attr "mode" "QI")])
7874 (define_insn "*testqi_ext_2"
7875   [(set (reg FLAGS_REG)
7876         (compare
7877           (and:SI
7878             (zero_extract:SI
7879               (match_operand 0 "ext_register_operand" "Q")
7880               (const_int 8)
7881               (const_int 8))
7882             (zero_extract:SI
7883               (match_operand 1 "ext_register_operand" "Q")
7884               (const_int 8)
7885               (const_int 8)))
7886           (const_int 0)))]
7887   "ix86_match_ccmode (insn, CCNOmode)"
7888   "test{b}\t{%h1, %h0|%h0, %h1}"
7889   [(set_attr "type" "test")
7890    (set_attr "mode" "QI")])
7892 ;; Combine likes to form bit extractions for some tests.  Humor it.
7893 (define_insn "*testqi_ext_3"
7894   [(set (reg FLAGS_REG)
7895         (compare (zero_extract:SI
7896                    (match_operand 0 "nonimmediate_operand" "rm")
7897                    (match_operand:SI 1 "const_int_operand" "")
7898                    (match_operand:SI 2 "const_int_operand" ""))
7899                  (const_int 0)))]
7900   "ix86_match_ccmode (insn, CCNOmode)
7901    && INTVAL (operands[1]) > 0
7902    && INTVAL (operands[2]) >= 0
7903    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7904    && (GET_MODE (operands[0]) == SImode
7905        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7906        || GET_MODE (operands[0]) == HImode
7907        || GET_MODE (operands[0]) == QImode)"
7908   "#")
7910 (define_insn "*testqi_ext_3_rex64"
7911   [(set (reg FLAGS_REG)
7912         (compare (zero_extract:DI
7913                    (match_operand 0 "nonimmediate_operand" "rm")
7914                    (match_operand:DI 1 "const_int_operand" "")
7915                    (match_operand:DI 2 "const_int_operand" ""))
7916                  (const_int 0)))]
7917   "TARGET_64BIT
7918    && ix86_match_ccmode (insn, CCNOmode)
7919    && INTVAL (operands[1]) > 0
7920    && INTVAL (operands[2]) >= 0
7921    /* Ensure that resulting mask is zero or sign extended operand.  */
7922    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7923        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7924            && INTVAL (operands[1]) > 32))
7925    && (GET_MODE (operands[0]) == SImode
7926        || GET_MODE (operands[0]) == DImode
7927        || GET_MODE (operands[0]) == HImode
7928        || GET_MODE (operands[0]) == QImode)"
7929   "#")
7931 (define_split
7932   [(set (match_operand 0 "flags_reg_operand" "")
7933         (match_operator 1 "compare_operator"
7934           [(zero_extract
7935              (match_operand 2 "nonimmediate_operand" "")
7936              (match_operand 3 "const_int_operand" "")
7937              (match_operand 4 "const_int_operand" ""))
7938            (const_int 0)]))]
7939   "ix86_match_ccmode (insn, CCNOmode)"
7940   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7942   rtx val = operands[2];
7943   HOST_WIDE_INT len = INTVAL (operands[3]);
7944   HOST_WIDE_INT pos = INTVAL (operands[4]);
7945   HOST_WIDE_INT mask;
7946   enum machine_mode mode, submode;
7948   mode = GET_MODE (val);
7949   if (GET_CODE (val) == MEM)
7950     {
7951       /* ??? Combine likes to put non-volatile mem extractions in QImode
7952          no matter the size of the test.  So find a mode that works.  */
7953       if (! MEM_VOLATILE_P (val))
7954         {
7955           mode = smallest_mode_for_size (pos + len, MODE_INT);
7956           val = adjust_address (val, mode, 0);
7957         }
7958     }
7959   else if (GET_CODE (val) == SUBREG
7960            && (submode = GET_MODE (SUBREG_REG (val)),
7961                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7962            && pos + len <= GET_MODE_BITSIZE (submode))
7963     {
7964       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7965       mode = submode;
7966       val = SUBREG_REG (val);
7967     }
7968   else if (mode == HImode && pos + len <= 8)
7969     {
7970       /* Small HImode tests can be converted to QImode.  */
7971       mode = QImode;
7972       val = gen_lowpart (QImode, val);
7973     }
7975   if (len == HOST_BITS_PER_WIDE_INT)
7976     mask = -1;
7977   else
7978     mask = ((HOST_WIDE_INT)1 << len) - 1;
7979   mask <<= pos;
7981   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7984 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7985 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7986 ;; this is relatively important trick.
7987 ;; Do the conversion only post-reload to avoid limiting of the register class
7988 ;; to QI regs.
7989 (define_split
7990   [(set (match_operand 0 "flags_reg_operand" "")
7991         (match_operator 1 "compare_operator"
7992           [(and (match_operand 2 "register_operand" "")
7993                 (match_operand 3 "const_int_operand" ""))
7994            (const_int 0)]))]
7995    "reload_completed
7996     && QI_REG_P (operands[2])
7997     && GET_MODE (operands[2]) != QImode
7998     && ((ix86_match_ccmode (insn, CCZmode)
7999          && !(INTVAL (operands[3]) & ~(255 << 8)))
8000         || (ix86_match_ccmode (insn, CCNOmode)
8001             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8002   [(set (match_dup 0)
8003         (match_op_dup 1
8004           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8005                    (match_dup 3))
8006            (const_int 0)]))]
8007   "operands[2] = gen_lowpart (SImode, operands[2]);
8008    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8010 (define_split
8011   [(set (match_operand 0 "flags_reg_operand" "")
8012         (match_operator 1 "compare_operator"
8013           [(and (match_operand 2 "nonimmediate_operand" "")
8014                 (match_operand 3 "const_int_operand" ""))
8015            (const_int 0)]))]
8016    "reload_completed
8017     && GET_MODE (operands[2]) != QImode
8018     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8019     && ((ix86_match_ccmode (insn, CCZmode)
8020          && !(INTVAL (operands[3]) & ~255))
8021         || (ix86_match_ccmode (insn, CCNOmode)
8022             && !(INTVAL (operands[3]) & ~127)))"
8023   [(set (match_dup 0)
8024         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8025                          (const_int 0)]))]
8026   "operands[2] = gen_lowpart (QImode, operands[2]);
8027    operands[3] = gen_lowpart (QImode, operands[3]);")
8030 ;; %%% This used to optimize known byte-wide and operations to memory,
8031 ;; and sometimes to QImode registers.  If this is considered useful,
8032 ;; it should be done with splitters.
8034 (define_expand "anddi3"
8035   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8036         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8037                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8038    (clobber (reg:CC FLAGS_REG))]
8039   "TARGET_64BIT"
8040   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8042 (define_insn "*anddi_1_rex64"
8043   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8044         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8045                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8046    (clobber (reg:CC FLAGS_REG))]
8047   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8049   switch (get_attr_type (insn))
8050     {
8051     case TYPE_IMOVX:
8052       {
8053         enum machine_mode mode;
8055         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8056         if (INTVAL (operands[2]) == 0xff)
8057           mode = QImode;
8058         else
8059           {
8060             gcc_assert (INTVAL (operands[2]) == 0xffff);
8061             mode = HImode;
8062           }
8063         
8064         operands[1] = gen_lowpart (mode, operands[1]);
8065         if (mode == QImode)
8066           return "movz{bq|x}\t{%1,%0|%0, %1}";
8067         else
8068           return "movz{wq|x}\t{%1,%0|%0, %1}";
8069       }
8071     default:
8072       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8073       if (get_attr_mode (insn) == MODE_SI)
8074         return "and{l}\t{%k2, %k0|%k0, %k2}";
8075       else
8076         return "and{q}\t{%2, %0|%0, %2}";
8077     }
8079   [(set_attr "type" "alu,alu,alu,imovx")
8080    (set_attr "length_immediate" "*,*,*,0")
8081    (set_attr "mode" "SI,DI,DI,DI")])
8083 (define_insn "*anddi_2"
8084   [(set (reg FLAGS_REG)
8085         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8086                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8087                  (const_int 0)))
8088    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8089         (and:DI (match_dup 1) (match_dup 2)))]
8090   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8091    && ix86_binary_operator_ok (AND, DImode, operands)"
8092   "@
8093    and{l}\t{%k2, %k0|%k0, %k2}
8094    and{q}\t{%2, %0|%0, %2}
8095    and{q}\t{%2, %0|%0, %2}"
8096   [(set_attr "type" "alu")
8097    (set_attr "mode" "SI,DI,DI")])
8099 (define_expand "andsi3"
8100   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8101         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8102                 (match_operand:SI 2 "general_operand" "")))
8103    (clobber (reg:CC FLAGS_REG))]
8104   ""
8105   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8107 (define_insn "*andsi_1"
8108   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8109         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8110                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8111    (clobber (reg:CC FLAGS_REG))]
8112   "ix86_binary_operator_ok (AND, SImode, operands)"
8114   switch (get_attr_type (insn))
8115     {
8116     case TYPE_IMOVX:
8117       {
8118         enum machine_mode mode;
8120         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8121         if (INTVAL (operands[2]) == 0xff)
8122           mode = QImode;
8123         else
8124           {
8125             gcc_assert (INTVAL (operands[2]) == 0xffff);
8126             mode = HImode;
8127           }
8128         
8129         operands[1] = gen_lowpart (mode, operands[1]);
8130         if (mode == QImode)
8131           return "movz{bl|x}\t{%1,%0|%0, %1}";
8132         else
8133           return "movz{wl|x}\t{%1,%0|%0, %1}";
8134       }
8136     default:
8137       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8138       return "and{l}\t{%2, %0|%0, %2}";
8139     }
8141   [(set_attr "type" "alu,alu,imovx")
8142    (set_attr "length_immediate" "*,*,0")
8143    (set_attr "mode" "SI")])
8145 (define_split
8146   [(set (match_operand 0 "register_operand" "")
8147         (and (match_dup 0)
8148              (const_int -65536)))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8151   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8152   "operands[1] = gen_lowpart (HImode, operands[0]);")
8154 (define_split
8155   [(set (match_operand 0 "ext_register_operand" "")
8156         (and (match_dup 0)
8157              (const_int -256)))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8160   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8161   "operands[1] = gen_lowpart (QImode, operands[0]);")
8163 (define_split
8164   [(set (match_operand 0 "ext_register_operand" "")
8165         (and (match_dup 0)
8166              (const_int -65281)))
8167    (clobber (reg:CC FLAGS_REG))]
8168   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8169   [(parallel [(set (zero_extract:SI (match_dup 0)
8170                                     (const_int 8)
8171                                     (const_int 8))
8172                    (xor:SI 
8173                      (zero_extract:SI (match_dup 0)
8174                                       (const_int 8)
8175                                       (const_int 8))
8176                      (zero_extract:SI (match_dup 0)
8177                                       (const_int 8)
8178                                       (const_int 8))))
8179               (clobber (reg:CC FLAGS_REG))])]
8180   "operands[0] = gen_lowpart (SImode, operands[0]);")
8182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8183 (define_insn "*andsi_1_zext"
8184   [(set (match_operand:DI 0 "register_operand" "=r")
8185         (zero_extend:DI
8186           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8187                   (match_operand:SI 2 "general_operand" "rim"))))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8190   "and{l}\t{%2, %k0|%k0, %2}"
8191   [(set_attr "type" "alu")
8192    (set_attr "mode" "SI")])
8194 (define_insn "*andsi_2"
8195   [(set (reg FLAGS_REG)
8196         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8197                          (match_operand:SI 2 "general_operand" "rim,ri"))
8198                  (const_int 0)))
8199    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8200         (and:SI (match_dup 1) (match_dup 2)))]
8201   "ix86_match_ccmode (insn, CCNOmode)
8202    && ix86_binary_operator_ok (AND, SImode, operands)"
8203   "and{l}\t{%2, %0|%0, %2}"
8204   [(set_attr "type" "alu")
8205    (set_attr "mode" "SI")])
8207 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8208 (define_insn "*andsi_2_zext"
8209   [(set (reg FLAGS_REG)
8210         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8211                          (match_operand:SI 2 "general_operand" "rim"))
8212                  (const_int 0)))
8213    (set (match_operand:DI 0 "register_operand" "=r")
8214         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8215   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8216    && ix86_binary_operator_ok (AND, SImode, operands)"
8217   "and{l}\t{%2, %k0|%k0, %2}"
8218   [(set_attr "type" "alu")
8219    (set_attr "mode" "SI")])
8221 (define_expand "andhi3"
8222   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8223         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8224                 (match_operand:HI 2 "general_operand" "")))
8225    (clobber (reg:CC FLAGS_REG))]
8226   "TARGET_HIMODE_MATH"
8227   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8229 (define_insn "*andhi_1"
8230   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8231         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8232                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "ix86_binary_operator_ok (AND, HImode, operands)"
8236   switch (get_attr_type (insn))
8237     {
8238     case TYPE_IMOVX:
8239       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8240       gcc_assert (INTVAL (operands[2]) == 0xff);
8241       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8243     default:
8244       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8246       return "and{w}\t{%2, %0|%0, %2}";
8247     }
8249   [(set_attr "type" "alu,alu,imovx")
8250    (set_attr "length_immediate" "*,*,0")
8251    (set_attr "mode" "HI,HI,SI")])
8253 (define_insn "*andhi_2"
8254   [(set (reg FLAGS_REG)
8255         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8256                          (match_operand:HI 2 "general_operand" "rim,ri"))
8257                  (const_int 0)))
8258    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8259         (and:HI (match_dup 1) (match_dup 2)))]
8260   "ix86_match_ccmode (insn, CCNOmode)
8261    && ix86_binary_operator_ok (AND, HImode, operands)"
8262   "and{w}\t{%2, %0|%0, %2}"
8263   [(set_attr "type" "alu")
8264    (set_attr "mode" "HI")])
8266 (define_expand "andqi3"
8267   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8268         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8269                 (match_operand:QI 2 "general_operand" "")))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "TARGET_QIMODE_MATH"
8272   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8274 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8275 (define_insn "*andqi_1"
8276   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8277         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8278                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8279    (clobber (reg:CC FLAGS_REG))]
8280   "ix86_binary_operator_ok (AND, QImode, operands)"
8281   "@
8282    and{b}\t{%2, %0|%0, %2}
8283    and{b}\t{%2, %0|%0, %2}
8284    and{l}\t{%k2, %k0|%k0, %k2}"
8285   [(set_attr "type" "alu")
8286    (set_attr "mode" "QI,QI,SI")])
8288 (define_insn "*andqi_1_slp"
8289   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8290         (and:QI (match_dup 0)
8291                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8292    (clobber (reg:CC FLAGS_REG))]
8293   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8294    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8295   "and{b}\t{%1, %0|%0, %1}"
8296   [(set_attr "type" "alu1")
8297    (set_attr "mode" "QI")])
8299 (define_insn "*andqi_2_maybe_si"
8300   [(set (reg FLAGS_REG)
8301         (compare (and:QI
8302                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8303                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8304                  (const_int 0)))
8305    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8306         (and:QI (match_dup 1) (match_dup 2)))]
8307   "ix86_binary_operator_ok (AND, QImode, operands)
8308    && ix86_match_ccmode (insn,
8309                          GET_CODE (operands[2]) == CONST_INT
8310                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8312   if (which_alternative == 2)
8313     {
8314       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8315         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8316       return "and{l}\t{%2, %k0|%k0, %2}";
8317     }
8318   return "and{b}\t{%2, %0|%0, %2}";
8320   [(set_attr "type" "alu")
8321    (set_attr "mode" "QI,QI,SI")])
8323 (define_insn "*andqi_2"
8324   [(set (reg FLAGS_REG)
8325         (compare (and:QI
8326                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8327                    (match_operand:QI 2 "general_operand" "qim,qi"))
8328                  (const_int 0)))
8329    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8330         (and:QI (match_dup 1) (match_dup 2)))]
8331   "ix86_match_ccmode (insn, CCNOmode)
8332    && ix86_binary_operator_ok (AND, QImode, operands)"
8333   "and{b}\t{%2, %0|%0, %2}"
8334   [(set_attr "type" "alu")
8335    (set_attr "mode" "QI")])
8337 (define_insn "*andqi_2_slp"
8338   [(set (reg FLAGS_REG)
8339         (compare (and:QI
8340                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8341                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8342                  (const_int 0)))
8343    (set (strict_low_part (match_dup 0))
8344         (and:QI (match_dup 0) (match_dup 1)))]
8345   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8346    && ix86_match_ccmode (insn, CCNOmode)
8347    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8348   "and{b}\t{%1, %0|%0, %1}"
8349   [(set_attr "type" "alu1")
8350    (set_attr "mode" "QI")])
8352 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8353 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8354 ;; for a QImode operand, which of course failed.
8356 (define_insn "andqi_ext_0"
8357   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8358                          (const_int 8)
8359                          (const_int 8))
8360         (and:SI 
8361           (zero_extract:SI
8362             (match_operand 1 "ext_register_operand" "0")
8363             (const_int 8)
8364             (const_int 8))
8365           (match_operand 2 "const_int_operand" "n")))
8366    (clobber (reg:CC FLAGS_REG))]
8367   ""
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 ;; Generated by peephole translating test to and.  This shows up
8374 ;; often in fp comparisons.
8376 (define_insn "*andqi_ext_0_cc"
8377   [(set (reg FLAGS_REG)
8378         (compare
8379           (and:SI
8380             (zero_extract:SI
8381               (match_operand 1 "ext_register_operand" "0")
8382               (const_int 8)
8383               (const_int 8))
8384             (match_operand 2 "const_int_operand" "n"))
8385           (const_int 0)))
8386    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8387                          (const_int 8)
8388                          (const_int 8))
8389         (and:SI 
8390           (zero_extract:SI
8391             (match_dup 1)
8392             (const_int 8)
8393             (const_int 8))
8394           (match_dup 2)))]
8395   "ix86_match_ccmode (insn, CCNOmode)"
8396   "and{b}\t{%2, %h0|%h0, %2}"
8397   [(set_attr "type" "alu")
8398    (set_attr "length_immediate" "1")
8399    (set_attr "mode" "QI")])
8401 (define_insn "*andqi_ext_1"
8402   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8403                          (const_int 8)
8404                          (const_int 8))
8405         (and:SI 
8406           (zero_extract:SI
8407             (match_operand 1 "ext_register_operand" "0")
8408             (const_int 8)
8409             (const_int 8))
8410           (zero_extend:SI
8411             (match_operand:QI 2 "general_operand" "Qm"))))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "!TARGET_64BIT"
8414   "and{b}\t{%2, %h0|%h0, %2}"
8415   [(set_attr "type" "alu")
8416    (set_attr "length_immediate" "0")
8417    (set_attr "mode" "QI")])
8419 (define_insn "*andqi_ext_1_rex64"
8420   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8421                          (const_int 8)
8422                          (const_int 8))
8423         (and:SI 
8424           (zero_extract:SI
8425             (match_operand 1 "ext_register_operand" "0")
8426             (const_int 8)
8427             (const_int 8))
8428           (zero_extend:SI
8429             (match_operand 2 "ext_register_operand" "Q"))))
8430    (clobber (reg:CC FLAGS_REG))]
8431   "TARGET_64BIT"
8432   "and{b}\t{%2, %h0|%h0, %2}"
8433   [(set_attr "type" "alu")
8434    (set_attr "length_immediate" "0")
8435    (set_attr "mode" "QI")])
8437 (define_insn "*andqi_ext_2"
8438   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8439                          (const_int 8)
8440                          (const_int 8))
8441         (and:SI
8442           (zero_extract:SI
8443             (match_operand 1 "ext_register_operand" "%0")
8444             (const_int 8)
8445             (const_int 8))
8446           (zero_extract:SI
8447             (match_operand 2 "ext_register_operand" "Q")
8448             (const_int 8)
8449             (const_int 8))))
8450    (clobber (reg:CC FLAGS_REG))]
8451   ""
8452   "and{b}\t{%h2, %h0|%h0, %h2}"
8453   [(set_attr "type" "alu")
8454    (set_attr "length_immediate" "0")
8455    (set_attr "mode" "QI")])
8457 ;; Convert wide AND instructions with immediate operand to shorter QImode
8458 ;; equivalents when possible.
8459 ;; Don't do the splitting with memory operands, since it introduces risk
8460 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8461 ;; for size, but that can (should?) be handled by generic code instead.
8462 (define_split
8463   [(set (match_operand 0 "register_operand" "")
8464         (and (match_operand 1 "register_operand" "")
8465              (match_operand 2 "const_int_operand" "")))
8466    (clobber (reg:CC FLAGS_REG))]
8467    "reload_completed
8468     && QI_REG_P (operands[0])
8469     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8470     && !(~INTVAL (operands[2]) & ~(255 << 8))
8471     && GET_MODE (operands[0]) != QImode"
8472   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8473                    (and:SI (zero_extract:SI (match_dup 1)
8474                                             (const_int 8) (const_int 8))
8475                            (match_dup 2)))
8476               (clobber (reg:CC FLAGS_REG))])]
8477   "operands[0] = gen_lowpart (SImode, operands[0]);
8478    operands[1] = gen_lowpart (SImode, operands[1]);
8479    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8481 ;; Since AND can be encoded with sign extended immediate, this is only
8482 ;; profitable when 7th bit is not set.
8483 (define_split
8484   [(set (match_operand 0 "register_operand" "")
8485         (and (match_operand 1 "general_operand" "")
8486              (match_operand 2 "const_int_operand" "")))
8487    (clobber (reg:CC FLAGS_REG))]
8488    "reload_completed
8489     && ANY_QI_REG_P (operands[0])
8490     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8491     && !(~INTVAL (operands[2]) & ~255)
8492     && !(INTVAL (operands[2]) & 128)
8493     && GET_MODE (operands[0]) != QImode"
8494   [(parallel [(set (strict_low_part (match_dup 0))
8495                    (and:QI (match_dup 1)
8496                            (match_dup 2)))
8497               (clobber (reg:CC FLAGS_REG))])]
8498   "operands[0] = gen_lowpart (QImode, operands[0]);
8499    operands[1] = gen_lowpart (QImode, operands[1]);
8500    operands[2] = gen_lowpart (QImode, operands[2]);")
8502 ;; Logical inclusive OR instructions
8504 ;; %%% This used to optimize known byte-wide and operations to memory.
8505 ;; If this is considered useful, it should be done with splitters.
8507 (define_expand "iordi3"
8508   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8509         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8510                 (match_operand:DI 2 "x86_64_general_operand" "")))
8511    (clobber (reg:CC FLAGS_REG))]
8512   "TARGET_64BIT"
8513   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8515 (define_insn "*iordi_1_rex64"
8516   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8517         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8518                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8519    (clobber (reg:CC FLAGS_REG))]
8520   "TARGET_64BIT
8521    && ix86_binary_operator_ok (IOR, DImode, operands)"
8522   "or{q}\t{%2, %0|%0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "DI")])
8526 (define_insn "*iordi_2_rex64"
8527   [(set (reg FLAGS_REG)
8528         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8529                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8530                  (const_int 0)))
8531    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8532         (ior:DI (match_dup 1) (match_dup 2)))]
8533   "TARGET_64BIT
8534    && ix86_match_ccmode (insn, CCNOmode)
8535    && ix86_binary_operator_ok (IOR, DImode, operands)"
8536   "or{q}\t{%2, %0|%0, %2}"
8537   [(set_attr "type" "alu")
8538    (set_attr "mode" "DI")])
8540 (define_insn "*iordi_3_rex64"
8541   [(set (reg FLAGS_REG)
8542         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8543                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8544                  (const_int 0)))
8545    (clobber (match_scratch:DI 0 "=r"))]
8546   "TARGET_64BIT
8547    && ix86_match_ccmode (insn, CCNOmode)
8548    && ix86_binary_operator_ok (IOR, DImode, operands)"
8549   "or{q}\t{%2, %0|%0, %2}"
8550   [(set_attr "type" "alu")
8551    (set_attr "mode" "DI")])
8554 (define_expand "iorsi3"
8555   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8556         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8557                 (match_operand:SI 2 "general_operand" "")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   ""
8560   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8562 (define_insn "*iorsi_1"
8563   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8564         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8565                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "ix86_binary_operator_ok (IOR, SImode, operands)"
8568   "or{l}\t{%2, %0|%0, %2}"
8569   [(set_attr "type" "alu")
8570    (set_attr "mode" "SI")])
8572 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8573 (define_insn "*iorsi_1_zext"
8574   [(set (match_operand:DI 0 "register_operand" "=rm")
8575         (zero_extend:DI
8576           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8577                   (match_operand:SI 2 "general_operand" "rim"))))
8578    (clobber (reg:CC FLAGS_REG))]
8579   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8580   "or{l}\t{%2, %k0|%k0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "mode" "SI")])
8584 (define_insn "*iorsi_1_zext_imm"
8585   [(set (match_operand:DI 0 "register_operand" "=rm")
8586         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8587                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8588    (clobber (reg:CC FLAGS_REG))]
8589   "TARGET_64BIT"
8590   "or{l}\t{%2, %k0|%k0, %2}"
8591   [(set_attr "type" "alu")
8592    (set_attr "mode" "SI")])
8594 (define_insn "*iorsi_2"
8595   [(set (reg FLAGS_REG)
8596         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8597                          (match_operand:SI 2 "general_operand" "rim,ri"))
8598                  (const_int 0)))
8599    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8600         (ior:SI (match_dup 1) (match_dup 2)))]
8601   "ix86_match_ccmode (insn, CCNOmode)
8602    && ix86_binary_operator_ok (IOR, SImode, operands)"
8603   "or{l}\t{%2, %0|%0, %2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "mode" "SI")])
8607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8608 ;; ??? Special case for immediate operand is missing - it is tricky.
8609 (define_insn "*iorsi_2_zext"
8610   [(set (reg FLAGS_REG)
8611         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8612                          (match_operand:SI 2 "general_operand" "rim"))
8613                  (const_int 0)))
8614    (set (match_operand:DI 0 "register_operand" "=r")
8615         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8616   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8617    && ix86_binary_operator_ok (IOR, SImode, operands)"
8618   "or{l}\t{%2, %k0|%k0, %2}"
8619   [(set_attr "type" "alu")
8620    (set_attr "mode" "SI")])
8622 (define_insn "*iorsi_2_zext_imm"
8623   [(set (reg FLAGS_REG)
8624         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8625                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8626                  (const_int 0)))
8627    (set (match_operand:DI 0 "register_operand" "=r")
8628         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8629   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8630    && ix86_binary_operator_ok (IOR, SImode, operands)"
8631   "or{l}\t{%2, %k0|%k0, %2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "SI")])
8635 (define_insn "*iorsi_3"
8636   [(set (reg FLAGS_REG)
8637         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8638                          (match_operand:SI 2 "general_operand" "rim"))
8639                  (const_int 0)))
8640    (clobber (match_scratch:SI 0 "=r"))]
8641   "ix86_match_ccmode (insn, CCNOmode)
8642    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8643   "or{l}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "SI")])
8647 (define_expand "iorhi3"
8648   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8649         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8650                 (match_operand:HI 2 "general_operand" "")))
8651    (clobber (reg:CC FLAGS_REG))]
8652   "TARGET_HIMODE_MATH"
8653   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8655 (define_insn "*iorhi_1"
8656   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8657         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8658                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8659    (clobber (reg:CC FLAGS_REG))]
8660   "ix86_binary_operator_ok (IOR, HImode, operands)"
8661   "or{w}\t{%2, %0|%0, %2}"
8662   [(set_attr "type" "alu")
8663    (set_attr "mode" "HI")])
8665 (define_insn "*iorhi_2"
8666   [(set (reg FLAGS_REG)
8667         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8668                          (match_operand:HI 2 "general_operand" "rim,ri"))
8669                  (const_int 0)))
8670    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8671         (ior:HI (match_dup 1) (match_dup 2)))]
8672   "ix86_match_ccmode (insn, CCNOmode)
8673    && ix86_binary_operator_ok (IOR, HImode, operands)"
8674   "or{w}\t{%2, %0|%0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "mode" "HI")])
8678 (define_insn "*iorhi_3"
8679   [(set (reg FLAGS_REG)
8680         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8681                          (match_operand:HI 2 "general_operand" "rim"))
8682                  (const_int 0)))
8683    (clobber (match_scratch:HI 0 "=r"))]
8684   "ix86_match_ccmode (insn, CCNOmode)
8685    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8686   "or{w}\t{%2, %0|%0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "HI")])
8690 (define_expand "iorqi3"
8691   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8692         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8693                 (match_operand:QI 2 "general_operand" "")))
8694    (clobber (reg:CC FLAGS_REG))]
8695   "TARGET_QIMODE_MATH"
8696   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8698 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8699 (define_insn "*iorqi_1"
8700   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8701         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8702                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8703    (clobber (reg:CC FLAGS_REG))]
8704   "ix86_binary_operator_ok (IOR, QImode, operands)"
8705   "@
8706    or{b}\t{%2, %0|%0, %2}
8707    or{b}\t{%2, %0|%0, %2}
8708    or{l}\t{%k2, %k0|%k0, %k2}"
8709   [(set_attr "type" "alu")
8710    (set_attr "mode" "QI,QI,SI")])
8712 (define_insn "*iorqi_1_slp"
8713   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8714         (ior:QI (match_dup 0)
8715                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8719   "or{b}\t{%1, %0|%0, %1}"
8720   [(set_attr "type" "alu1")
8721    (set_attr "mode" "QI")])
8723 (define_insn "*iorqi_2"
8724   [(set (reg FLAGS_REG)
8725         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8726                          (match_operand:QI 2 "general_operand" "qim,qi"))
8727                  (const_int 0)))
8728    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8729         (ior:QI (match_dup 1) (match_dup 2)))]
8730   "ix86_match_ccmode (insn, CCNOmode)
8731    && ix86_binary_operator_ok (IOR, QImode, operands)"
8732   "or{b}\t{%2, %0|%0, %2}"
8733   [(set_attr "type" "alu")
8734    (set_attr "mode" "QI")])
8736 (define_insn "*iorqi_2_slp"
8737   [(set (reg FLAGS_REG)
8738         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8739                          (match_operand:QI 1 "general_operand" "qim,qi"))
8740                  (const_int 0)))
8741    (set (strict_low_part (match_dup 0))
8742         (ior:QI (match_dup 0) (match_dup 1)))]
8743   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8744    && ix86_match_ccmode (insn, CCNOmode)
8745    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8746   "or{b}\t{%1, %0|%0, %1}"
8747   [(set_attr "type" "alu1")
8748    (set_attr "mode" "QI")])
8750 (define_insn "*iorqi_3"
8751   [(set (reg FLAGS_REG)
8752         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8753                          (match_operand:QI 2 "general_operand" "qim"))
8754                  (const_int 0)))
8755    (clobber (match_scratch:QI 0 "=q"))]
8756   "ix86_match_ccmode (insn, CCNOmode)
8757    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8758   "or{b}\t{%2, %0|%0, %2}"
8759   [(set_attr "type" "alu")
8760    (set_attr "mode" "QI")])
8762 (define_insn "iorqi_ext_0"
8763   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8764                          (const_int 8)
8765                          (const_int 8))
8766         (ior:SI 
8767           (zero_extract:SI
8768             (match_operand 1 "ext_register_operand" "0")
8769             (const_int 8)
8770             (const_int 8))
8771           (match_operand 2 "const_int_operand" "n")))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8774   "or{b}\t{%2, %h0|%h0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "length_immediate" "1")
8777    (set_attr "mode" "QI")])
8779 (define_insn "*iorqi_ext_1"
8780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781                          (const_int 8)
8782                          (const_int 8))
8783         (ior:SI 
8784           (zero_extract:SI
8785             (match_operand 1 "ext_register_operand" "0")
8786             (const_int 8)
8787             (const_int 8))
8788           (zero_extend:SI
8789             (match_operand:QI 2 "general_operand" "Qm"))))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "!TARGET_64BIT
8792    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8793   "or{b}\t{%2, %h0|%h0, %2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "length_immediate" "0")
8796    (set_attr "mode" "QI")])
8798 (define_insn "*iorqi_ext_1_rex64"
8799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8800                          (const_int 8)
8801                          (const_int 8))
8802         (ior:SI 
8803           (zero_extract:SI
8804             (match_operand 1 "ext_register_operand" "0")
8805             (const_int 8)
8806             (const_int 8))
8807           (zero_extend:SI
8808             (match_operand 2 "ext_register_operand" "Q"))))
8809    (clobber (reg:CC FLAGS_REG))]
8810   "TARGET_64BIT
8811    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8812   "or{b}\t{%2, %h0|%h0, %2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "length_immediate" "0")
8815    (set_attr "mode" "QI")])
8817 (define_insn "*iorqi_ext_2"
8818   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8819                          (const_int 8)
8820                          (const_int 8))
8821         (ior:SI 
8822           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8823                            (const_int 8)
8824                            (const_int 8))
8825           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8826                            (const_int 8)
8827                            (const_int 8))))
8828    (clobber (reg:CC FLAGS_REG))]
8829   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8830   "ior{b}\t{%h2, %h0|%h0, %h2}"
8831   [(set_attr "type" "alu")
8832    (set_attr "length_immediate" "0")
8833    (set_attr "mode" "QI")])
8835 (define_split
8836   [(set (match_operand 0 "register_operand" "")
8837         (ior (match_operand 1 "register_operand" "")
8838              (match_operand 2 "const_int_operand" "")))
8839    (clobber (reg:CC FLAGS_REG))]
8840    "reload_completed
8841     && QI_REG_P (operands[0])
8842     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8843     && !(INTVAL (operands[2]) & ~(255 << 8))
8844     && GET_MODE (operands[0]) != QImode"
8845   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8846                    (ior:SI (zero_extract:SI (match_dup 1)
8847                                             (const_int 8) (const_int 8))
8848                            (match_dup 2)))
8849               (clobber (reg:CC FLAGS_REG))])]
8850   "operands[0] = gen_lowpart (SImode, operands[0]);
8851    operands[1] = gen_lowpart (SImode, operands[1]);
8852    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854 ;; Since OR can be encoded with sign extended immediate, this is only
8855 ;; profitable when 7th bit is set.
8856 (define_split
8857   [(set (match_operand 0 "register_operand" "")
8858         (ior (match_operand 1 "general_operand" "")
8859              (match_operand 2 "const_int_operand" "")))
8860    (clobber (reg:CC FLAGS_REG))]
8861    "reload_completed
8862     && ANY_QI_REG_P (operands[0])
8863     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8864     && !(INTVAL (operands[2]) & ~255)
8865     && (INTVAL (operands[2]) & 128)
8866     && GET_MODE (operands[0]) != QImode"
8867   [(parallel [(set (strict_low_part (match_dup 0))
8868                    (ior:QI (match_dup 1)
8869                            (match_dup 2)))
8870               (clobber (reg:CC FLAGS_REG))])]
8871   "operands[0] = gen_lowpart (QImode, operands[0]);
8872    operands[1] = gen_lowpart (QImode, operands[1]);
8873    operands[2] = gen_lowpart (QImode, operands[2]);")
8875 ;; Logical XOR instructions
8877 ;; %%% This used to optimize known byte-wide and operations to memory.
8878 ;; If this is considered useful, it should be done with splitters.
8880 (define_expand "xordi3"
8881   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8882         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8883                 (match_operand:DI 2 "x86_64_general_operand" "")))
8884    (clobber (reg:CC FLAGS_REG))]
8885   "TARGET_64BIT"
8886   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8888 (define_insn "*xordi_1_rex64"
8889   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8890         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8891                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "TARGET_64BIT
8894    && ix86_binary_operator_ok (XOR, DImode, operands)"
8895   "@
8896    xor{q}\t{%2, %0|%0, %2}
8897    xor{q}\t{%2, %0|%0, %2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "DI,DI")])
8901 (define_insn "*xordi_2_rex64"
8902   [(set (reg FLAGS_REG)
8903         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8904                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8905                  (const_int 0)))
8906    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8907         (xor:DI (match_dup 1) (match_dup 2)))]
8908   "TARGET_64BIT
8909    && ix86_match_ccmode (insn, CCNOmode)
8910    && ix86_binary_operator_ok (XOR, DImode, operands)"
8911   "@
8912    xor{q}\t{%2, %0|%0, %2}
8913    xor{q}\t{%2, %0|%0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "mode" "DI,DI")])
8917 (define_insn "*xordi_3_rex64"
8918   [(set (reg FLAGS_REG)
8919         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8920                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8921                  (const_int 0)))
8922    (clobber (match_scratch:DI 0 "=r"))]
8923   "TARGET_64BIT
8924    && ix86_match_ccmode (insn, CCNOmode)
8925    && ix86_binary_operator_ok (XOR, DImode, operands)"
8926   "xor{q}\t{%2, %0|%0, %2}"
8927   [(set_attr "type" "alu")
8928    (set_attr "mode" "DI")])
8930 (define_expand "xorsi3"
8931   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8932         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8933                 (match_operand:SI 2 "general_operand" "")))
8934    (clobber (reg:CC FLAGS_REG))]
8935   ""
8936   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8938 (define_insn "*xorsi_1"
8939   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8940         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941                 (match_operand:SI 2 "general_operand" "ri,rm")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "ix86_binary_operator_ok (XOR, SImode, operands)"
8944   "xor{l}\t{%2, %0|%0, %2}"
8945   [(set_attr "type" "alu")
8946    (set_attr "mode" "SI")])
8948 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8949 ;; Add speccase for immediates
8950 (define_insn "*xorsi_1_zext"
8951   [(set (match_operand:DI 0 "register_operand" "=r")
8952         (zero_extend:DI
8953           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954                   (match_operand:SI 2 "general_operand" "rim"))))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8957   "xor{l}\t{%2, %k0|%k0, %2}"
8958   [(set_attr "type" "alu")
8959    (set_attr "mode" "SI")])
8961 (define_insn "*xorsi_1_zext_imm"
8962   [(set (match_operand:DI 0 "register_operand" "=r")
8963         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8964                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8965    (clobber (reg:CC FLAGS_REG))]
8966   "TARGET_64BIT && 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"
8972   [(set (reg FLAGS_REG)
8973         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8974                          (match_operand:SI 2 "general_operand" "rim,ri"))
8975                  (const_int 0)))
8976    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8977         (xor:SI (match_dup 1) (match_dup 2)))]
8978   "ix86_match_ccmode (insn, CCNOmode)
8979    && ix86_binary_operator_ok (XOR, SImode, operands)"
8980   "xor{l}\t{%2, %0|%0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8985 ;; ??? Special case for immediate operand is missing - it is tricky.
8986 (define_insn "*xorsi_2_zext"
8987   [(set (reg FLAGS_REG)
8988         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989                          (match_operand:SI 2 "general_operand" "rim"))
8990                  (const_int 0)))
8991    (set (match_operand:DI 0 "register_operand" "=r")
8992         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8993   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994    && ix86_binary_operator_ok (XOR, SImode, operands)"
8995   "xor{l}\t{%2, %k0|%k0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "mode" "SI")])
8999 (define_insn "*xorsi_2_zext_imm"
9000   [(set (reg FLAGS_REG)
9001         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9003                  (const_int 0)))
9004    (set (match_operand:DI 0 "register_operand" "=r")
9005         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9006   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007    && ix86_binary_operator_ok (XOR, SImode, operands)"
9008   "xor{l}\t{%2, %k0|%k0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "SI")])
9012 (define_insn "*xorsi_3"
9013   [(set (reg FLAGS_REG)
9014         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9015                          (match_operand:SI 2 "general_operand" "rim"))
9016                  (const_int 0)))
9017    (clobber (match_scratch:SI 0 "=r"))]
9018   "ix86_match_ccmode (insn, CCNOmode)
9019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9020   "xor{l}\t{%2, %0|%0, %2}"
9021   [(set_attr "type" "alu")
9022    (set_attr "mode" "SI")])
9024 (define_expand "xorhi3"
9025   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9026         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9027                 (match_operand:HI 2 "general_operand" "")))
9028    (clobber (reg:CC FLAGS_REG))]
9029   "TARGET_HIMODE_MATH"
9030   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9032 (define_insn "*xorhi_1"
9033   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9034         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9035                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "ix86_binary_operator_ok (XOR, HImode, operands)"
9038   "xor{w}\t{%2, %0|%0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "mode" "HI")])
9042 (define_insn "*xorhi_2"
9043   [(set (reg FLAGS_REG)
9044         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9045                          (match_operand:HI 2 "general_operand" "rim,ri"))
9046                  (const_int 0)))
9047    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9048         (xor:HI (match_dup 1) (match_dup 2)))]
9049   "ix86_match_ccmode (insn, CCNOmode)
9050    && ix86_binary_operator_ok (XOR, HImode, operands)"
9051   "xor{w}\t{%2, %0|%0, %2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "mode" "HI")])
9055 (define_insn "*xorhi_3"
9056   [(set (reg FLAGS_REG)
9057         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9058                          (match_operand:HI 2 "general_operand" "rim"))
9059                  (const_int 0)))
9060    (clobber (match_scratch:HI 0 "=r"))]
9061   "ix86_match_ccmode (insn, CCNOmode)
9062    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9063   "xor{w}\t{%2, %0|%0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "HI")])
9067 (define_expand "xorqi3"
9068   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9069         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9070                 (match_operand:QI 2 "general_operand" "")))
9071    (clobber (reg:CC FLAGS_REG))]
9072   "TARGET_QIMODE_MATH"
9073   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9075 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9076 (define_insn "*xorqi_1"
9077   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9078         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9079                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "ix86_binary_operator_ok (XOR, QImode, operands)"
9082   "@
9083    xor{b}\t{%2, %0|%0, %2}
9084    xor{b}\t{%2, %0|%0, %2}
9085    xor{l}\t{%k2, %k0|%k0, %k2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "QI,QI,SI")])
9089 (define_insn "*xorqi_1_slp"
9090   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9091         (xor:QI (match_dup 0)
9092                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9096   "xor{b}\t{%1, %0|%0, %1}"
9097   [(set_attr "type" "alu1")
9098    (set_attr "mode" "QI")])
9100 (define_insn "xorqi_ext_0"
9101   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9102                          (const_int 8)
9103                          (const_int 8))
9104         (xor:SI 
9105           (zero_extract:SI
9106             (match_operand 1 "ext_register_operand" "0")
9107             (const_int 8)
9108             (const_int 8))
9109           (match_operand 2 "const_int_operand" "n")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9112   "xor{b}\t{%2, %h0|%h0, %2}"
9113   [(set_attr "type" "alu")
9114    (set_attr "length_immediate" "1")
9115    (set_attr "mode" "QI")])
9117 (define_insn "*xorqi_ext_1"
9118   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119                          (const_int 8)
9120                          (const_int 8))
9121         (xor:SI 
9122           (zero_extract:SI
9123             (match_operand 1 "ext_register_operand" "0")
9124             (const_int 8)
9125             (const_int 8))
9126           (zero_extend:SI
9127             (match_operand:QI 2 "general_operand" "Qm"))))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "!TARGET_64BIT
9130    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9131   "xor{b}\t{%2, %h0|%h0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "length_immediate" "0")
9134    (set_attr "mode" "QI")])
9136 (define_insn "*xorqi_ext_1_rex64"
9137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9138                          (const_int 8)
9139                          (const_int 8))
9140         (xor:SI 
9141           (zero_extract:SI
9142             (match_operand 1 "ext_register_operand" "0")
9143             (const_int 8)
9144             (const_int 8))
9145           (zero_extend:SI
9146             (match_operand 2 "ext_register_operand" "Q"))))
9147    (clobber (reg:CC FLAGS_REG))]
9148   "TARGET_64BIT
9149    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9150   "xor{b}\t{%2, %h0|%h0, %2}"
9151   [(set_attr "type" "alu")
9152    (set_attr "length_immediate" "0")
9153    (set_attr "mode" "QI")])
9155 (define_insn "*xorqi_ext_2"
9156   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9157                          (const_int 8)
9158                          (const_int 8))
9159         (xor:SI 
9160           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9161                            (const_int 8)
9162                            (const_int 8))
9163           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9164                            (const_int 8)
9165                            (const_int 8))))
9166    (clobber (reg:CC FLAGS_REG))]
9167   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9168   "xor{b}\t{%h2, %h0|%h0, %h2}"
9169   [(set_attr "type" "alu")
9170    (set_attr "length_immediate" "0")
9171    (set_attr "mode" "QI")])
9173 (define_insn "*xorqi_cc_1"
9174   [(set (reg FLAGS_REG)
9175         (compare
9176           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9177                   (match_operand:QI 2 "general_operand" "qim,qi"))
9178           (const_int 0)))
9179    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9180         (xor:QI (match_dup 1) (match_dup 2)))]
9181   "ix86_match_ccmode (insn, CCNOmode)
9182    && ix86_binary_operator_ok (XOR, QImode, operands)"
9183   "xor{b}\t{%2, %0|%0, %2}"
9184   [(set_attr "type" "alu")
9185    (set_attr "mode" "QI")])
9187 (define_insn "*xorqi_2_slp"
9188   [(set (reg FLAGS_REG)
9189         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9190                          (match_operand:QI 1 "general_operand" "qim,qi"))
9191                  (const_int 0)))
9192    (set (strict_low_part (match_dup 0))
9193         (xor:QI (match_dup 0) (match_dup 1)))]
9194   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9195    && ix86_match_ccmode (insn, CCNOmode)
9196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197   "xor{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9201 (define_insn "*xorqi_cc_2"
9202   [(set (reg FLAGS_REG)
9203         (compare
9204           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9205                   (match_operand:QI 2 "general_operand" "qim"))
9206           (const_int 0)))
9207    (clobber (match_scratch:QI 0 "=q"))]
9208   "ix86_match_ccmode (insn, CCNOmode)
9209    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9210   "xor{b}\t{%2, %0|%0, %2}"
9211   [(set_attr "type" "alu")
9212    (set_attr "mode" "QI")])
9214 (define_insn "*xorqi_cc_ext_1"
9215   [(set (reg FLAGS_REG)
9216         (compare
9217           (xor:SI
9218             (zero_extract:SI
9219               (match_operand 1 "ext_register_operand" "0")
9220               (const_int 8)
9221               (const_int 8))
9222             (match_operand:QI 2 "general_operand" "qmn"))
9223           (const_int 0)))
9224    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9225                          (const_int 8)
9226                          (const_int 8))
9227         (xor:SI 
9228           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9229           (match_dup 2)))]
9230   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9231   "xor{b}\t{%2, %h0|%h0, %2}"
9232   [(set_attr "type" "alu")
9233    (set_attr "mode" "QI")])
9235 (define_insn "*xorqi_cc_ext_1_rex64"
9236   [(set (reg FLAGS_REG)
9237         (compare
9238           (xor:SI
9239             (zero_extract:SI
9240               (match_operand 1 "ext_register_operand" "0")
9241               (const_int 8)
9242               (const_int 8))
9243             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9244           (const_int 0)))
9245    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9246                          (const_int 8)
9247                          (const_int 8))
9248         (xor:SI 
9249           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9250           (match_dup 2)))]
9251   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9252   "xor{b}\t{%2, %h0|%h0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "mode" "QI")])
9256 (define_expand "xorqi_cc_ext_1"
9257   [(parallel [
9258      (set (reg:CCNO FLAGS_REG)
9259           (compare:CCNO
9260             (xor:SI
9261               (zero_extract:SI
9262                 (match_operand 1 "ext_register_operand" "")
9263                 (const_int 8)
9264                 (const_int 8))
9265               (match_operand:QI 2 "general_operand" ""))
9266             (const_int 0)))
9267      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9268                            (const_int 8)
9269                            (const_int 8))
9270           (xor:SI 
9271             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9272             (match_dup 2)))])]
9273   ""
9274   "")
9276 (define_split
9277   [(set (match_operand 0 "register_operand" "")
9278         (xor (match_operand 1 "register_operand" "")
9279              (match_operand 2 "const_int_operand" "")))
9280    (clobber (reg:CC FLAGS_REG))]
9281    "reload_completed
9282     && QI_REG_P (operands[0])
9283     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9284     && !(INTVAL (operands[2]) & ~(255 << 8))
9285     && GET_MODE (operands[0]) != QImode"
9286   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9287                    (xor:SI (zero_extract:SI (match_dup 1)
9288                                             (const_int 8) (const_int 8))
9289                            (match_dup 2)))
9290               (clobber (reg:CC FLAGS_REG))])]
9291   "operands[0] = gen_lowpart (SImode, operands[0]);
9292    operands[1] = gen_lowpart (SImode, operands[1]);
9293    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9295 ;; Since XOR can be encoded with sign extended immediate, this is only
9296 ;; profitable when 7th bit is set.
9297 (define_split
9298   [(set (match_operand 0 "register_operand" "")
9299         (xor (match_operand 1 "general_operand" "")
9300              (match_operand 2 "const_int_operand" "")))
9301    (clobber (reg:CC FLAGS_REG))]
9302    "reload_completed
9303     && ANY_QI_REG_P (operands[0])
9304     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9305     && !(INTVAL (operands[2]) & ~255)
9306     && (INTVAL (operands[2]) & 128)
9307     && GET_MODE (operands[0]) != QImode"
9308   [(parallel [(set (strict_low_part (match_dup 0))
9309                    (xor:QI (match_dup 1)
9310                            (match_dup 2)))
9311               (clobber (reg:CC FLAGS_REG))])]
9312   "operands[0] = gen_lowpart (QImode, operands[0]);
9313    operands[1] = gen_lowpart (QImode, operands[1]);
9314    operands[2] = gen_lowpart (QImode, operands[2]);")
9316 ;; Negation instructions
9318 (define_expand "negti2"
9319   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9320                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9321               (clobber (reg:CC FLAGS_REG))])]
9322   "TARGET_64BIT"
9323   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9325 (define_insn "*negti2_1"
9326   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9327         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "TARGET_64BIT
9330    && ix86_unary_operator_ok (NEG, TImode, operands)"
9331   "#")
9333 (define_split
9334   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9335         (neg:TI (match_operand:TI 1 "general_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "TARGET_64BIT && reload_completed"
9338   [(parallel
9339     [(set (reg:CCZ FLAGS_REG)
9340           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9341      (set (match_dup 0) (neg:DI (match_dup 2)))])
9342    (parallel
9343     [(set (match_dup 1)
9344           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9345                             (match_dup 3))
9346                    (const_int 0)))
9347      (clobber (reg:CC FLAGS_REG))])
9348    (parallel
9349     [(set (match_dup 1)
9350           (neg:DI (match_dup 1)))
9351      (clobber (reg:CC FLAGS_REG))])]
9352   "split_ti (operands+1, 1, operands+2, operands+3);
9353    split_ti (operands+0, 1, operands+0, operands+1);")
9355 (define_expand "negdi2"
9356   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9357                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9358               (clobber (reg:CC FLAGS_REG))])]
9359   ""
9360   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9362 (define_insn "*negdi2_1"
9363   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9364         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9365    (clobber (reg:CC FLAGS_REG))]
9366   "!TARGET_64BIT
9367    && ix86_unary_operator_ok (NEG, DImode, operands)"
9368   "#")
9370 (define_split
9371   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9372         (neg:DI (match_operand:DI 1 "general_operand" "")))
9373    (clobber (reg:CC FLAGS_REG))]
9374   "!TARGET_64BIT && reload_completed"
9375   [(parallel
9376     [(set (reg:CCZ FLAGS_REG)
9377           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9378      (set (match_dup 0) (neg:SI (match_dup 2)))])
9379    (parallel
9380     [(set (match_dup 1)
9381           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9382                             (match_dup 3))
9383                    (const_int 0)))
9384      (clobber (reg:CC FLAGS_REG))])
9385    (parallel
9386     [(set (match_dup 1)
9387           (neg:SI (match_dup 1)))
9388      (clobber (reg:CC FLAGS_REG))])]
9389   "split_di (operands+1, 1, operands+2, operands+3);
9390    split_di (operands+0, 1, operands+0, operands+1);")
9392 (define_insn "*negdi2_1_rex64"
9393   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9394         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9397   "neg{q}\t%0"
9398   [(set_attr "type" "negnot")
9399    (set_attr "mode" "DI")])
9401 ;; The problem with neg is that it does not perform (compare x 0),
9402 ;; it really performs (compare 0 x), which leaves us with the zero
9403 ;; flag being the only useful item.
9405 (define_insn "*negdi2_cmpz_rex64"
9406   [(set (reg:CCZ FLAGS_REG)
9407         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9408                      (const_int 0)))
9409    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9410         (neg:DI (match_dup 1)))]
9411   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9412   "neg{q}\t%0"
9413   [(set_attr "type" "negnot")
9414    (set_attr "mode" "DI")])
9417 (define_expand "negsi2"
9418   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9419                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9420               (clobber (reg:CC FLAGS_REG))])]
9421   ""
9422   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9424 (define_insn "*negsi2_1"
9425   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9426         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "ix86_unary_operator_ok (NEG, SImode, operands)"
9429   "neg{l}\t%0"
9430   [(set_attr "type" "negnot")
9431    (set_attr "mode" "SI")])
9433 ;; Combine is quite creative about this pattern.
9434 (define_insn "*negsi2_1_zext"
9435   [(set (match_operand:DI 0 "register_operand" "=r")
9436         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9437                                         (const_int 32)))
9438                      (const_int 32)))
9439    (clobber (reg:CC FLAGS_REG))]
9440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9441   "neg{l}\t%k0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "SI")])
9445 ;; The problem with neg is that it does not perform (compare x 0),
9446 ;; it really performs (compare 0 x), which leaves us with the zero
9447 ;; flag being the only useful item.
9449 (define_insn "*negsi2_cmpz"
9450   [(set (reg:CCZ FLAGS_REG)
9451         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9452                      (const_int 0)))
9453    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9454         (neg:SI (match_dup 1)))]
9455   "ix86_unary_operator_ok (NEG, SImode, operands)"
9456   "neg{l}\t%0"
9457   [(set_attr "type" "negnot")
9458    (set_attr "mode" "SI")])
9460 (define_insn "*negsi2_cmpz_zext"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (lshiftrt:DI
9463                        (neg:DI (ashift:DI
9464                                  (match_operand:DI 1 "register_operand" "0")
9465                                  (const_int 32)))
9466                        (const_int 32))
9467                      (const_int 0)))
9468    (set (match_operand:DI 0 "register_operand" "=r")
9469         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9470                                         (const_int 32)))
9471                      (const_int 32)))]
9472   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9473   "neg{l}\t%k0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9477 (define_expand "neghi2"
9478   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9479                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9480               (clobber (reg:CC FLAGS_REG))])]
9481   "TARGET_HIMODE_MATH"
9482   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9484 (define_insn "*neghi2_1"
9485   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9486         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "ix86_unary_operator_ok (NEG, HImode, operands)"
9489   "neg{w}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "HI")])
9493 (define_insn "*neghi2_cmpz"
9494   [(set (reg:CCZ FLAGS_REG)
9495         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9496                      (const_int 0)))
9497    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9498         (neg:HI (match_dup 1)))]
9499   "ix86_unary_operator_ok (NEG, HImode, operands)"
9500   "neg{w}\t%0"
9501   [(set_attr "type" "negnot")
9502    (set_attr "mode" "HI")])
9504 (define_expand "negqi2"
9505   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9506                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9507               (clobber (reg:CC FLAGS_REG))])]
9508   "TARGET_QIMODE_MATH"
9509   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9511 (define_insn "*negqi2_1"
9512   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9513         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9514    (clobber (reg:CC FLAGS_REG))]
9515   "ix86_unary_operator_ok (NEG, QImode, operands)"
9516   "neg{b}\t%0"
9517   [(set_attr "type" "negnot")
9518    (set_attr "mode" "QI")])
9520 (define_insn "*negqi2_cmpz"
9521   [(set (reg:CCZ FLAGS_REG)
9522         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9523                      (const_int 0)))
9524    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9525         (neg:QI (match_dup 1)))]
9526   "ix86_unary_operator_ok (NEG, QImode, operands)"
9527   "neg{b}\t%0"
9528   [(set_attr "type" "negnot")
9529    (set_attr "mode" "QI")])
9531 ;; Changing of sign for FP values is doable using integer unit too.
9533 (define_expand "negsf2"
9534   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9535         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9536   "TARGET_80387 || TARGET_SSE_MATH"
9537   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9539 (define_expand "abssf2"
9540   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9541         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9542   "TARGET_80387 || TARGET_SSE_MATH"
9543   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9545 (define_insn "*absnegsf2_mixed"
9546   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,f,rm")
9547         (match_operator:SF 3 "absneg_operator"
9548           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0  ,0")]))
9549    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9550    (clobber (reg:CC FLAGS_REG))]
9551   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9552    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9553   "#")
9555 (define_insn "*absnegsf2_sse"
9556   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9557         (match_operator:SF 3 "absneg_operator"
9558           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9559    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9560    (clobber (reg:CC FLAGS_REG))]
9561   "TARGET_SSE_MATH
9562    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9563   "#")
9565 (define_insn "*absnegsf2_i387"
9566   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9567         (match_operator:SF 3 "absneg_operator"
9568           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9569    (use (match_operand 2 "" ""))
9570    (clobber (reg:CC FLAGS_REG))]
9571   "TARGET_80387 && !TARGET_SSE_MATH
9572    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9573   "#")
9575 (define_expand "copysignsf3"
9576   [(match_operand:SF 0 "register_operand" "")
9577    (match_operand:SF 1 "nonmemory_operand" "")
9578    (match_operand:SF 2 "register_operand" "")]
9579   "TARGET_SSE_MATH"
9581   ix86_expand_copysign (operands);
9582   DONE;
9585 (define_insn_and_split "copysignsf3_const"
9586   [(set (match_operand:SF 0 "register_operand"          "=x")
9587         (unspec:SF
9588           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9589            (match_operand:SF 2 "register_operand"       "0")
9590            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9591           UNSPEC_COPYSIGN))]
9592   "TARGET_SSE_MATH"
9593   "#"
9594   "&& reload_completed"
9595   [(const_int 0)]
9597   ix86_split_copysign_const (operands);
9598   DONE;
9601 (define_insn "copysignsf3_var"
9602   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9603         (unspec:SF
9604           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9605            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9606            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9607            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9608           UNSPEC_COPYSIGN))
9609    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9610   "TARGET_SSE_MATH"
9611   "#")
9613 (define_split
9614   [(set (match_operand:SF 0 "register_operand" "")
9615         (unspec:SF
9616           [(match_operand:SF 2 "register_operand" "")
9617            (match_operand:SF 3 "register_operand" "")
9618            (match_operand:V4SF 4 "" "")
9619            (match_operand:V4SF 5 "" "")]
9620           UNSPEC_COPYSIGN))
9621    (clobber (match_scratch:V4SF 1 ""))]
9622   "TARGET_SSE_MATH && reload_completed"
9623   [(const_int 0)]
9625   ix86_split_copysign_var (operands);
9626   DONE;
9629 (define_expand "negdf2"
9630   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9631         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9632   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9633   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9635 (define_expand "absdf2"
9636   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9637         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9638   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9639   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9641 (define_insn "*absnegdf2_mixed"
9642   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9643         (match_operator:DF 3 "absneg_operator"
9644           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y,0  ,0")]))
9645    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9648    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9649   "#")
9651 (define_insn "*absnegdf2_sse"
9652   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9653         (match_operator:DF 3 "absneg_operator"
9654           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9655    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9656    (clobber (reg:CC FLAGS_REG))]
9657   "TARGET_SSE2 && TARGET_SSE_MATH
9658    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9659   "#")
9661 (define_insn "*absnegdf2_i387"
9662   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9663         (match_operator:DF 3 "absneg_operator"
9664           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9665    (use (match_operand 2 "" ""))
9666    (clobber (reg:CC FLAGS_REG))]
9667   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9668    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9669   "#")
9671 (define_expand "copysigndf3"
9672   [(match_operand:DF 0 "register_operand" "")
9673    (match_operand:DF 1 "nonmemory_operand" "")
9674    (match_operand:DF 2 "register_operand" "")]
9675   "TARGET_SSE2 && TARGET_SSE_MATH"
9677   ix86_expand_copysign (operands);
9678   DONE;
9681 (define_insn_and_split "copysigndf3_const"
9682   [(set (match_operand:DF 0 "register_operand"          "=x")
9683         (unspec:DF
9684           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9685            (match_operand:DF 2 "register_operand"       "0")
9686            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9687           UNSPEC_COPYSIGN))]
9688   "TARGET_SSE2 && TARGET_SSE_MATH"
9689   "#"
9690   "&& reload_completed"
9691   [(const_int 0)]
9693   ix86_split_copysign_const (operands);
9694   DONE;
9697 (define_insn "copysigndf3_var"
9698   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9699         (unspec:DF
9700           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9701            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9702            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9703            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9704           UNSPEC_COPYSIGN))
9705    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9706   "TARGET_SSE2 && TARGET_SSE_MATH"
9707   "#")
9709 (define_split
9710   [(set (match_operand:DF 0 "register_operand" "")
9711         (unspec:DF
9712           [(match_operand:DF 2 "register_operand" "")
9713            (match_operand:DF 3 "register_operand" "")
9714            (match_operand:V2DF 4 "" "")
9715            (match_operand:V2DF 5 "" "")]
9716           UNSPEC_COPYSIGN))
9717    (clobber (match_scratch:V2DF 1 ""))]
9718   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9719   [(const_int 0)]
9721   ix86_split_copysign_var (operands);
9722   DONE;
9725 (define_expand "negxf2"
9726   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9727         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9728   "TARGET_80387"
9729   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9731 (define_expand "absxf2"
9732   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9733         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9734   "TARGET_80387"
9735   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9737 (define_insn "*absnegxf2_i387"
9738   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9739         (match_operator:XF 3 "absneg_operator"
9740           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9741    (use (match_operand 2 "" ""))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "TARGET_80387
9744    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9745   "#")
9747 ;; Splitters for fp abs and neg.
9749 (define_split
9750   [(set (match_operand 0 "fp_register_operand" "")
9751         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9752    (use (match_operand 2 "" ""))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "reload_completed"
9755   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9757 (define_split
9758   [(set (match_operand 0 "register_operand" "")
9759         (match_operator 3 "absneg_operator"
9760           [(match_operand 1 "register_operand" "")]))
9761    (use (match_operand 2 "nonimmediate_operand" ""))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "reload_completed && SSE_REG_P (operands[0])"
9764   [(set (match_dup 0) (match_dup 3))]
9766   enum machine_mode mode = GET_MODE (operands[0]);
9767   enum machine_mode vmode = GET_MODE (operands[2]);
9768   rtx tmp;
9769   
9770   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9771   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9772   if (operands_match_p (operands[0], operands[2]))
9773     {
9774       tmp = operands[1];
9775       operands[1] = operands[2];
9776       operands[2] = tmp;
9777     }
9778   if (GET_CODE (operands[3]) == ABS)
9779     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9780   else
9781     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9782   operands[3] = tmp;
9785 (define_split
9786   [(set (match_operand:SF 0 "register_operand" "")
9787         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9788    (use (match_operand:V4SF 2 "" ""))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "reload_completed"
9791   [(parallel [(set (match_dup 0) (match_dup 1))
9792               (clobber (reg:CC FLAGS_REG))])]
9794   rtx tmp;
9795   operands[0] = gen_lowpart (SImode, operands[0]);
9796   if (GET_CODE (operands[1]) == ABS)
9797     {
9798       tmp = gen_int_mode (0x7fffffff, SImode);
9799       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9800     }
9801   else
9802     {
9803       tmp = gen_int_mode (0x80000000, SImode);
9804       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9805     }
9806   operands[1] = tmp;
9809 (define_split
9810   [(set (match_operand:DF 0 "register_operand" "")
9811         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9812    (use (match_operand 2 "" ""))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "reload_completed"
9815   [(parallel [(set (match_dup 0) (match_dup 1))
9816               (clobber (reg:CC FLAGS_REG))])]
9818   rtx tmp;
9819   if (TARGET_64BIT)
9820     {
9821       tmp = gen_lowpart (DImode, operands[0]);
9822       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9823       operands[0] = tmp;
9825       if (GET_CODE (operands[1]) == ABS)
9826         tmp = const0_rtx;
9827       else
9828         tmp = gen_rtx_NOT (DImode, tmp);
9829     }
9830   else
9831     {
9832       operands[0] = gen_highpart (SImode, operands[0]);
9833       if (GET_CODE (operands[1]) == ABS)
9834         {
9835           tmp = gen_int_mode (0x7fffffff, SImode);
9836           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9837         }
9838       else
9839         {
9840           tmp = gen_int_mode (0x80000000, SImode);
9841           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9842         }
9843     }
9844   operands[1] = tmp;
9847 (define_split
9848   [(set (match_operand:XF 0 "register_operand" "")
9849         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9850    (use (match_operand 2 "" ""))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "reload_completed"
9853   [(parallel [(set (match_dup 0) (match_dup 1))
9854               (clobber (reg:CC FLAGS_REG))])]
9856   rtx tmp;
9857   operands[0] = gen_rtx_REG (SImode,
9858                              true_regnum (operands[0])
9859                              + (TARGET_64BIT ? 1 : 2));
9860   if (GET_CODE (operands[1]) == ABS)
9861     {
9862       tmp = GEN_INT (0x7fff);
9863       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9864     }
9865   else
9866     {
9867       tmp = GEN_INT (0x8000);
9868       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9869     }
9870   operands[1] = tmp;
9873 (define_split
9874   [(set (match_operand 0 "memory_operand" "")
9875         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9876    (use (match_operand 2 "" ""))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "reload_completed"
9879   [(parallel [(set (match_dup 0) (match_dup 1))
9880               (clobber (reg:CC FLAGS_REG))])]
9882   enum machine_mode mode = GET_MODE (operands[0]);
9883   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9884   rtx tmp;
9886   operands[0] = adjust_address (operands[0], QImode, size - 1);
9887   if (GET_CODE (operands[1]) == ABS)
9888     {
9889       tmp = gen_int_mode (0x7f, QImode);
9890       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9891     }
9892   else
9893     {
9894       tmp = gen_int_mode (0x80, QImode);
9895       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9896     }
9897   operands[1] = tmp;
9900 ;; Conditionalize these after reload. If they match before reload, we 
9901 ;; lose the clobber and ability to use integer instructions.
9903 (define_insn "*negsf2_1"
9904   [(set (match_operand:SF 0 "register_operand" "=f")
9905         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9906   "TARGET_80387 && reload_completed"
9907   "fchs"
9908   [(set_attr "type" "fsgn")
9909    (set_attr "mode" "SF")])
9911 (define_insn "*negdf2_1"
9912   [(set (match_operand:DF 0 "register_operand" "=f")
9913         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9914   "TARGET_80387 && reload_completed"
9915   "fchs"
9916   [(set_attr "type" "fsgn")
9917    (set_attr "mode" "DF")])
9919 (define_insn "*negxf2_1"
9920   [(set (match_operand:XF 0 "register_operand" "=f")
9921         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9922   "TARGET_80387 && reload_completed"
9923   "fchs"
9924   [(set_attr "type" "fsgn")
9925    (set_attr "mode" "XF")])
9927 (define_insn "*abssf2_1"
9928   [(set (match_operand:SF 0 "register_operand" "=f")
9929         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9930   "TARGET_80387 && reload_completed"
9931   "fabs"
9932   [(set_attr "type" "fsgn")
9933    (set_attr "mode" "SF")])
9935 (define_insn "*absdf2_1"
9936   [(set (match_operand:DF 0 "register_operand" "=f")
9937         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9938   "TARGET_80387 && reload_completed"
9939   "fabs"
9940   [(set_attr "type" "fsgn")
9941    (set_attr "mode" "DF")])
9943 (define_insn "*absxf2_1"
9944   [(set (match_operand:XF 0 "register_operand" "=f")
9945         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9946   "TARGET_80387 && reload_completed"
9947   "fabs"
9948   [(set_attr "type" "fsgn")
9949    (set_attr "mode" "DF")])
9951 (define_insn "*negextendsfdf2"
9952   [(set (match_operand:DF 0 "register_operand" "=f")
9953         (neg:DF (float_extend:DF
9954                   (match_operand:SF 1 "register_operand" "0"))))]
9955   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9956   "fchs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9960 (define_insn "*negextenddfxf2"
9961   [(set (match_operand:XF 0 "register_operand" "=f")
9962         (neg:XF (float_extend:XF
9963                   (match_operand:DF 1 "register_operand" "0"))))]
9964   "TARGET_80387"
9965   "fchs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "XF")])
9969 (define_insn "*negextendsfxf2"
9970   [(set (match_operand:XF 0 "register_operand" "=f")
9971         (neg:XF (float_extend:XF
9972                   (match_operand:SF 1 "register_operand" "0"))))]
9973   "TARGET_80387"
9974   "fchs"
9975   [(set_attr "type" "fsgn")
9976    (set_attr "mode" "XF")])
9978 (define_insn "*absextendsfdf2"
9979   [(set (match_operand:DF 0 "register_operand" "=f")
9980         (abs:DF (float_extend:DF
9981                   (match_operand:SF 1 "register_operand" "0"))))]
9982   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9983   "fabs"
9984   [(set_attr "type" "fsgn")
9985    (set_attr "mode" "DF")])
9987 (define_insn "*absextenddfxf2"
9988   [(set (match_operand:XF 0 "register_operand" "=f")
9989         (abs:XF (float_extend:XF
9990           (match_operand:DF 1 "register_operand" "0"))))]
9991   "TARGET_80387"
9992   "fabs"
9993   [(set_attr "type" "fsgn")
9994    (set_attr "mode" "XF")])
9996 (define_insn "*absextendsfxf2"
9997   [(set (match_operand:XF 0 "register_operand" "=f")
9998         (abs:XF (float_extend:XF
9999           (match_operand:SF 1 "register_operand" "0"))))]
10000   "TARGET_80387"
10001   "fabs"
10002   [(set_attr "type" "fsgn")
10003    (set_attr "mode" "XF")])
10005 ;; One complement instructions
10007 (define_expand "one_cmpldi2"
10008   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10009         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10010   "TARGET_64BIT"
10011   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10013 (define_insn "*one_cmpldi2_1_rex64"
10014   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10015         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10016   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10017   "not{q}\t%0"
10018   [(set_attr "type" "negnot")
10019    (set_attr "mode" "DI")])
10021 (define_insn "*one_cmpldi2_2_rex64"
10022   [(set (reg FLAGS_REG)
10023         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10024                  (const_int 0)))
10025    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10026         (not:DI (match_dup 1)))]
10027   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10028    && ix86_unary_operator_ok (NOT, DImode, operands)"
10029   "#"
10030   [(set_attr "type" "alu1")
10031    (set_attr "mode" "DI")])
10033 (define_split
10034   [(set (match_operand 0 "flags_reg_operand" "")
10035         (match_operator 2 "compare_operator"
10036           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10037            (const_int 0)]))
10038    (set (match_operand:DI 1 "nonimmediate_operand" "")
10039         (not:DI (match_dup 3)))]
10040   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10041   [(parallel [(set (match_dup 0)
10042                    (match_op_dup 2
10043                      [(xor:DI (match_dup 3) (const_int -1))
10044                       (const_int 0)]))
10045               (set (match_dup 1)
10046                    (xor:DI (match_dup 3) (const_int -1)))])]
10047   "")
10049 (define_expand "one_cmplsi2"
10050   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10051         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10052   ""
10053   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10055 (define_insn "*one_cmplsi2_1"
10056   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10057         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10058   "ix86_unary_operator_ok (NOT, SImode, operands)"
10059   "not{l}\t%0"
10060   [(set_attr "type" "negnot")
10061    (set_attr "mode" "SI")])
10063 ;; ??? Currently never generated - xor is used instead.
10064 (define_insn "*one_cmplsi2_1_zext"
10065   [(set (match_operand:DI 0 "register_operand" "=r")
10066         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10067   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10068   "not{l}\t%k0"
10069   [(set_attr "type" "negnot")
10070    (set_attr "mode" "SI")])
10072 (define_insn "*one_cmplsi2_2"
10073   [(set (reg FLAGS_REG)
10074         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10075                  (const_int 0)))
10076    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10077         (not:SI (match_dup 1)))]
10078   "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 "nonimmediate_operand" ""))
10088            (const_int 0)]))
10089    (set (match_operand:SI 1 "nonimmediate_operand" "")
10090         (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                    (xor:SI (match_dup 3) (const_int -1)))])]
10097   "")
10099 ;; ??? Currently never generated - xor is used instead.
10100 (define_insn "*one_cmplsi2_2_zext"
10101   [(set (reg FLAGS_REG)
10102         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10103                  (const_int 0)))
10104    (set (match_operand:DI 0 "register_operand" "=r")
10105         (zero_extend:DI (not:SI (match_dup 1))))]
10106   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10107    && ix86_unary_operator_ok (NOT, SImode, operands)"
10108   "#"
10109   [(set_attr "type" "alu1")
10110    (set_attr "mode" "SI")])
10112 (define_split
10113   [(set (match_operand 0 "flags_reg_operand" "")
10114         (match_operator 2 "compare_operator"
10115           [(not:SI (match_operand:SI 3 "register_operand" ""))
10116            (const_int 0)]))
10117    (set (match_operand:DI 1 "register_operand" "")
10118         (zero_extend:DI (not:SI (match_dup 3))))]
10119   "ix86_match_ccmode (insn, CCNOmode)"
10120   [(parallel [(set (match_dup 0)
10121                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10122                                     (const_int 0)]))
10123               (set (match_dup 1)
10124                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10125   "")
10127 (define_expand "one_cmplhi2"
10128   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10129         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10130   "TARGET_HIMODE_MATH"
10131   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10133 (define_insn "*one_cmplhi2_1"
10134   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10135         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10136   "ix86_unary_operator_ok (NOT, HImode, operands)"
10137   "not{w}\t%0"
10138   [(set_attr "type" "negnot")
10139    (set_attr "mode" "HI")])
10141 (define_insn "*one_cmplhi2_2"
10142   [(set (reg FLAGS_REG)
10143         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10144                  (const_int 0)))
10145    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10146         (not:HI (match_dup 1)))]
10147   "ix86_match_ccmode (insn, CCNOmode)
10148    && ix86_unary_operator_ok (NEG, HImode, operands)"
10149   "#"
10150   [(set_attr "type" "alu1")
10151    (set_attr "mode" "HI")])
10153 (define_split
10154   [(set (match_operand 0 "flags_reg_operand" "")
10155         (match_operator 2 "compare_operator"
10156           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10157            (const_int 0)]))
10158    (set (match_operand:HI 1 "nonimmediate_operand" "")
10159         (not:HI (match_dup 3)))]
10160   "ix86_match_ccmode (insn, CCNOmode)"
10161   [(parallel [(set (match_dup 0)
10162                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10163                                     (const_int 0)]))
10164               (set (match_dup 1)
10165                    (xor:HI (match_dup 3) (const_int -1)))])]
10166   "")
10168 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10169 (define_expand "one_cmplqi2"
10170   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10171         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10172   "TARGET_QIMODE_MATH"
10173   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10175 (define_insn "*one_cmplqi2_1"
10176   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10177         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10178   "ix86_unary_operator_ok (NOT, QImode, operands)"
10179   "@
10180    not{b}\t%0
10181    not{l}\t%k0"
10182   [(set_attr "type" "negnot")
10183    (set_attr "mode" "QI,SI")])
10185 (define_insn "*one_cmplqi2_2"
10186   [(set (reg FLAGS_REG)
10187         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10188                  (const_int 0)))
10189    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10190         (not:QI (match_dup 1)))]
10191   "ix86_match_ccmode (insn, CCNOmode)
10192    && ix86_unary_operator_ok (NOT, QImode, operands)"
10193   "#"
10194   [(set_attr "type" "alu1")
10195    (set_attr "mode" "QI")])
10197 (define_split
10198   [(set (match_operand 0 "flags_reg_operand" "")
10199         (match_operator 2 "compare_operator"
10200           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10201            (const_int 0)]))
10202    (set (match_operand:QI 1 "nonimmediate_operand" "")
10203         (not:QI (match_dup 3)))]
10204   "ix86_match_ccmode (insn, CCNOmode)"
10205   [(parallel [(set (match_dup 0)
10206                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10207                                     (const_int 0)]))
10208               (set (match_dup 1)
10209                    (xor:QI (match_dup 3) (const_int -1)))])]
10210   "")
10212 ;; Arithmetic shift instructions
10214 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10215 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10216 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10217 ;; from the assembler input.
10219 ;; This instruction shifts the target reg/mem as usual, but instead of
10220 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10221 ;; is a left shift double, bits are taken from the high order bits of
10222 ;; reg, else if the insn is a shift right double, bits are taken from the
10223 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10224 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10226 ;; Since sh[lr]d does not change the `reg' operand, that is done
10227 ;; separately, making all shifts emit pairs of shift double and normal
10228 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10229 ;; support a 63 bit shift, each shift where the count is in a reg expands
10230 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10232 ;; If the shift count is a constant, we need never emit more than one
10233 ;; shift pair, instead using moves and sign extension for counts greater
10234 ;; than 31.
10236 (define_expand "ashlti3"
10237   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10238                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10239                               (match_operand:QI 2 "nonmemory_operand" "")))
10240               (clobber (reg:CC FLAGS_REG))])]
10241   "TARGET_64BIT"
10243   if (! immediate_operand (operands[2], QImode))
10244     {
10245       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10246       DONE;
10247     }
10248   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10249   DONE;
10252 (define_insn "ashlti3_1"
10253   [(set (match_operand:TI 0 "register_operand" "=r")
10254         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10255                    (match_operand:QI 2 "register_operand" "c")))
10256    (clobber (match_scratch:DI 3 "=&r"))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "TARGET_64BIT"
10259   "#"
10260   [(set_attr "type" "multi")])
10262 (define_insn "*ashlti3_2"
10263   [(set (match_operand:TI 0 "register_operand" "=r")
10264         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10265                    (match_operand:QI 2 "immediate_operand" "O")))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "TARGET_64BIT"
10268   "#"
10269   [(set_attr "type" "multi")])
10271 (define_split
10272   [(set (match_operand:TI 0 "register_operand" "")
10273         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10274                    (match_operand:QI 2 "register_operand" "")))
10275    (clobber (match_scratch:DI 3 ""))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "TARGET_64BIT && reload_completed"
10278   [(const_int 0)]
10279   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10281 (define_split
10282   [(set (match_operand:TI 0 "register_operand" "")
10283         (ashift:TI (match_operand:TI 1 "register_operand" "")
10284                    (match_operand:QI 2 "immediate_operand" "")))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "TARGET_64BIT && reload_completed"
10287   [(const_int 0)]
10288   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10290 (define_insn "x86_64_shld"
10291   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10292         (ior:DI (ashift:DI (match_dup 0)
10293                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10294                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10295                   (minus:QI (const_int 64) (match_dup 2)))))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_64BIT"
10298   "@
10299    shld{q}\t{%2, %1, %0|%0, %1, %2}
10300    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10301   [(set_attr "type" "ishift")
10302    (set_attr "prefix_0f" "1")
10303    (set_attr "mode" "DI")
10304    (set_attr "athlon_decode" "vector")])
10306 (define_expand "x86_64_shift_adj"
10307   [(set (reg:CCZ FLAGS_REG)
10308         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10309                              (const_int 64))
10310                      (const_int 0)))
10311    (set (match_operand:DI 0 "register_operand" "")
10312         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10313                          (match_operand:DI 1 "register_operand" "")
10314                          (match_dup 0)))
10315    (set (match_dup 1)
10316         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10317                          (match_operand:DI 3 "register_operand" "r")
10318                          (match_dup 1)))]
10319   "TARGET_64BIT"
10320   "")
10322 (define_expand "ashldi3"
10323   [(set (match_operand:DI 0 "shiftdi_operand" "")
10324         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10325                    (match_operand:QI 2 "nonmemory_operand" "")))]
10326   ""
10327   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10329 (define_insn "*ashldi3_1_rex64"
10330   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10331         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10332                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10336   switch (get_attr_type (insn))
10337     {
10338     case TYPE_ALU:
10339       gcc_assert (operands[2] == const1_rtx);
10340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10341       return "add{q}\t{%0, %0|%0, %0}";
10343     case TYPE_LEA:
10344       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10345       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10346       operands[1] = gen_rtx_MULT (DImode, operands[1],
10347                                   GEN_INT (1 << INTVAL (operands[2])));
10348       return "lea{q}\t{%a1, %0|%0, %a1}";
10350     default:
10351       if (REG_P (operands[2]))
10352         return "sal{q}\t{%b2, %0|%0, %b2}";
10353       else if (operands[2] == const1_rtx
10354                && (TARGET_SHIFT1 || optimize_size))
10355         return "sal{q}\t%0";
10356       else
10357         return "sal{q}\t{%2, %0|%0, %2}";
10358     }
10360   [(set (attr "type")
10361      (cond [(eq_attr "alternative" "1")
10362               (const_string "lea")
10363             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10364                           (const_int 0))
10365                       (match_operand 0 "register_operand" ""))
10366                  (match_operand 2 "const1_operand" ""))
10367               (const_string "alu")
10368            ]
10369            (const_string "ishift")))
10370    (set_attr "mode" "DI")])
10372 ;; Convert lea to the lea pattern to avoid flags dependency.
10373 (define_split
10374   [(set (match_operand:DI 0 "register_operand" "")
10375         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10376                    (match_operand:QI 2 "immediate_operand" "")))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT && reload_completed
10379    && true_regnum (operands[0]) != true_regnum (operands[1])"
10380   [(set (match_dup 0)
10381         (mult:DI (match_dup 1)
10382                  (match_dup 2)))]
10383   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10385 ;; This pattern can't accept a variable shift count, since shifts by
10386 ;; zero don't affect the flags.  We assume that shifts by constant
10387 ;; zero are optimized away.
10388 (define_insn "*ashldi3_cmp_rex64"
10389   [(set (reg FLAGS_REG)
10390         (compare
10391           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10392                      (match_operand:QI 2 "immediate_operand" "e"))
10393           (const_int 0)))
10394    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10395         (ashift:DI (match_dup 1) (match_dup 2)))]
10396   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10397    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10399   switch (get_attr_type (insn))
10400     {
10401     case TYPE_ALU:
10402       gcc_assert (operands[2] == const1_rtx);
10403       return "add{q}\t{%0, %0|%0, %0}";
10405     default:
10406       if (REG_P (operands[2]))
10407         return "sal{q}\t{%b2, %0|%0, %b2}";
10408       else if (operands[2] == const1_rtx
10409                && (TARGET_SHIFT1 || optimize_size))
10410         return "sal{q}\t%0";
10411       else
10412         return "sal{q}\t{%2, %0|%0, %2}";
10413     }
10415   [(set (attr "type")
10416      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10417                           (const_int 0))
10418                       (match_operand 0 "register_operand" ""))
10419                  (match_operand 2 "const1_operand" ""))
10420               (const_string "alu")
10421            ]
10422            (const_string "ishift")))
10423    (set_attr "mode" "DI")])
10425 (define_insn "*ashldi3_1"
10426   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10427         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10428                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10429    (clobber (reg:CC FLAGS_REG))]
10430   "!TARGET_64BIT"
10431   "#"
10432   [(set_attr "type" "multi")])
10434 ;; By default we don't ask for a scratch register, because when DImode
10435 ;; values are manipulated, registers are already at a premium.  But if
10436 ;; we have one handy, we won't turn it away.
10437 (define_peephole2
10438   [(match_scratch:SI 3 "r")
10439    (parallel [(set (match_operand:DI 0 "register_operand" "")
10440                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10441                               (match_operand:QI 2 "nonmemory_operand" "")))
10442               (clobber (reg:CC FLAGS_REG))])
10443    (match_dup 3)]
10444   "!TARGET_64BIT && TARGET_CMOVE"
10445   [(const_int 0)]
10446   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10448 (define_split
10449   [(set (match_operand:DI 0 "register_operand" "")
10450         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10451                    (match_operand:QI 2 "nonmemory_operand" "")))
10452    (clobber (reg:CC FLAGS_REG))]
10453   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10454                      ? flow2_completed : reload_completed)"
10455   [(const_int 0)]
10456   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10458 (define_insn "x86_shld_1"
10459   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10460         (ior:SI (ashift:SI (match_dup 0)
10461                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10462                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10463                   (minus:QI (const_int 32) (match_dup 2)))))
10464    (clobber (reg:CC FLAGS_REG))]
10465   ""
10466   "@
10467    shld{l}\t{%2, %1, %0|%0, %1, %2}
10468    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10469   [(set_attr "type" "ishift")
10470    (set_attr "prefix_0f" "1")
10471    (set_attr "mode" "SI")
10472    (set_attr "pent_pair" "np")
10473    (set_attr "athlon_decode" "vector")])
10475 (define_expand "x86_shift_adj_1"
10476   [(set (reg:CCZ FLAGS_REG)
10477         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10478                              (const_int 32))
10479                      (const_int 0)))
10480    (set (match_operand:SI 0 "register_operand" "")
10481         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10482                          (match_operand:SI 1 "register_operand" "")
10483                          (match_dup 0)))
10484    (set (match_dup 1)
10485         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10486                          (match_operand:SI 3 "register_operand" "r")
10487                          (match_dup 1)))]
10488   "TARGET_CMOVE"
10489   "")
10491 (define_expand "x86_shift_adj_2"
10492   [(use (match_operand:SI 0 "register_operand" ""))
10493    (use (match_operand:SI 1 "register_operand" ""))
10494    (use (match_operand:QI 2 "register_operand" ""))]
10495   ""
10497   rtx label = gen_label_rtx ();
10498   rtx tmp;
10500   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10502   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10503   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10504   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10505                               gen_rtx_LABEL_REF (VOIDmode, label),
10506                               pc_rtx);
10507   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10508   JUMP_LABEL (tmp) = label;
10510   emit_move_insn (operands[0], operands[1]);
10511   ix86_expand_clear (operands[1]);
10513   emit_label (label);
10514   LABEL_NUSES (label) = 1;
10516   DONE;
10519 (define_expand "ashlsi3"
10520   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10521         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10522                    (match_operand:QI 2 "nonmemory_operand" "")))
10523    (clobber (reg:CC FLAGS_REG))]
10524   ""
10525   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10527 (define_insn "*ashlsi3_1"
10528   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10529         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10530                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10531    (clobber (reg:CC FLAGS_REG))]
10532   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10534   switch (get_attr_type (insn))
10535     {
10536     case TYPE_ALU:
10537       gcc_assert (operands[2] == const1_rtx);
10538       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10539       return "add{l}\t{%0, %0|%0, %0}";
10541     case TYPE_LEA:
10542       return "#";
10544     default:
10545       if (REG_P (operands[2]))
10546         return "sal{l}\t{%b2, %0|%0, %b2}";
10547       else if (operands[2] == const1_rtx
10548                && (TARGET_SHIFT1 || optimize_size))
10549         return "sal{l}\t%0";
10550       else
10551         return "sal{l}\t{%2, %0|%0, %2}";
10552     }
10554   [(set (attr "type")
10555      (cond [(eq_attr "alternative" "1")
10556               (const_string "lea")
10557             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10558                           (const_int 0))
10559                       (match_operand 0 "register_operand" ""))
10560                  (match_operand 2 "const1_operand" ""))
10561               (const_string "alu")
10562            ]
10563            (const_string "ishift")))
10564    (set_attr "mode" "SI")])
10566 ;; Convert lea to the lea pattern to avoid flags dependency.
10567 (define_split
10568   [(set (match_operand 0 "register_operand" "")
10569         (ashift (match_operand 1 "index_register_operand" "")
10570                 (match_operand:QI 2 "const_int_operand" "")))
10571    (clobber (reg:CC FLAGS_REG))]
10572   "reload_completed
10573    && true_regnum (operands[0]) != true_regnum (operands[1])
10574    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10575   [(const_int 0)]
10577   rtx pat;
10578   enum machine_mode mode = GET_MODE (operands[0]);
10580   if (GET_MODE_SIZE (mode) < 4)
10581     operands[0] = gen_lowpart (SImode, operands[0]);
10582   if (mode != Pmode)
10583     operands[1] = gen_lowpart (Pmode, operands[1]);
10584   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10586   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10587   if (Pmode != SImode)
10588     pat = gen_rtx_SUBREG (SImode, pat, 0);
10589   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10590   DONE;
10593 ;; Rare case of shifting RSP is handled by generating move and shift
10594 (define_split
10595   [(set (match_operand 0 "register_operand" "")
10596         (ashift (match_operand 1 "register_operand" "")
10597                 (match_operand:QI 2 "const_int_operand" "")))
10598    (clobber (reg:CC FLAGS_REG))]
10599   "reload_completed
10600    && true_regnum (operands[0]) != true_regnum (operands[1])"
10601   [(const_int 0)]
10603   rtx pat, clob;
10604   emit_move_insn (operands[0], operands[1]);
10605   pat = gen_rtx_SET (VOIDmode, operands[0],
10606                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10607                                      operands[0], operands[2]));
10608   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10609   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10610   DONE;
10613 (define_insn "*ashlsi3_1_zext"
10614   [(set (match_operand:DI 0 "register_operand" "=r,r")
10615         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10616                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10620   switch (get_attr_type (insn))
10621     {
10622     case TYPE_ALU:
10623       gcc_assert (operands[2] == const1_rtx);
10624       return "add{l}\t{%k0, %k0|%k0, %k0}";
10626     case TYPE_LEA:
10627       return "#";
10629     default:
10630       if (REG_P (operands[2]))
10631         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10632       else if (operands[2] == const1_rtx
10633                && (TARGET_SHIFT1 || optimize_size))
10634         return "sal{l}\t%k0";
10635       else
10636         return "sal{l}\t{%2, %k0|%k0, %2}";
10637     }
10639   [(set (attr "type")
10640      (cond [(eq_attr "alternative" "1")
10641               (const_string "lea")
10642             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10643                      (const_int 0))
10644                  (match_operand 2 "const1_operand" ""))
10645               (const_string "alu")
10646            ]
10647            (const_string "ishift")))
10648    (set_attr "mode" "SI")])
10650 ;; Convert lea to the lea pattern to avoid flags dependency.
10651 (define_split
10652   [(set (match_operand:DI 0 "register_operand" "")
10653         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10654                                 (match_operand:QI 2 "const_int_operand" ""))))
10655    (clobber (reg:CC FLAGS_REG))]
10656   "TARGET_64BIT && reload_completed
10657    && true_regnum (operands[0]) != true_regnum (operands[1])"
10658   [(set (match_dup 0) (zero_extend:DI
10659                         (subreg:SI (mult:SI (match_dup 1)
10660                                             (match_dup 2)) 0)))]
10662   operands[1] = gen_lowpart (Pmode, operands[1]);
10663   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10666 ;; This pattern can't accept a variable shift count, since shifts by
10667 ;; zero don't affect the flags.  We assume that shifts by constant
10668 ;; zero are optimized away.
10669 (define_insn "*ashlsi3_cmp"
10670   [(set (reg FLAGS_REG)
10671         (compare
10672           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10673                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10674           (const_int 0)))
10675    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10676         (ashift:SI (match_dup 1) (match_dup 2)))]
10677   "ix86_match_ccmode (insn, CCGOCmode)
10678    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10680   switch (get_attr_type (insn))
10681     {
10682     case TYPE_ALU:
10683       gcc_assert (operands[2] == const1_rtx);
10684       return "add{l}\t{%0, %0|%0, %0}";
10686     default:
10687       if (REG_P (operands[2]))
10688         return "sal{l}\t{%b2, %0|%0, %b2}";
10689       else if (operands[2] == const1_rtx
10690                && (TARGET_SHIFT1 || optimize_size))
10691         return "sal{l}\t%0";
10692       else
10693         return "sal{l}\t{%2, %0|%0, %2}";
10694     }
10696   [(set (attr "type")
10697      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10698                           (const_int 0))
10699                       (match_operand 0 "register_operand" ""))
10700                  (match_operand 2 "const1_operand" ""))
10701               (const_string "alu")
10702            ]
10703            (const_string "ishift")))
10704    (set_attr "mode" "SI")])
10706 (define_insn "*ashlsi3_cmp_zext"
10707   [(set (reg FLAGS_REG)
10708         (compare
10709           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10710                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10711           (const_int 0)))
10712    (set (match_operand:DI 0 "register_operand" "=r")
10713         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10714   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10715    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10717   switch (get_attr_type (insn))
10718     {
10719     case TYPE_ALU:
10720       gcc_assert (operands[2] == const1_rtx);
10721       return "add{l}\t{%k0, %k0|%k0, %k0}";
10723     default:
10724       if (REG_P (operands[2]))
10725         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10726       else if (operands[2] == const1_rtx
10727                && (TARGET_SHIFT1 || optimize_size))
10728         return "sal{l}\t%k0";
10729       else
10730         return "sal{l}\t{%2, %k0|%k0, %2}";
10731     }
10733   [(set (attr "type")
10734      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10735                      (const_int 0))
10736                  (match_operand 2 "const1_operand" ""))
10737               (const_string "alu")
10738            ]
10739            (const_string "ishift")))
10740    (set_attr "mode" "SI")])
10742 (define_expand "ashlhi3"
10743   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10744         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10745                    (match_operand:QI 2 "nonmemory_operand" "")))
10746    (clobber (reg:CC FLAGS_REG))]
10747   "TARGET_HIMODE_MATH"
10748   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10750 (define_insn "*ashlhi3_1_lea"
10751   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10752         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10753                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10754    (clobber (reg:CC FLAGS_REG))]
10755   "!TARGET_PARTIAL_REG_STALL
10756    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10758   switch (get_attr_type (insn))
10759     {
10760     case TYPE_LEA:
10761       return "#";
10762     case TYPE_ALU:
10763       gcc_assert (operands[2] == const1_rtx);
10764       return "add{w}\t{%0, %0|%0, %0}";
10766     default:
10767       if (REG_P (operands[2]))
10768         return "sal{w}\t{%b2, %0|%0, %b2}";
10769       else if (operands[2] == const1_rtx
10770                && (TARGET_SHIFT1 || optimize_size))
10771         return "sal{w}\t%0";
10772       else
10773         return "sal{w}\t{%2, %0|%0, %2}";
10774     }
10776   [(set (attr "type")
10777      (cond [(eq_attr "alternative" "1")
10778               (const_string "lea")
10779             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10780                           (const_int 0))
10781                       (match_operand 0 "register_operand" ""))
10782                  (match_operand 2 "const1_operand" ""))
10783               (const_string "alu")
10784            ]
10785            (const_string "ishift")))
10786    (set_attr "mode" "HI,SI")])
10788 (define_insn "*ashlhi3_1"
10789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10790         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10791                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10792    (clobber (reg:CC FLAGS_REG))]
10793   "TARGET_PARTIAL_REG_STALL
10794    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10796   switch (get_attr_type (insn))
10797     {
10798     case TYPE_ALU:
10799       gcc_assert (operands[2] == const1_rtx);
10800       return "add{w}\t{%0, %0|%0, %0}";
10802     default:
10803       if (REG_P (operands[2]))
10804         return "sal{w}\t{%b2, %0|%0, %b2}";
10805       else if (operands[2] == const1_rtx
10806                && (TARGET_SHIFT1 || optimize_size))
10807         return "sal{w}\t%0";
10808       else
10809         return "sal{w}\t{%2, %0|%0, %2}";
10810     }
10812   [(set (attr "type")
10813      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10814                           (const_int 0))
10815                       (match_operand 0 "register_operand" ""))
10816                  (match_operand 2 "const1_operand" ""))
10817               (const_string "alu")
10818            ]
10819            (const_string "ishift")))
10820    (set_attr "mode" "HI")])
10822 ;; This pattern can't accept a variable shift count, since shifts by
10823 ;; zero don't affect the flags.  We assume that shifts by constant
10824 ;; zero are optimized away.
10825 (define_insn "*ashlhi3_cmp"
10826   [(set (reg FLAGS_REG)
10827         (compare
10828           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10829                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10830           (const_int 0)))
10831    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10832         (ashift:HI (match_dup 1) (match_dup 2)))]
10833   "ix86_match_ccmode (insn, CCGOCmode)
10834    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10836   switch (get_attr_type (insn))
10837     {
10838     case TYPE_ALU:
10839       gcc_assert (operands[2] == const1_rtx);
10840       return "add{w}\t{%0, %0|%0, %0}";
10842     default:
10843       if (REG_P (operands[2]))
10844         return "sal{w}\t{%b2, %0|%0, %b2}";
10845       else if (operands[2] == const1_rtx
10846                && (TARGET_SHIFT1 || optimize_size))
10847         return "sal{w}\t%0";
10848       else
10849         return "sal{w}\t{%2, %0|%0, %2}";
10850     }
10852   [(set (attr "type")
10853      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10854                           (const_int 0))
10855                       (match_operand 0 "register_operand" ""))
10856                  (match_operand 2 "const1_operand" ""))
10857               (const_string "alu")
10858            ]
10859            (const_string "ishift")))
10860    (set_attr "mode" "HI")])
10862 (define_expand "ashlqi3"
10863   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10864         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10865                    (match_operand:QI 2 "nonmemory_operand" "")))
10866    (clobber (reg:CC FLAGS_REG))]
10867   "TARGET_QIMODE_MATH"
10868   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10870 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10872 (define_insn "*ashlqi3_1_lea"
10873   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10874         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10875                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "!TARGET_PARTIAL_REG_STALL
10878    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10880   switch (get_attr_type (insn))
10881     {
10882     case TYPE_LEA:
10883       return "#";
10884     case TYPE_ALU:
10885       gcc_assert (operands[2] == const1_rtx);
10886       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10887         return "add{l}\t{%k0, %k0|%k0, %k0}";
10888       else
10889         return "add{b}\t{%0, %0|%0, %0}";
10891     default:
10892       if (REG_P (operands[2]))
10893         {
10894           if (get_attr_mode (insn) == MODE_SI)
10895             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10896           else
10897             return "sal{b}\t{%b2, %0|%0, %b2}";
10898         }
10899       else if (operands[2] == const1_rtx
10900                && (TARGET_SHIFT1 || optimize_size))
10901         {
10902           if (get_attr_mode (insn) == MODE_SI)
10903             return "sal{l}\t%0";
10904           else
10905             return "sal{b}\t%0";
10906         }
10907       else
10908         {
10909           if (get_attr_mode (insn) == MODE_SI)
10910             return "sal{l}\t{%2, %k0|%k0, %2}";
10911           else
10912             return "sal{b}\t{%2, %0|%0, %2}";
10913         }
10914     }
10916   [(set (attr "type")
10917      (cond [(eq_attr "alternative" "2")
10918               (const_string "lea")
10919             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10920                           (const_int 0))
10921                       (match_operand 0 "register_operand" ""))
10922                  (match_operand 2 "const1_operand" ""))
10923               (const_string "alu")
10924            ]
10925            (const_string "ishift")))
10926    (set_attr "mode" "QI,SI,SI")])
10928 (define_insn "*ashlqi3_1"
10929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10930         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10931                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10932    (clobber (reg:CC FLAGS_REG))]
10933   "TARGET_PARTIAL_REG_STALL
10934    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10936   switch (get_attr_type (insn))
10937     {
10938     case TYPE_ALU:
10939       gcc_assert (operands[2] == const1_rtx);
10940       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10941         return "add{l}\t{%k0, %k0|%k0, %k0}";
10942       else
10943         return "add{b}\t{%0, %0|%0, %0}";
10945     default:
10946       if (REG_P (operands[2]))
10947         {
10948           if (get_attr_mode (insn) == MODE_SI)
10949             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10950           else
10951             return "sal{b}\t{%b2, %0|%0, %b2}";
10952         }
10953       else if (operands[2] == const1_rtx
10954                && (TARGET_SHIFT1 || optimize_size))
10955         {
10956           if (get_attr_mode (insn) == MODE_SI)
10957             return "sal{l}\t%0";
10958           else
10959             return "sal{b}\t%0";
10960         }
10961       else
10962         {
10963           if (get_attr_mode (insn) == MODE_SI)
10964             return "sal{l}\t{%2, %k0|%k0, %2}";
10965           else
10966             return "sal{b}\t{%2, %0|%0, %2}";
10967         }
10968     }
10970   [(set (attr "type")
10971      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10972                           (const_int 0))
10973                       (match_operand 0 "register_operand" ""))
10974                  (match_operand 2 "const1_operand" ""))
10975               (const_string "alu")
10976            ]
10977            (const_string "ishift")))
10978    (set_attr "mode" "QI,SI")])
10980 ;; This pattern can't accept a variable shift count, since shifts by
10981 ;; zero don't affect the flags.  We assume that shifts by constant
10982 ;; zero are optimized away.
10983 (define_insn "*ashlqi3_cmp"
10984   [(set (reg FLAGS_REG)
10985         (compare
10986           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10987                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10988           (const_int 0)))
10989    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10990         (ashift:QI (match_dup 1) (match_dup 2)))]
10991   "ix86_match_ccmode (insn, CCGOCmode)
10992    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10994   switch (get_attr_type (insn))
10995     {
10996     case TYPE_ALU:
10997       gcc_assert (operands[2] == const1_rtx);
10998       return "add{b}\t{%0, %0|%0, %0}";
11000     default:
11001       if (REG_P (operands[2]))
11002         return "sal{b}\t{%b2, %0|%0, %b2}";
11003       else if (operands[2] == const1_rtx
11004                && (TARGET_SHIFT1 || optimize_size))
11005         return "sal{b}\t%0";
11006       else
11007         return "sal{b}\t{%2, %0|%0, %2}";
11008     }
11010   [(set (attr "type")
11011      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11012                           (const_int 0))
11013                       (match_operand 0 "register_operand" ""))
11014                  (match_operand 2 "const1_operand" ""))
11015               (const_string "alu")
11016            ]
11017            (const_string "ishift")))
11018    (set_attr "mode" "QI")])
11020 ;; See comment above `ashldi3' about how this works.
11022 (define_expand "ashrti3"
11023   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11024                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11025                                 (match_operand:QI 2 "nonmemory_operand" "")))
11026               (clobber (reg:CC FLAGS_REG))])]
11027   "TARGET_64BIT"
11029   if (! immediate_operand (operands[2], QImode))
11030     {
11031       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11032       DONE;
11033     }
11034   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11035   DONE;
11038 (define_insn "ashrti3_1"
11039   [(set (match_operand:TI 0 "register_operand" "=r")
11040         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11041                      (match_operand:QI 2 "register_operand" "c")))
11042    (clobber (match_scratch:DI 3 "=&r"))
11043    (clobber (reg:CC FLAGS_REG))]
11044   "TARGET_64BIT"
11045   "#"
11046   [(set_attr "type" "multi")])
11048 (define_insn "*ashrti3_2"
11049   [(set (match_operand:TI 0 "register_operand" "=r")
11050         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11051                      (match_operand:QI 2 "immediate_operand" "O")))
11052    (clobber (reg:CC FLAGS_REG))]
11053   "TARGET_64BIT"
11054   "#"
11055   [(set_attr "type" "multi")])
11057 (define_split
11058   [(set (match_operand:TI 0 "register_operand" "")
11059         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11060                      (match_operand:QI 2 "register_operand" "")))
11061    (clobber (match_scratch:DI 3 ""))
11062    (clobber (reg:CC FLAGS_REG))]
11063   "TARGET_64BIT && reload_completed"
11064   [(const_int 0)]
11065   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11067 (define_split
11068   [(set (match_operand:TI 0 "register_operand" "")
11069         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11070                      (match_operand:QI 2 "immediate_operand" "")))
11071    (clobber (reg:CC FLAGS_REG))]
11072   "TARGET_64BIT && reload_completed"
11073   [(const_int 0)]
11074   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11076 (define_insn "x86_64_shrd"
11077   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11078         (ior:DI (ashiftrt:DI (match_dup 0)
11079                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11080                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11081                   (minus:QI (const_int 64) (match_dup 2)))))
11082    (clobber (reg:CC FLAGS_REG))]
11083   "TARGET_64BIT"
11084   "@
11085    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11086    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11087   [(set_attr "type" "ishift")
11088    (set_attr "prefix_0f" "1")
11089    (set_attr "mode" "DI")
11090    (set_attr "athlon_decode" "vector")])
11092 (define_expand "ashrdi3"
11093   [(set (match_operand:DI 0 "shiftdi_operand" "")
11094         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11095                      (match_operand:QI 2 "nonmemory_operand" "")))]
11096   ""
11097   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11099 (define_insn "*ashrdi3_63_rex64"
11100   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11101         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11102                      (match_operand:DI 2 "const_int_operand" "i,i")))
11103    (clobber (reg:CC FLAGS_REG))]
11104   "TARGET_64BIT && INTVAL (operands[2]) == 63
11105    && (TARGET_USE_CLTD || optimize_size)
11106    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11107   "@
11108    {cqto|cqo}
11109    sar{q}\t{%2, %0|%0, %2}"
11110   [(set_attr "type" "imovx,ishift")
11111    (set_attr "prefix_0f" "0,*")
11112    (set_attr "length_immediate" "0,*")
11113    (set_attr "modrm" "0,1")
11114    (set_attr "mode" "DI")])
11116 (define_insn "*ashrdi3_1_one_bit_rex64"
11117   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11118         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11119                      (match_operand:QI 2 "const1_operand" "")))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11122    && (TARGET_SHIFT1 || optimize_size)"
11123   "sar{q}\t%0"
11124   [(set_attr "type" "ishift")
11125    (set (attr "length") 
11126      (if_then_else (match_operand:DI 0 "register_operand" "") 
11127         (const_string "2")
11128         (const_string "*")))])
11130 (define_insn "*ashrdi3_1_rex64"
11131   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11132         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11133                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11134    (clobber (reg:CC FLAGS_REG))]
11135   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11136   "@
11137    sar{q}\t{%2, %0|%0, %2}
11138    sar{q}\t{%b2, %0|%0, %b2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "mode" "DI")])
11142 ;; This pattern can't accept a variable shift count, since shifts by
11143 ;; zero don't affect the flags.  We assume that shifts by constant
11144 ;; zero are optimized away.
11145 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11146   [(set (reg FLAGS_REG)
11147         (compare
11148           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11149                        (match_operand:QI 2 "const1_operand" ""))
11150           (const_int 0)))
11151    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11152         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11153   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11154    && (TARGET_SHIFT1 || optimize_size)
11155    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11156   "sar{q}\t%0"
11157   [(set_attr "type" "ishift")
11158    (set (attr "length") 
11159      (if_then_else (match_operand:DI 0 "register_operand" "") 
11160         (const_string "2")
11161         (const_string "*")))])
11163 ;; This pattern can't accept a variable shift count, since shifts by
11164 ;; zero don't affect the flags.  We assume that shifts by constant
11165 ;; zero are optimized away.
11166 (define_insn "*ashrdi3_cmp_rex64"
11167   [(set (reg FLAGS_REG)
11168         (compare
11169           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11170                        (match_operand:QI 2 "const_int_operand" "n"))
11171           (const_int 0)))
11172    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11173         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11174   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11175    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11176   "sar{q}\t{%2, %0|%0, %2}"
11177   [(set_attr "type" "ishift")
11178    (set_attr "mode" "DI")])
11180 (define_insn "*ashrdi3_1"
11181   [(set (match_operand:DI 0 "register_operand" "=r")
11182         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11183                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11184    (clobber (reg:CC FLAGS_REG))]
11185   "!TARGET_64BIT"
11186   "#"
11187   [(set_attr "type" "multi")])
11189 ;; By default we don't ask for a scratch register, because when DImode
11190 ;; values are manipulated, registers are already at a premium.  But if
11191 ;; we have one handy, we won't turn it away.
11192 (define_peephole2
11193   [(match_scratch:SI 3 "r")
11194    (parallel [(set (match_operand:DI 0 "register_operand" "")
11195                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11196                                 (match_operand:QI 2 "nonmemory_operand" "")))
11197               (clobber (reg:CC FLAGS_REG))])
11198    (match_dup 3)]
11199   "!TARGET_64BIT && TARGET_CMOVE"
11200   [(const_int 0)]
11201   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11203 (define_split
11204   [(set (match_operand:DI 0 "register_operand" "")
11205         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11206                      (match_operand:QI 2 "nonmemory_operand" "")))
11207    (clobber (reg:CC FLAGS_REG))]
11208   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11209                      ? flow2_completed : reload_completed)"
11210   [(const_int 0)]
11211   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11213 (define_insn "x86_shrd_1"
11214   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11215         (ior:SI (ashiftrt:SI (match_dup 0)
11216                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11217                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11218                   (minus:QI (const_int 32) (match_dup 2)))))
11219    (clobber (reg:CC FLAGS_REG))]
11220   ""
11221   "@
11222    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11223    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11224   [(set_attr "type" "ishift")
11225    (set_attr "prefix_0f" "1")
11226    (set_attr "pent_pair" "np")
11227    (set_attr "mode" "SI")])
11229 (define_expand "x86_shift_adj_3"
11230   [(use (match_operand:SI 0 "register_operand" ""))
11231    (use (match_operand:SI 1 "register_operand" ""))
11232    (use (match_operand:QI 2 "register_operand" ""))]
11233   ""
11235   rtx label = gen_label_rtx ();
11236   rtx tmp;
11238   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11240   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11241   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11242   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11243                               gen_rtx_LABEL_REF (VOIDmode, label),
11244                               pc_rtx);
11245   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11246   JUMP_LABEL (tmp) = label;
11248   emit_move_insn (operands[0], operands[1]);
11249   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11251   emit_label (label);
11252   LABEL_NUSES (label) = 1;
11254   DONE;
11257 (define_insn "ashrsi3_31"
11258   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11259         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11260                      (match_operand:SI 2 "const_int_operand" "i,i")))
11261    (clobber (reg:CC FLAGS_REG))]
11262   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11263    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11264   "@
11265    {cltd|cdq}
11266    sar{l}\t{%2, %0|%0, %2}"
11267   [(set_attr "type" "imovx,ishift")
11268    (set_attr "prefix_0f" "0,*")
11269    (set_attr "length_immediate" "0,*")
11270    (set_attr "modrm" "0,1")
11271    (set_attr "mode" "SI")])
11273 (define_insn "*ashrsi3_31_zext"
11274   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11275         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11276                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11279    && INTVAL (operands[2]) == 31
11280    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11281   "@
11282    {cltd|cdq}
11283    sar{l}\t{%2, %k0|%k0, %2}"
11284   [(set_attr "type" "imovx,ishift")
11285    (set_attr "prefix_0f" "0,*")
11286    (set_attr "length_immediate" "0,*")
11287    (set_attr "modrm" "0,1")
11288    (set_attr "mode" "SI")])
11290 (define_expand "ashrsi3"
11291   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11292         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11293                      (match_operand:QI 2 "nonmemory_operand" "")))
11294    (clobber (reg:CC FLAGS_REG))]
11295   ""
11296   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11298 (define_insn "*ashrsi3_1_one_bit"
11299   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11300         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const1_operand" "")))
11302    (clobber (reg:CC FLAGS_REG))]
11303   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11304    && (TARGET_SHIFT1 || optimize_size)"
11305   "sar{l}\t%0"
11306   [(set_attr "type" "ishift")
11307    (set (attr "length") 
11308      (if_then_else (match_operand:SI 0 "register_operand" "") 
11309         (const_string "2")
11310         (const_string "*")))])
11312 (define_insn "*ashrsi3_1_one_bit_zext"
11313   [(set (match_operand:DI 0 "register_operand" "=r")
11314         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11315                                      (match_operand:QI 2 "const1_operand" ""))))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11318    && (TARGET_SHIFT1 || optimize_size)"
11319   "sar{l}\t%k0"
11320   [(set_attr "type" "ishift")
11321    (set_attr "length" "2")])
11323 (define_insn "*ashrsi3_1"
11324   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11325         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11326                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11327    (clobber (reg:CC FLAGS_REG))]
11328   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329   "@
11330    sar{l}\t{%2, %0|%0, %2}
11331    sar{l}\t{%b2, %0|%0, %b2}"
11332   [(set_attr "type" "ishift")
11333    (set_attr "mode" "SI")])
11335 (define_insn "*ashrsi3_1_zext"
11336   [(set (match_operand:DI 0 "register_operand" "=r,r")
11337         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11338                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11339    (clobber (reg:CC FLAGS_REG))]
11340   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11341   "@
11342    sar{l}\t{%2, %k0|%k0, %2}
11343    sar{l}\t{%b2, %k0|%k0, %b2}"
11344   [(set_attr "type" "ishift")
11345    (set_attr "mode" "SI")])
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags.  We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrsi3_one_bit_cmp"
11351   [(set (reg FLAGS_REG)
11352         (compare
11353           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11354                        (match_operand:QI 2 "const1_operand" ""))
11355           (const_int 0)))
11356    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11357         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11358   "ix86_match_ccmode (insn, CCGOCmode)
11359    && (TARGET_SHIFT1 || optimize_size)
11360    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11361   "sar{l}\t%0"
11362   [(set_attr "type" "ishift")
11363    (set (attr "length") 
11364      (if_then_else (match_operand:SI 0 "register_operand" "") 
11365         (const_string "2")
11366         (const_string "*")))])
11368 (define_insn "*ashrsi3_one_bit_cmp_zext"
11369   [(set (reg FLAGS_REG)
11370         (compare
11371           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11372                        (match_operand:QI 2 "const1_operand" ""))
11373           (const_int 0)))
11374    (set (match_operand:DI 0 "register_operand" "=r")
11375         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11376   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11377    && (TARGET_SHIFT1 || optimize_size)
11378    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11379   "sar{l}\t%k0"
11380   [(set_attr "type" "ishift")
11381    (set_attr "length" "2")])
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags.  We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrsi3_cmp"
11387   [(set (reg FLAGS_REG)
11388         (compare
11389           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11390                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11391           (const_int 0)))
11392    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11393         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11394   "ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11396   "sar{l}\t{%2, %0|%0, %2}"
11397   [(set_attr "type" "ishift")
11398    (set_attr "mode" "SI")])
11400 (define_insn "*ashrsi3_cmp_zext"
11401   [(set (reg FLAGS_REG)
11402         (compare
11403           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11404                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11405           (const_int 0)))
11406    (set (match_operand:DI 0 "register_operand" "=r")
11407         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11408   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11409    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11410   "sar{l}\t{%2, %k0|%k0, %2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "SI")])
11414 (define_expand "ashrhi3"
11415   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11416         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11417                      (match_operand:QI 2 "nonmemory_operand" "")))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "TARGET_HIMODE_MATH"
11420   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11422 (define_insn "*ashrhi3_1_one_bit"
11423   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11424         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11425                      (match_operand:QI 2 "const1_operand" "")))
11426    (clobber (reg:CC FLAGS_REG))]
11427   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11428    && (TARGET_SHIFT1 || optimize_size)"
11429   "sar{w}\t%0"
11430   [(set_attr "type" "ishift")
11431    (set (attr "length") 
11432      (if_then_else (match_operand 0 "register_operand" "") 
11433         (const_string "2")
11434         (const_string "*")))])
11436 (define_insn "*ashrhi3_1"
11437   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11438         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11439                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11440    (clobber (reg:CC FLAGS_REG))]
11441   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11442   "@
11443    sar{w}\t{%2, %0|%0, %2}
11444    sar{w}\t{%b2, %0|%0, %b2}"
11445   [(set_attr "type" "ishift")
11446    (set_attr "mode" "HI")])
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags.  We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*ashrhi3_one_bit_cmp"
11452   [(set (reg FLAGS_REG)
11453         (compare
11454           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11455                        (match_operand:QI 2 "const1_operand" ""))
11456           (const_int 0)))
11457    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11458         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11459   "ix86_match_ccmode (insn, CCGOCmode)
11460    && (TARGET_SHIFT1 || optimize_size)
11461    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11462   "sar{w}\t%0"
11463   [(set_attr "type" "ishift")
11464    (set (attr "length") 
11465      (if_then_else (match_operand 0 "register_operand" "") 
11466         (const_string "2")
11467         (const_string "*")))])
11469 ;; This pattern can't accept a variable shift count, since shifts by
11470 ;; zero don't affect the flags.  We assume that shifts by constant
11471 ;; zero are optimized away.
11472 (define_insn "*ashrhi3_cmp"
11473   [(set (reg FLAGS_REG)
11474         (compare
11475           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11477           (const_int 0)))
11478    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11479         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11480   "ix86_match_ccmode (insn, CCGOCmode)
11481    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11482   "sar{w}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "ishift")
11484    (set_attr "mode" "HI")])
11486 (define_expand "ashrqi3"
11487   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11488         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11489                      (match_operand:QI 2 "nonmemory_operand" "")))
11490    (clobber (reg:CC FLAGS_REG))]
11491   "TARGET_QIMODE_MATH"
11492   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11494 (define_insn "*ashrqi3_1_one_bit"
11495   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11496         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11497                      (match_operand:QI 2 "const1_operand" "")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11500    && (TARGET_SHIFT1 || optimize_size)"
11501   "sar{b}\t%0"
11502   [(set_attr "type" "ishift")
11503    (set (attr "length") 
11504      (if_then_else (match_operand 0 "register_operand" "") 
11505         (const_string "2")
11506         (const_string "*")))])
11508 (define_insn "*ashrqi3_1_one_bit_slp"
11509   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11510         (ashiftrt:QI (match_dup 0)
11511                      (match_operand:QI 1 "const1_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11514    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11515    && (TARGET_SHIFT1 || optimize_size)"
11516   "sar{b}\t%0"
11517   [(set_attr "type" "ishift1")
11518    (set (attr "length") 
11519      (if_then_else (match_operand 0 "register_operand" "") 
11520         (const_string "2")
11521         (const_string "*")))])
11523 (define_insn "*ashrqi3_1"
11524   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11525         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11526                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11527    (clobber (reg:CC FLAGS_REG))]
11528   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11529   "@
11530    sar{b}\t{%2, %0|%0, %2}
11531    sar{b}\t{%b2, %0|%0, %b2}"
11532   [(set_attr "type" "ishift")
11533    (set_attr "mode" "QI")])
11535 (define_insn "*ashrqi3_1_slp"
11536   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11537         (ashiftrt:QI (match_dup 0)
11538                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11539    (clobber (reg:CC FLAGS_REG))]
11540   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11541    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11542   "@
11543    sar{b}\t{%1, %0|%0, %1}
11544    sar{b}\t{%b1, %0|%0, %b1}"
11545   [(set_attr "type" "ishift1")
11546    (set_attr "mode" "QI")])
11548 ;; This pattern can't accept a variable shift count, since shifts by
11549 ;; zero don't affect the flags.  We assume that shifts by constant
11550 ;; zero are optimized away.
11551 (define_insn "*ashrqi3_one_bit_cmp"
11552   [(set (reg FLAGS_REG)
11553         (compare
11554           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11555                        (match_operand:QI 2 "const1_operand" "I"))
11556           (const_int 0)))
11557    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11558         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11559   "ix86_match_ccmode (insn, CCGOCmode)
11560    && (TARGET_SHIFT1 || optimize_size)
11561    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11562   "sar{b}\t%0"
11563   [(set_attr "type" "ishift")
11564    (set (attr "length") 
11565      (if_then_else (match_operand 0 "register_operand" "") 
11566         (const_string "2")
11567         (const_string "*")))])
11569 ;; This pattern can't accept a variable shift count, since shifts by
11570 ;; zero don't affect the flags.  We assume that shifts by constant
11571 ;; zero are optimized away.
11572 (define_insn "*ashrqi3_cmp"
11573   [(set (reg FLAGS_REG)
11574         (compare
11575           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11576                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11577           (const_int 0)))
11578    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11579         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11580   "ix86_match_ccmode (insn, CCGOCmode)
11581    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11582   "sar{b}\t{%2, %0|%0, %2}"
11583   [(set_attr "type" "ishift")
11584    (set_attr "mode" "QI")])
11586 ;; Logical shift instructions
11588 ;; See comment above `ashldi3' about how this works.
11590 (define_expand "lshrti3"
11591   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11592                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11593                                 (match_operand:QI 2 "nonmemory_operand" "")))
11594               (clobber (reg:CC FLAGS_REG))])]
11595   "TARGET_64BIT"
11597   if (! immediate_operand (operands[2], QImode))
11598     {
11599       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11600       DONE;
11601     }
11602   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11603   DONE;
11606 (define_insn "lshrti3_1"
11607   [(set (match_operand:TI 0 "register_operand" "=r")
11608         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11609                      (match_operand:QI 2 "register_operand" "c")))
11610    (clobber (match_scratch:DI 3 "=&r"))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "TARGET_64BIT"
11613   "#"
11614   [(set_attr "type" "multi")])
11616 (define_insn "*lshrti3_2"
11617   [(set (match_operand:TI 0 "register_operand" "=r")
11618         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11619                      (match_operand:QI 2 "immediate_operand" "O")))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT"
11622   "#"
11623   [(set_attr "type" "multi")])
11625 (define_split 
11626   [(set (match_operand:TI 0 "register_operand" "")
11627         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11628                      (match_operand:QI 2 "register_operand" "")))
11629    (clobber (match_scratch:DI 3 ""))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && reload_completed"
11632   [(const_int 0)]
11633   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11635 (define_split 
11636   [(set (match_operand:TI 0 "register_operand" "")
11637         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11638                      (match_operand:QI 2 "immediate_operand" "")))
11639    (clobber (reg:CC FLAGS_REG))]
11640   "TARGET_64BIT && reload_completed"
11641   [(const_int 0)]
11642   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11644 (define_expand "lshrdi3"
11645   [(set (match_operand:DI 0 "shiftdi_operand" "")
11646         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11647                      (match_operand:QI 2 "nonmemory_operand" "")))]
11648   ""
11649   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11651 (define_insn "*lshrdi3_1_one_bit_rex64"
11652   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11653         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11654                      (match_operand:QI 2 "const1_operand" "")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11657    && (TARGET_SHIFT1 || optimize_size)"
11658   "shr{q}\t%0"
11659   [(set_attr "type" "ishift")
11660    (set (attr "length") 
11661      (if_then_else (match_operand:DI 0 "register_operand" "") 
11662         (const_string "2")
11663         (const_string "*")))])
11665 (define_insn "*lshrdi3_1_rex64"
11666   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11667         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11668                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11671   "@
11672    shr{q}\t{%2, %0|%0, %2}
11673    shr{q}\t{%b2, %0|%0, %b2}"
11674   [(set_attr "type" "ishift")
11675    (set_attr "mode" "DI")])
11677 ;; This pattern can't accept a variable shift count, since shifts by
11678 ;; zero don't affect the flags.  We assume that shifts by constant
11679 ;; zero are optimized away.
11680 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684                        (match_operand:QI 2 "const1_operand" ""))
11685           (const_int 0)))
11686    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11687         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11688   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11689    && (TARGET_SHIFT1 || optimize_size)
11690    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11691   "shr{q}\t%0"
11692   [(set_attr "type" "ishift")
11693    (set (attr "length") 
11694      (if_then_else (match_operand:DI 0 "register_operand" "") 
11695         (const_string "2")
11696         (const_string "*")))])
11698 ;; This pattern can't accept a variable shift count, since shifts by
11699 ;; zero don't affect the flags.  We assume that shifts by constant
11700 ;; zero are optimized away.
11701 (define_insn "*lshrdi3_cmp_rex64"
11702   [(set (reg FLAGS_REG)
11703         (compare
11704           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11705                        (match_operand:QI 2 "const_int_operand" "e"))
11706           (const_int 0)))
11707    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11708         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11709   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11711   "shr{q}\t{%2, %0|%0, %2}"
11712   [(set_attr "type" "ishift")
11713    (set_attr "mode" "DI")])
11715 (define_insn "*lshrdi3_1"
11716   [(set (match_operand:DI 0 "register_operand" "=r")
11717         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11718                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "!TARGET_64BIT"
11721   "#"
11722   [(set_attr "type" "multi")])
11724 ;; By default we don't ask for a scratch register, because when DImode
11725 ;; values are manipulated, registers are already at a premium.  But if
11726 ;; we have one handy, we won't turn it away.
11727 (define_peephole2
11728   [(match_scratch:SI 3 "r")
11729    (parallel [(set (match_operand:DI 0 "register_operand" "")
11730                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11731                                 (match_operand:QI 2 "nonmemory_operand" "")))
11732               (clobber (reg:CC FLAGS_REG))])
11733    (match_dup 3)]
11734   "!TARGET_64BIT && TARGET_CMOVE"
11735   [(const_int 0)]
11736   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11738 (define_split 
11739   [(set (match_operand:DI 0 "register_operand" "")
11740         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11741                      (match_operand:QI 2 "nonmemory_operand" "")))
11742    (clobber (reg:CC FLAGS_REG))]
11743   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11744                      ? flow2_completed : reload_completed)"
11745   [(const_int 0)]
11746   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11748 (define_expand "lshrsi3"
11749   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11750         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11751                      (match_operand:QI 2 "nonmemory_operand" "")))
11752    (clobber (reg:CC FLAGS_REG))]
11753   ""
11754   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11756 (define_insn "*lshrsi3_1_one_bit"
11757   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11758         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11759                      (match_operand:QI 2 "const1_operand" "")))
11760    (clobber (reg:CC FLAGS_REG))]
11761   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11762    && (TARGET_SHIFT1 || optimize_size)"
11763   "shr{l}\t%0"
11764   [(set_attr "type" "ishift")
11765    (set (attr "length") 
11766      (if_then_else (match_operand:SI 0 "register_operand" "") 
11767         (const_string "2")
11768         (const_string "*")))])
11770 (define_insn "*lshrsi3_1_one_bit_zext"
11771   [(set (match_operand:DI 0 "register_operand" "=r")
11772         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11773                      (match_operand:QI 2 "const1_operand" "")))
11774    (clobber (reg:CC FLAGS_REG))]
11775   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11776    && (TARGET_SHIFT1 || optimize_size)"
11777   "shr{l}\t%k0"
11778   [(set_attr "type" "ishift")
11779    (set_attr "length" "2")])
11781 (define_insn "*lshrsi3_1"
11782   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11783         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11784                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11787   "@
11788    shr{l}\t{%2, %0|%0, %2}
11789    shr{l}\t{%b2, %0|%0, %b2}"
11790   [(set_attr "type" "ishift")
11791    (set_attr "mode" "SI")])
11793 (define_insn "*lshrsi3_1_zext"
11794   [(set (match_operand:DI 0 "register_operand" "=r,r")
11795         (zero_extend:DI
11796           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11797                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11798    (clobber (reg:CC FLAGS_REG))]
11799   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11800   "@
11801    shr{l}\t{%2, %k0|%k0, %2}
11802    shr{l}\t{%b2, %k0|%k0, %b2}"
11803   [(set_attr "type" "ishift")
11804    (set_attr "mode" "SI")])
11806 ;; This pattern can't accept a variable shift count, since shifts by
11807 ;; zero don't affect the flags.  We assume that shifts by constant
11808 ;; zero are optimized away.
11809 (define_insn "*lshrsi3_one_bit_cmp"
11810   [(set (reg FLAGS_REG)
11811         (compare
11812           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11813                        (match_operand:QI 2 "const1_operand" ""))
11814           (const_int 0)))
11815    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11816         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11817   "ix86_match_ccmode (insn, CCGOCmode)
11818    && (TARGET_SHIFT1 || optimize_size)
11819    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11820   "shr{l}\t%0"
11821   [(set_attr "type" "ishift")
11822    (set (attr "length") 
11823      (if_then_else (match_operand:SI 0 "register_operand" "") 
11824         (const_string "2")
11825         (const_string "*")))])
11827 (define_insn "*lshrsi3_cmp_one_bit_zext"
11828   [(set (reg FLAGS_REG)
11829         (compare
11830           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11831                        (match_operand:QI 2 "const1_operand" ""))
11832           (const_int 0)))
11833    (set (match_operand:DI 0 "register_operand" "=r")
11834         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11835   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11836    && (TARGET_SHIFT1 || optimize_size)
11837    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11838   "shr{l}\t%k0"
11839   [(set_attr "type" "ishift")
11840    (set_attr "length" "2")])
11842 ;; This pattern can't accept a variable shift count, since shifts by
11843 ;; zero don't affect the flags.  We assume that shifts by constant
11844 ;; zero are optimized away.
11845 (define_insn "*lshrsi3_cmp"
11846   [(set (reg FLAGS_REG)
11847         (compare
11848           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11849                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11850           (const_int 0)))
11851    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11852         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11853   "ix86_match_ccmode (insn, CCGOCmode)
11854    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11855   "shr{l}\t{%2, %0|%0, %2}"
11856   [(set_attr "type" "ishift")
11857    (set_attr "mode" "SI")])
11859 (define_insn "*lshrsi3_cmp_zext"
11860   [(set (reg FLAGS_REG)
11861         (compare
11862           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11863                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864           (const_int 0)))
11865    (set (match_operand:DI 0 "register_operand" "=r")
11866         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11867   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11868    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11869   "shr{l}\t{%2, %k0|%k0, %2}"
11870   [(set_attr "type" "ishift")
11871    (set_attr "mode" "SI")])
11873 (define_expand "lshrhi3"
11874   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11875         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11876                      (match_operand:QI 2 "nonmemory_operand" "")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "TARGET_HIMODE_MATH"
11879   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11881 (define_insn "*lshrhi3_1_one_bit"
11882   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11883         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11884                      (match_operand:QI 2 "const1_operand" "")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11887    && (TARGET_SHIFT1 || optimize_size)"
11888   "shr{w}\t%0"
11889   [(set_attr "type" "ishift")
11890    (set (attr "length") 
11891      (if_then_else (match_operand 0 "register_operand" "") 
11892         (const_string "2")
11893         (const_string "*")))])
11895 (define_insn "*lshrhi3_1"
11896   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11897         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11898                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11901   "@
11902    shr{w}\t{%2, %0|%0, %2}
11903    shr{w}\t{%b2, %0|%0, %b2}"
11904   [(set_attr "type" "ishift")
11905    (set_attr "mode" "HI")])
11907 ;; This pattern can't accept a variable shift count, since shifts by
11908 ;; zero don't affect the flags.  We assume that shifts by constant
11909 ;; zero are optimized away.
11910 (define_insn "*lshrhi3_one_bit_cmp"
11911   [(set (reg FLAGS_REG)
11912         (compare
11913           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11914                        (match_operand:QI 2 "const1_operand" ""))
11915           (const_int 0)))
11916    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11917         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11918   "ix86_match_ccmode (insn, CCGOCmode)
11919    && (TARGET_SHIFT1 || optimize_size)
11920    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11921   "shr{w}\t%0"
11922   [(set_attr "type" "ishift")
11923    (set (attr "length") 
11924      (if_then_else (match_operand:SI 0 "register_operand" "") 
11925         (const_string "2")
11926         (const_string "*")))])
11928 ;; This pattern can't accept a variable shift count, since shifts by
11929 ;; zero don't affect the flags.  We assume that shifts by constant
11930 ;; zero are optimized away.
11931 (define_insn "*lshrhi3_cmp"
11932   [(set (reg FLAGS_REG)
11933         (compare
11934           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11935                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11936           (const_int 0)))
11937    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11938         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11939   "ix86_match_ccmode (insn, CCGOCmode)
11940    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11941   "shr{w}\t{%2, %0|%0, %2}"
11942   [(set_attr "type" "ishift")
11943    (set_attr "mode" "HI")])
11945 (define_expand "lshrqi3"
11946   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11947         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11948                      (match_operand:QI 2 "nonmemory_operand" "")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "TARGET_QIMODE_MATH"
11951   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11953 (define_insn "*lshrqi3_1_one_bit"
11954   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11955         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11956                      (match_operand:QI 2 "const1_operand" "")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11959    && (TARGET_SHIFT1 || optimize_size)"
11960   "shr{b}\t%0"
11961   [(set_attr "type" "ishift")
11962    (set (attr "length") 
11963      (if_then_else (match_operand 0 "register_operand" "") 
11964         (const_string "2")
11965         (const_string "*")))])
11967 (define_insn "*lshrqi3_1_one_bit_slp"
11968   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11969         (lshiftrt:QI (match_dup 0)
11970                      (match_operand:QI 1 "const1_operand" "")))
11971    (clobber (reg:CC FLAGS_REG))]
11972   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11973    && (TARGET_SHIFT1 || optimize_size)"
11974   "shr{b}\t%0"
11975   [(set_attr "type" "ishift1")
11976    (set (attr "length") 
11977      (if_then_else (match_operand 0 "register_operand" "") 
11978         (const_string "2")
11979         (const_string "*")))])
11981 (define_insn "*lshrqi3_1"
11982   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11983         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11984                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11985    (clobber (reg:CC FLAGS_REG))]
11986   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11987   "@
11988    shr{b}\t{%2, %0|%0, %2}
11989    shr{b}\t{%b2, %0|%0, %b2}"
11990   [(set_attr "type" "ishift")
11991    (set_attr "mode" "QI")])
11993 (define_insn "*lshrqi3_1_slp"
11994   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11995         (lshiftrt:QI (match_dup 0)
11996                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11999    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12000   "@
12001    shr{b}\t{%1, %0|%0, %1}
12002    shr{b}\t{%b1, %0|%0, %b1}"
12003   [(set_attr "type" "ishift1")
12004    (set_attr "mode" "QI")])
12006 ;; This pattern can't accept a variable shift count, since shifts by
12007 ;; zero don't affect the flags.  We assume that shifts by constant
12008 ;; zero are optimized away.
12009 (define_insn "*lshrqi2_one_bit_cmp"
12010   [(set (reg FLAGS_REG)
12011         (compare
12012           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12013                        (match_operand:QI 2 "const1_operand" ""))
12014           (const_int 0)))
12015    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12016         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12017   "ix86_match_ccmode (insn, CCGOCmode)
12018    && (TARGET_SHIFT1 || optimize_size)
12019    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12020   "shr{b}\t%0"
12021   [(set_attr "type" "ishift")
12022    (set (attr "length") 
12023      (if_then_else (match_operand:SI 0 "register_operand" "") 
12024         (const_string "2")
12025         (const_string "*")))])
12027 ;; This pattern can't accept a variable shift count, since shifts by
12028 ;; zero don't affect the flags.  We assume that shifts by constant
12029 ;; zero are optimized away.
12030 (define_insn "*lshrqi2_cmp"
12031   [(set (reg FLAGS_REG)
12032         (compare
12033           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12034                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12035           (const_int 0)))
12036    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12037         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12038   "ix86_match_ccmode (insn, CCGOCmode)
12039    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12040   "shr{b}\t{%2, %0|%0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "QI")])
12044 ;; Rotate instructions
12046 (define_expand "rotldi3"
12047   [(set (match_operand:DI 0 "shiftdi_operand" "")
12048         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12049                    (match_operand:QI 2 "nonmemory_operand" "")))
12050    (clobber (reg:CC FLAGS_REG))]
12051  ""
12053   if (TARGET_64BIT)
12054     {
12055       ix86_expand_binary_operator (ROTATE, DImode, operands);
12056       DONE;
12057     }
12058   if (!const_1_to_31_operand (operands[2], VOIDmode))
12059     FAIL;
12060   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12061   DONE;
12064 ;; Implement rotation using two double-precision shift instructions
12065 ;; and a scratch register.   
12066 (define_insn_and_split "ix86_rotldi3"
12067  [(set (match_operand:DI 0 "register_operand" "=r")
12068        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12069                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12070   (clobber (reg:CC FLAGS_REG))
12071   (clobber (match_scratch:SI 3 "=&r"))]
12072  "!TARGET_64BIT"
12073  "" 
12074  "&& reload_completed"
12075  [(set (match_dup 3) (match_dup 4))
12076   (parallel
12077    [(set (match_dup 4)
12078          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12079                  (lshiftrt:SI (match_dup 5)
12080                               (minus:QI (const_int 32) (match_dup 2)))))
12081     (clobber (reg:CC FLAGS_REG))])
12082   (parallel
12083    [(set (match_dup 5)
12084          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12085                  (lshiftrt:SI (match_dup 3)
12086                               (minus:QI (const_int 32) (match_dup 2)))))
12087     (clobber (reg:CC FLAGS_REG))])]
12088  "split_di (operands, 1, operands + 4, operands + 5);")
12090 (define_insn "*rotlsi3_1_one_bit_rex64"
12091   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12092         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093                    (match_operand:QI 2 "const1_operand" "")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12096    && (TARGET_SHIFT1 || optimize_size)"
12097   "rol{q}\t%0"
12098   [(set_attr "type" "rotate")
12099    (set (attr "length") 
12100      (if_then_else (match_operand:DI 0 "register_operand" "") 
12101         (const_string "2")
12102         (const_string "*")))])
12104 (define_insn "*rotldi3_1_rex64"
12105   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12106         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12107                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12110   "@
12111    rol{q}\t{%2, %0|%0, %2}
12112    rol{q}\t{%b2, %0|%0, %b2}"
12113   [(set_attr "type" "rotate")
12114    (set_attr "mode" "DI")])
12116 (define_expand "rotlsi3"
12117   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12118         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12119                    (match_operand:QI 2 "nonmemory_operand" "")))
12120    (clobber (reg:CC FLAGS_REG))]
12121   ""
12122   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12124 (define_insn "*rotlsi3_1_one_bit"
12125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12126         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12127                    (match_operand:QI 2 "const1_operand" "")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12130    && (TARGET_SHIFT1 || optimize_size)"
12131   "rol{l}\t%0"
12132   [(set_attr "type" "rotate")
12133    (set (attr "length") 
12134      (if_then_else (match_operand:SI 0 "register_operand" "") 
12135         (const_string "2")
12136         (const_string "*")))])
12138 (define_insn "*rotlsi3_1_one_bit_zext"
12139   [(set (match_operand:DI 0 "register_operand" "=r")
12140         (zero_extend:DI
12141           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12142                      (match_operand:QI 2 "const1_operand" ""))))
12143    (clobber (reg:CC FLAGS_REG))]
12144   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12145    && (TARGET_SHIFT1 || optimize_size)"
12146   "rol{l}\t%k0"
12147   [(set_attr "type" "rotate")
12148    (set_attr "length" "2")])
12150 (define_insn "*rotlsi3_1"
12151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12152         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12153                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12156   "@
12157    rol{l}\t{%2, %0|%0, %2}
12158    rol{l}\t{%b2, %0|%0, %b2}"
12159   [(set_attr "type" "rotate")
12160    (set_attr "mode" "SI")])
12162 (define_insn "*rotlsi3_1_zext"
12163   [(set (match_operand:DI 0 "register_operand" "=r,r")
12164         (zero_extend:DI
12165           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12166                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12169   "@
12170    rol{l}\t{%2, %k0|%k0, %2}
12171    rol{l}\t{%b2, %k0|%k0, %b2}"
12172   [(set_attr "type" "rotate")
12173    (set_attr "mode" "SI")])
12175 (define_expand "rotlhi3"
12176   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12177         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12178                    (match_operand:QI 2 "nonmemory_operand" "")))
12179    (clobber (reg:CC FLAGS_REG))]
12180   "TARGET_HIMODE_MATH"
12181   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12183 (define_insn "*rotlhi3_1_one_bit"
12184   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12185         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12186                    (match_operand:QI 2 "const1_operand" "")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12189    && (TARGET_SHIFT1 || optimize_size)"
12190   "rol{w}\t%0"
12191   [(set_attr "type" "rotate")
12192    (set (attr "length") 
12193      (if_then_else (match_operand 0 "register_operand" "") 
12194         (const_string "2")
12195         (const_string "*")))])
12197 (define_insn "*rotlhi3_1"
12198   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12199         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12200                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12203   "@
12204    rol{w}\t{%2, %0|%0, %2}
12205    rol{w}\t{%b2, %0|%0, %b2}"
12206   [(set_attr "type" "rotate")
12207    (set_attr "mode" "HI")])
12209 (define_expand "rotlqi3"
12210   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12211         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12212                    (match_operand:QI 2 "nonmemory_operand" "")))
12213    (clobber (reg:CC FLAGS_REG))]
12214   "TARGET_QIMODE_MATH"
12215   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12217 (define_insn "*rotlqi3_1_one_bit_slp"
12218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12219         (rotate:QI (match_dup 0)
12220                    (match_operand:QI 1 "const1_operand" "")))
12221    (clobber (reg:CC FLAGS_REG))]
12222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12223    && (TARGET_SHIFT1 || optimize_size)"
12224   "rol{b}\t%0"
12225   [(set_attr "type" "rotate1")
12226    (set (attr "length") 
12227      (if_then_else (match_operand 0 "register_operand" "") 
12228         (const_string "2")
12229         (const_string "*")))])
12231 (define_insn "*rotlqi3_1_one_bit"
12232   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12233         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12234                    (match_operand:QI 2 "const1_operand" "")))
12235    (clobber (reg:CC FLAGS_REG))]
12236   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12237    && (TARGET_SHIFT1 || optimize_size)"
12238   "rol{b}\t%0"
12239   [(set_attr "type" "rotate")
12240    (set (attr "length") 
12241      (if_then_else (match_operand 0 "register_operand" "") 
12242         (const_string "2")
12243         (const_string "*")))])
12245 (define_insn "*rotlqi3_1_slp"
12246   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247         (rotate:QI (match_dup 0)
12248                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12252   "@
12253    rol{b}\t{%1, %0|%0, %1}
12254    rol{b}\t{%b1, %0|%0, %b1}"
12255   [(set_attr "type" "rotate1")
12256    (set_attr "mode" "QI")])
12258 (define_insn "*rotlqi3_1"
12259   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12260         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12261                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12264   "@
12265    rol{b}\t{%2, %0|%0, %2}
12266    rol{b}\t{%b2, %0|%0, %b2}"
12267   [(set_attr "type" "rotate")
12268    (set_attr "mode" "QI")])
12270 (define_expand "rotrdi3"
12271   [(set (match_operand:DI 0 "shiftdi_operand" "")
12272         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12273                    (match_operand:QI 2 "nonmemory_operand" "")))
12274    (clobber (reg:CC FLAGS_REG))]
12275  ""
12277   if (TARGET_64BIT)
12278     {
12279       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12280       DONE;
12281     }
12282   if (!const_1_to_31_operand (operands[2], VOIDmode))
12283     FAIL;
12284   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12285   DONE;
12287   
12288 ;; Implement rotation using two double-precision shift instructions
12289 ;; and a scratch register.   
12290 (define_insn_and_split "ix86_rotrdi3"
12291  [(set (match_operand:DI 0 "register_operand" "=r")
12292        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12293                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12294   (clobber (reg:CC FLAGS_REG))
12295   (clobber (match_scratch:SI 3 "=&r"))]
12296  "!TARGET_64BIT"
12297  ""
12298  "&& reload_completed"
12299  [(set (match_dup 3) (match_dup 4))
12300   (parallel
12301    [(set (match_dup 4)
12302          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12303                  (ashift:SI (match_dup 5)
12304                             (minus:QI (const_int 32) (match_dup 2)))))
12305     (clobber (reg:CC FLAGS_REG))])
12306   (parallel
12307    [(set (match_dup 5)
12308          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12309                  (ashift:SI (match_dup 3)
12310                             (minus:QI (const_int 32) (match_dup 2)))))
12311     (clobber (reg:CC FLAGS_REG))])]
12312  "split_di (operands, 1, operands + 4, operands + 5);")
12314 (define_insn "*rotrdi3_1_one_bit_rex64"
12315   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12316         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12317                      (match_operand:QI 2 "const1_operand" "")))
12318    (clobber (reg:CC FLAGS_REG))]
12319   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12320    && (TARGET_SHIFT1 || optimize_size)"
12321   "ror{q}\t%0"
12322   [(set_attr "type" "rotate")
12323    (set (attr "length") 
12324      (if_then_else (match_operand:DI 0 "register_operand" "") 
12325         (const_string "2")
12326         (const_string "*")))])
12328 (define_insn "*rotrdi3_1_rex64"
12329   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12330         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12331                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12334   "@
12335    ror{q}\t{%2, %0|%0, %2}
12336    ror{q}\t{%b2, %0|%0, %b2}"
12337   [(set_attr "type" "rotate")
12338    (set_attr "mode" "DI")])
12340 (define_expand "rotrsi3"
12341   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12342         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12343                      (match_operand:QI 2 "nonmemory_operand" "")))
12344    (clobber (reg:CC FLAGS_REG))]
12345   ""
12346   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12348 (define_insn "*rotrsi3_1_one_bit"
12349   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12350         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12351                      (match_operand:QI 2 "const1_operand" "")))
12352    (clobber (reg:CC FLAGS_REG))]
12353   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12354    && (TARGET_SHIFT1 || optimize_size)"
12355   "ror{l}\t%0"
12356   [(set_attr "type" "rotate")
12357    (set (attr "length") 
12358      (if_then_else (match_operand:SI 0 "register_operand" "") 
12359         (const_string "2")
12360         (const_string "*")))])
12362 (define_insn "*rotrsi3_1_one_bit_zext"
12363   [(set (match_operand:DI 0 "register_operand" "=r")
12364         (zero_extend:DI
12365           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12366                        (match_operand:QI 2 "const1_operand" ""))))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12369    && (TARGET_SHIFT1 || optimize_size)"
12370   "ror{l}\t%k0"
12371   [(set_attr "type" "rotate")
12372    (set (attr "length") 
12373      (if_then_else (match_operand:SI 0 "register_operand" "") 
12374         (const_string "2")
12375         (const_string "*")))])
12377 (define_insn "*rotrsi3_1"
12378   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12379         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12380                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12383   "@
12384    ror{l}\t{%2, %0|%0, %2}
12385    ror{l}\t{%b2, %0|%0, %b2}"
12386   [(set_attr "type" "rotate")
12387    (set_attr "mode" "SI")])
12389 (define_insn "*rotrsi3_1_zext"
12390   [(set (match_operand:DI 0 "register_operand" "=r,r")
12391         (zero_extend:DI
12392           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12393                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12394    (clobber (reg:CC FLAGS_REG))]
12395   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12396   "@
12397    ror{l}\t{%2, %k0|%k0, %2}
12398    ror{l}\t{%b2, %k0|%k0, %b2}"
12399   [(set_attr "type" "rotate")
12400    (set_attr "mode" "SI")])
12402 (define_expand "rotrhi3"
12403   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12404         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12405                      (match_operand:QI 2 "nonmemory_operand" "")))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "TARGET_HIMODE_MATH"
12408   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12410 (define_insn "*rotrhi3_one_bit"
12411   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12412         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12413                      (match_operand:QI 2 "const1_operand" "")))
12414    (clobber (reg:CC FLAGS_REG))]
12415   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12416    && (TARGET_SHIFT1 || optimize_size)"
12417   "ror{w}\t%0"
12418   [(set_attr "type" "rotate")
12419    (set (attr "length") 
12420      (if_then_else (match_operand 0 "register_operand" "") 
12421         (const_string "2")
12422         (const_string "*")))])
12424 (define_insn "*rotrhi3"
12425   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12426         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12427                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12428    (clobber (reg:CC FLAGS_REG))]
12429   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12430   "@
12431    ror{w}\t{%2, %0|%0, %2}
12432    ror{w}\t{%b2, %0|%0, %b2}"
12433   [(set_attr "type" "rotate")
12434    (set_attr "mode" "HI")])
12436 (define_expand "rotrqi3"
12437   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12438         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12439                      (match_operand:QI 2 "nonmemory_operand" "")))
12440    (clobber (reg:CC FLAGS_REG))]
12441   "TARGET_QIMODE_MATH"
12442   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12444 (define_insn "*rotrqi3_1_one_bit"
12445   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12446         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447                      (match_operand:QI 2 "const1_operand" "")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12450    && (TARGET_SHIFT1 || optimize_size)"
12451   "ror{b}\t%0"
12452   [(set_attr "type" "rotate")
12453    (set (attr "length") 
12454      (if_then_else (match_operand 0 "register_operand" "") 
12455         (const_string "2")
12456         (const_string "*")))])
12458 (define_insn "*rotrqi3_1_one_bit_slp"
12459   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12460         (rotatert:QI (match_dup 0)
12461                      (match_operand:QI 1 "const1_operand" "")))
12462    (clobber (reg:CC FLAGS_REG))]
12463   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12464    && (TARGET_SHIFT1 || optimize_size)"
12465   "ror{b}\t%0"
12466   [(set_attr "type" "rotate1")
12467    (set (attr "length") 
12468      (if_then_else (match_operand 0 "register_operand" "") 
12469         (const_string "2")
12470         (const_string "*")))])
12472 (define_insn "*rotrqi3_1"
12473   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12474         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12475                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12478   "@
12479    ror{b}\t{%2, %0|%0, %2}
12480    ror{b}\t{%b2, %0|%0, %b2}"
12481   [(set_attr "type" "rotate")
12482    (set_attr "mode" "QI")])
12484 (define_insn "*rotrqi3_1_slp"
12485   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12486         (rotatert:QI (match_dup 0)
12487                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12488    (clobber (reg:CC FLAGS_REG))]
12489   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12490    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12491   "@
12492    ror{b}\t{%1, %0|%0, %1}
12493    ror{b}\t{%b1, %0|%0, %b1}"
12494   [(set_attr "type" "rotate1")
12495    (set_attr "mode" "QI")])
12497 ;; Bit set / bit test instructions
12499 (define_expand "extv"
12500   [(set (match_operand:SI 0 "register_operand" "")
12501         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12502                          (match_operand:SI 2 "immediate_operand" "")
12503                          (match_operand:SI 3 "immediate_operand" "")))]
12504   ""
12506   /* Handle extractions from %ah et al.  */
12507   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12508     FAIL;
12510   /* From mips.md: extract_bit_field doesn't verify that our source
12511      matches the predicate, so check it again here.  */
12512   if (! ext_register_operand (operands[1], VOIDmode))
12513     FAIL;
12516 (define_expand "extzv"
12517   [(set (match_operand:SI 0 "register_operand" "")
12518         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12519                          (match_operand:SI 2 "immediate_operand" "")
12520                          (match_operand:SI 3 "immediate_operand" "")))]
12521   ""
12523   /* Handle extractions from %ah et al.  */
12524   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12525     FAIL;
12527   /* From mips.md: extract_bit_field doesn't verify that our source
12528      matches the predicate, so check it again here.  */
12529   if (! ext_register_operand (operands[1], VOIDmode))
12530     FAIL;
12533 (define_expand "insv"
12534   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12535                       (match_operand 1 "immediate_operand" "")
12536                       (match_operand 2 "immediate_operand" ""))
12537         (match_operand 3 "register_operand" ""))]
12538   ""
12540   /* Handle extractions from %ah et al.  */
12541   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12542     FAIL;
12544   /* From mips.md: insert_bit_field doesn't verify that our source
12545      matches the predicate, so check it again here.  */
12546   if (! ext_register_operand (operands[0], VOIDmode))
12547     FAIL;
12549   if (TARGET_64BIT)
12550     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12551   else
12552     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12554   DONE;
12557 ;; %%% bts, btr, btc, bt.
12558 ;; In general these instructions are *slow* when applied to memory,
12559 ;; since they enforce atomic operation.  When applied to registers,
12560 ;; it depends on the cpu implementation.  They're never faster than
12561 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12562 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12563 ;; within the instruction itself, so operating on bits in the high
12564 ;; 32-bits of a register becomes easier.
12566 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12567 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12568 ;; negdf respectively, so they can never be disabled entirely.
12570 (define_insn "*btsq"
12571   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12572                          (const_int 1)
12573                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12574         (const_int 1))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12577   "bts{q} %1,%0"
12578   [(set_attr "type" "alu1")])
12580 (define_insn "*btrq"
12581   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12582                          (const_int 1)
12583                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12584         (const_int 0))
12585    (clobber (reg:CC FLAGS_REG))]
12586   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12587   "btr{q} %1,%0"
12588   [(set_attr "type" "alu1")])
12590 (define_insn "*btcq"
12591   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12592                          (const_int 1)
12593                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12594         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12597   "btc{q} %1,%0"
12598   [(set_attr "type" "alu1")])
12600 ;; Allow Nocona to avoid these instructions if a register is available.
12602 (define_peephole2
12603   [(match_scratch:DI 2 "r")
12604    (parallel [(set (zero_extract:DI
12605                      (match_operand:DI 0 "register_operand" "")
12606                      (const_int 1)
12607                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12608                    (const_int 1))
12609               (clobber (reg:CC FLAGS_REG))])]
12610   "TARGET_64BIT && !TARGET_USE_BT"
12611   [(const_int 0)]
12613   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12614   rtx op1;
12616   if (HOST_BITS_PER_WIDE_INT >= 64)
12617     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12618   else if (i < HOST_BITS_PER_WIDE_INT)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else
12621     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12623   op1 = immed_double_const (lo, hi, DImode);
12624   if (i >= 31)
12625     {
12626       emit_move_insn (operands[2], op1);
12627       op1 = operands[2];
12628     }
12630   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12631   DONE;
12634 (define_peephole2
12635   [(match_scratch:DI 2 "r")
12636    (parallel [(set (zero_extract:DI
12637                      (match_operand:DI 0 "register_operand" "")
12638                      (const_int 1)
12639                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12640                    (const_int 0))
12641               (clobber (reg:CC FLAGS_REG))])]
12642   "TARGET_64BIT && !TARGET_USE_BT"
12643   [(const_int 0)]
12645   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12646   rtx op1;
12648   if (HOST_BITS_PER_WIDE_INT >= 64)
12649     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12650   else if (i < HOST_BITS_PER_WIDE_INT)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else
12653     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655   op1 = immed_double_const (~lo, ~hi, DImode);
12656   if (i >= 32)
12657     {
12658       emit_move_insn (operands[2], op1);
12659       op1 = operands[2];
12660     }
12662   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12663   DONE;
12666 (define_peephole2
12667   [(match_scratch:DI 2 "r")
12668    (parallel [(set (zero_extract:DI
12669                      (match_operand:DI 0 "register_operand" "")
12670                      (const_int 1)
12671                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12672               (not:DI (zero_extract:DI
12673                         (match_dup 0) (const_int 1) (match_dup 1))))
12674               (clobber (reg:CC FLAGS_REG))])]
12675   "TARGET_64BIT && !TARGET_USE_BT"
12676   [(const_int 0)]
12678   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12679   rtx op1;
12681   if (HOST_BITS_PER_WIDE_INT >= 64)
12682     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12683   else if (i < HOST_BITS_PER_WIDE_INT)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else
12686     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12688   op1 = immed_double_const (lo, hi, DImode);
12689   if (i >= 31)
12690     {
12691       emit_move_insn (operands[2], op1);
12692       op1 = operands[2];
12693     }
12695   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12696   DONE;
12699 ;; Store-flag instructions.
12701 ;; For all sCOND expanders, also expand the compare or test insn that
12702 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12704 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12705 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12706 ;; way, which can later delete the movzx if only QImode is needed.
12708 (define_expand "seq"
12709   [(set (match_operand:QI 0 "register_operand" "")
12710         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12711   ""
12712   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12714 (define_expand "sne"
12715   [(set (match_operand:QI 0 "register_operand" "")
12716         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12717   ""
12718   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12720 (define_expand "sgt"
12721   [(set (match_operand:QI 0 "register_operand" "")
12722         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12723   ""
12724   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12726 (define_expand "sgtu"
12727   [(set (match_operand:QI 0 "register_operand" "")
12728         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729   ""
12730   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12732 (define_expand "slt"
12733   [(set (match_operand:QI 0 "register_operand" "")
12734         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735   ""
12736   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12738 (define_expand "sltu"
12739   [(set (match_operand:QI 0 "register_operand" "")
12740         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12741   ""
12742   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12744 (define_expand "sge"
12745   [(set (match_operand:QI 0 "register_operand" "")
12746         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747   ""
12748   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12750 (define_expand "sgeu"
12751   [(set (match_operand:QI 0 "register_operand" "")
12752         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12753   ""
12754   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12756 (define_expand "sle"
12757   [(set (match_operand:QI 0 "register_operand" "")
12758         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12759   ""
12760   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12762 (define_expand "sleu"
12763   [(set (match_operand:QI 0 "register_operand" "")
12764         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12765   ""
12766   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12768 (define_expand "sunordered"
12769   [(set (match_operand:QI 0 "register_operand" "")
12770         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12771   "TARGET_80387 || TARGET_SSE"
12772   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12774 (define_expand "sordered"
12775   [(set (match_operand:QI 0 "register_operand" "")
12776         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12777   "TARGET_80387"
12778   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12780 (define_expand "suneq"
12781   [(set (match_operand:QI 0 "register_operand" "")
12782         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12783   "TARGET_80387 || TARGET_SSE"
12784   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12786 (define_expand "sunge"
12787   [(set (match_operand:QI 0 "register_operand" "")
12788         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12789   "TARGET_80387 || TARGET_SSE"
12790   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12792 (define_expand "sungt"
12793   [(set (match_operand:QI 0 "register_operand" "")
12794         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12795   "TARGET_80387 || TARGET_SSE"
12796   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12798 (define_expand "sunle"
12799   [(set (match_operand:QI 0 "register_operand" "")
12800         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12801   "TARGET_80387 || TARGET_SSE"
12802   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12804 (define_expand "sunlt"
12805   [(set (match_operand:QI 0 "register_operand" "")
12806         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12807   "TARGET_80387 || TARGET_SSE"
12808   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12810 (define_expand "sltgt"
12811   [(set (match_operand:QI 0 "register_operand" "")
12812         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12813   "TARGET_80387 || TARGET_SSE"
12814   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12816 (define_insn "*setcc_1"
12817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12818         (match_operator:QI 1 "ix86_comparison_operator"
12819           [(reg FLAGS_REG) (const_int 0)]))]
12820   ""
12821   "set%C1\t%0"
12822   [(set_attr "type" "setcc")
12823    (set_attr "mode" "QI")])
12825 (define_insn "*setcc_2"
12826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12827         (match_operator:QI 1 "ix86_comparison_operator"
12828           [(reg FLAGS_REG) (const_int 0)]))]
12829   ""
12830   "set%C1\t%0"
12831   [(set_attr "type" "setcc")
12832    (set_attr "mode" "QI")])
12834 ;; In general it is not safe to assume too much about CCmode registers,
12835 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12836 ;; conditions this is safe on x86, so help combine not create
12838 ;;      seta    %al
12839 ;;      testb   %al, %al
12840 ;;      sete    %al
12842 (define_split 
12843   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12844         (ne:QI (match_operator 1 "ix86_comparison_operator"
12845                  [(reg FLAGS_REG) (const_int 0)])
12846             (const_int 0)))]
12847   ""
12848   [(set (match_dup 0) (match_dup 1))]
12850   PUT_MODE (operands[1], QImode);
12853 (define_split 
12854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12855         (ne:QI (match_operator 1 "ix86_comparison_operator"
12856                  [(reg FLAGS_REG) (const_int 0)])
12857             (const_int 0)))]
12858   ""
12859   [(set (match_dup 0) (match_dup 1))]
12861   PUT_MODE (operands[1], QImode);
12864 (define_split 
12865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12866         (eq:QI (match_operator 1 "ix86_comparison_operator"
12867                  [(reg FLAGS_REG) (const_int 0)])
12868             (const_int 0)))]
12869   ""
12870   [(set (match_dup 0) (match_dup 1))]
12872   rtx new_op1 = copy_rtx (operands[1]);
12873   operands[1] = new_op1;
12874   PUT_MODE (new_op1, QImode);
12875   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12876                                              GET_MODE (XEXP (new_op1, 0))));
12878   /* Make sure that (a) the CCmode we have for the flags is strong
12879      enough for the reversed compare or (b) we have a valid FP compare.  */
12880   if (! ix86_comparison_operator (new_op1, VOIDmode))
12881     FAIL;
12884 (define_split 
12885   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12886         (eq:QI (match_operator 1 "ix86_comparison_operator"
12887                  [(reg FLAGS_REG) (const_int 0)])
12888             (const_int 0)))]
12889   ""
12890   [(set (match_dup 0) (match_dup 1))]
12892   rtx new_op1 = copy_rtx (operands[1]);
12893   operands[1] = new_op1;
12894   PUT_MODE (new_op1, QImode);
12895   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12896                                              GET_MODE (XEXP (new_op1, 0))));
12898   /* Make sure that (a) the CCmode we have for the flags is strong
12899      enough for the reversed compare or (b) we have a valid FP compare.  */
12900   if (! ix86_comparison_operator (new_op1, VOIDmode))
12901     FAIL;
12904 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12905 ;; subsequent logical operations are used to imitate conditional moves.
12906 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12907 ;; it directly.
12909 (define_insn "*sse_setccsf"
12910   [(set (match_operand:SF 0 "register_operand" "=x")
12911         (match_operator:SF 1 "sse_comparison_operator"
12912           [(match_operand:SF 2 "register_operand" "0")
12913            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12914   "TARGET_SSE"
12915   "cmp%D1ss\t{%3, %0|%0, %3}"
12916   [(set_attr "type" "ssecmp")
12917    (set_attr "mode" "SF")])
12919 (define_insn "*sse_setccdf"
12920   [(set (match_operand:DF 0 "register_operand" "=Y")
12921         (match_operator:DF 1 "sse_comparison_operator"
12922           [(match_operand:DF 2 "register_operand" "0")
12923            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12924   "TARGET_SSE2"
12925   "cmp%D1sd\t{%3, %0|%0, %3}"
12926   [(set_attr "type" "ssecmp")
12927    (set_attr "mode" "DF")])
12929 ;; Basic conditional jump instructions.
12930 ;; We ignore the overflow flag for signed branch instructions.
12932 ;; For all bCOND expanders, also expand the compare or test insn that
12933 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12935 (define_expand "beq"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   ""
12941   "ix86_expand_branch (EQ, operands[0]); DONE;")
12943 (define_expand "bne"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   ""
12949   "ix86_expand_branch (NE, operands[0]); DONE;")
12951 (define_expand "bgt"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   ""
12957   "ix86_expand_branch (GT, operands[0]); DONE;")
12959 (define_expand "bgtu"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   ""
12965   "ix86_expand_branch (GTU, operands[0]); DONE;")
12967 (define_expand "blt"
12968   [(set (pc)
12969         (if_then_else (match_dup 1)
12970                       (label_ref (match_operand 0 "" ""))
12971                       (pc)))]
12972   ""
12973   "ix86_expand_branch (LT, operands[0]); DONE;")
12975 (define_expand "bltu"
12976   [(set (pc)
12977         (if_then_else (match_dup 1)
12978                       (label_ref (match_operand 0 "" ""))
12979                       (pc)))]
12980   ""
12981   "ix86_expand_branch (LTU, operands[0]); DONE;")
12983 (define_expand "bge"
12984   [(set (pc)
12985         (if_then_else (match_dup 1)
12986                       (label_ref (match_operand 0 "" ""))
12987                       (pc)))]
12988   ""
12989   "ix86_expand_branch (GE, operands[0]); DONE;")
12991 (define_expand "bgeu"
12992   [(set (pc)
12993         (if_then_else (match_dup 1)
12994                       (label_ref (match_operand 0 "" ""))
12995                       (pc)))]
12996   ""
12997   "ix86_expand_branch (GEU, operands[0]); DONE;")
12999 (define_expand "ble"
13000   [(set (pc)
13001         (if_then_else (match_dup 1)
13002                       (label_ref (match_operand 0 "" ""))
13003                       (pc)))]
13004   ""
13005   "ix86_expand_branch (LE, operands[0]); DONE;")
13007 (define_expand "bleu"
13008   [(set (pc)
13009         (if_then_else (match_dup 1)
13010                       (label_ref (match_operand 0 "" ""))
13011                       (pc)))]
13012   ""
13013   "ix86_expand_branch (LEU, operands[0]); DONE;")
13015 (define_expand "bunordered"
13016   [(set (pc)
13017         (if_then_else (match_dup 1)
13018                       (label_ref (match_operand 0 "" ""))
13019                       (pc)))]
13020   "TARGET_80387 || TARGET_SSE_MATH"
13021   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13023 (define_expand "bordered"
13024   [(set (pc)
13025         (if_then_else (match_dup 1)
13026                       (label_ref (match_operand 0 "" ""))
13027                       (pc)))]
13028   "TARGET_80387 || TARGET_SSE_MATH"
13029   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13031 (define_expand "buneq"
13032   [(set (pc)
13033         (if_then_else (match_dup 1)
13034                       (label_ref (match_operand 0 "" ""))
13035                       (pc)))]
13036   "TARGET_80387 || TARGET_SSE_MATH"
13037   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13039 (define_expand "bunge"
13040   [(set (pc)
13041         (if_then_else (match_dup 1)
13042                       (label_ref (match_operand 0 "" ""))
13043                       (pc)))]
13044   "TARGET_80387 || TARGET_SSE_MATH"
13045   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13047 (define_expand "bungt"
13048   [(set (pc)
13049         (if_then_else (match_dup 1)
13050                       (label_ref (match_operand 0 "" ""))
13051                       (pc)))]
13052   "TARGET_80387 || TARGET_SSE_MATH"
13053   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13055 (define_expand "bunle"
13056   [(set (pc)
13057         (if_then_else (match_dup 1)
13058                       (label_ref (match_operand 0 "" ""))
13059                       (pc)))]
13060   "TARGET_80387 || TARGET_SSE_MATH"
13061   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13063 (define_expand "bunlt"
13064   [(set (pc)
13065         (if_then_else (match_dup 1)
13066                       (label_ref (match_operand 0 "" ""))
13067                       (pc)))]
13068   "TARGET_80387 || TARGET_SSE_MATH"
13069   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13071 (define_expand "bltgt"
13072   [(set (pc)
13073         (if_then_else (match_dup 1)
13074                       (label_ref (match_operand 0 "" ""))
13075                       (pc)))]
13076   "TARGET_80387 || TARGET_SSE_MATH"
13077   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13079 (define_insn "*jcc_1"
13080   [(set (pc)
13081         (if_then_else (match_operator 1 "ix86_comparison_operator"
13082                                       [(reg FLAGS_REG) (const_int 0)])
13083                       (label_ref (match_operand 0 "" ""))
13084                       (pc)))]
13085   ""
13086   "%+j%C1\t%l0"
13087   [(set_attr "type" "ibr")
13088    (set_attr "modrm" "0")
13089    (set (attr "length")
13090            (if_then_else (and (ge (minus (match_dup 0) (pc))
13091                                   (const_int -126))
13092                               (lt (minus (match_dup 0) (pc))
13093                                   (const_int 128)))
13094              (const_int 2)
13095              (const_int 6)))])
13097 (define_insn "*jcc_2"
13098   [(set (pc)
13099         (if_then_else (match_operator 1 "ix86_comparison_operator"
13100                                       [(reg FLAGS_REG) (const_int 0)])
13101                       (pc)
13102                       (label_ref (match_operand 0 "" ""))))]
13103   ""
13104   "%+j%c1\t%l0"
13105   [(set_attr "type" "ibr")
13106    (set_attr "modrm" "0")
13107    (set (attr "length")
13108            (if_then_else (and (ge (minus (match_dup 0) (pc))
13109                                   (const_int -126))
13110                               (lt (minus (match_dup 0) (pc))
13111                                   (const_int 128)))
13112              (const_int 2)
13113              (const_int 6)))])
13115 ;; In general it is not safe to assume too much about CCmode registers,
13116 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13117 ;; conditions this is safe on x86, so help combine not create
13119 ;;      seta    %al
13120 ;;      testb   %al, %al
13121 ;;      je      Lfoo
13123 (define_split 
13124   [(set (pc)
13125         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13126                                       [(reg FLAGS_REG) (const_int 0)])
13127                           (const_int 0))
13128                       (label_ref (match_operand 1 "" ""))
13129                       (pc)))]
13130   ""
13131   [(set (pc)
13132         (if_then_else (match_dup 0)
13133                       (label_ref (match_dup 1))
13134                       (pc)))]
13136   PUT_MODE (operands[0], VOIDmode);
13138   
13139 (define_split 
13140   [(set (pc)
13141         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13142                                       [(reg FLAGS_REG) (const_int 0)])
13143                           (const_int 0))
13144                       (label_ref (match_operand 1 "" ""))
13145                       (pc)))]
13146   ""
13147   [(set (pc)
13148         (if_then_else (match_dup 0)
13149                       (label_ref (match_dup 1))
13150                       (pc)))]
13152   rtx new_op0 = copy_rtx (operands[0]);
13153   operands[0] = new_op0;
13154   PUT_MODE (new_op0, VOIDmode);
13155   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13156                                              GET_MODE (XEXP (new_op0, 0))));
13158   /* Make sure that (a) the CCmode we have for the flags is strong
13159      enough for the reversed compare or (b) we have a valid FP compare.  */
13160   if (! ix86_comparison_operator (new_op0, VOIDmode))
13161     FAIL;
13164 ;; Define combination compare-and-branch fp compare instructions to use
13165 ;; during early optimization.  Splitting the operation apart early makes
13166 ;; for bad code when we want to reverse the operation.
13168 (define_insn "*fp_jcc_1_mixed"
13169   [(set (pc)
13170         (if_then_else (match_operator 0 "comparison_operator"
13171                         [(match_operand 1 "register_operand" "f,x")
13172                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13173           (label_ref (match_operand 3 "" ""))
13174           (pc)))
13175    (clobber (reg:CCFP FPSR_REG))
13176    (clobber (reg:CCFP FLAGS_REG))]
13177   "TARGET_MIX_SSE_I387
13178    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13179    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13180    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13181   "#")
13183 (define_insn "*fp_jcc_1_sse"
13184   [(set (pc)
13185         (if_then_else (match_operator 0 "comparison_operator"
13186                         [(match_operand 1 "register_operand" "x")
13187                          (match_operand 2 "nonimmediate_operand" "xm")])
13188           (label_ref (match_operand 3 "" ""))
13189           (pc)))
13190    (clobber (reg:CCFP FPSR_REG))
13191    (clobber (reg:CCFP FLAGS_REG))]
13192   "TARGET_SSE_MATH
13193    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13194    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13195    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13196   "#")
13198 (define_insn "*fp_jcc_1_387"
13199   [(set (pc)
13200         (if_then_else (match_operator 0 "comparison_operator"
13201                         [(match_operand 1 "register_operand" "f")
13202                          (match_operand 2 "register_operand" "f")])
13203           (label_ref (match_operand 3 "" ""))
13204           (pc)))
13205    (clobber (reg:CCFP FPSR_REG))
13206    (clobber (reg:CCFP FLAGS_REG))]
13207   "TARGET_CMOVE && TARGET_80387
13208    && FLOAT_MODE_P (GET_MODE (operands[1]))
13209    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13210    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13211   "#")
13213 (define_insn "*fp_jcc_2_mixed"
13214   [(set (pc)
13215         (if_then_else (match_operator 0 "comparison_operator"
13216                         [(match_operand 1 "register_operand" "f,x")
13217                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13218           (pc)
13219           (label_ref (match_operand 3 "" ""))))
13220    (clobber (reg:CCFP FPSR_REG))
13221    (clobber (reg:CCFP FLAGS_REG))]
13222   "TARGET_MIX_SSE_I387
13223    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13224    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13225    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13226   "#")
13228 (define_insn "*fp_jcc_2_sse"
13229   [(set (pc)
13230         (if_then_else (match_operator 0 "comparison_operator"
13231                         [(match_operand 1 "register_operand" "x")
13232                          (match_operand 2 "nonimmediate_operand" "xm")])
13233           (pc)
13234           (label_ref (match_operand 3 "" ""))))
13235    (clobber (reg:CCFP FPSR_REG))
13236    (clobber (reg:CCFP FLAGS_REG))]
13237   "TARGET_SSE_MATH
13238    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13239    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13240    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13241   "#")
13243 (define_insn "*fp_jcc_2_387"
13244   [(set (pc)
13245         (if_then_else (match_operator 0 "comparison_operator"
13246                         [(match_operand 1 "register_operand" "f")
13247                          (match_operand 2 "register_operand" "f")])
13248           (pc)
13249           (label_ref (match_operand 3 "" ""))))
13250    (clobber (reg:CCFP FPSR_REG))
13251    (clobber (reg:CCFP FLAGS_REG))]
13252   "TARGET_CMOVE && TARGET_80387
13253    && FLOAT_MODE_P (GET_MODE (operands[1]))
13254    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13255    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13256   "#")
13258 (define_insn "*fp_jcc_3_387"
13259   [(set (pc)
13260         (if_then_else (match_operator 0 "comparison_operator"
13261                         [(match_operand 1 "register_operand" "f")
13262                          (match_operand 2 "nonimmediate_operand" "fm")])
13263           (label_ref (match_operand 3 "" ""))
13264           (pc)))
13265    (clobber (reg:CCFP FPSR_REG))
13266    (clobber (reg:CCFP FLAGS_REG))
13267    (clobber (match_scratch:HI 4 "=a"))]
13268   "TARGET_80387
13269    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13270    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13271    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13272    && SELECT_CC_MODE (GET_CODE (operands[0]),
13273                       operands[1], operands[2]) == CCFPmode
13274    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13275   "#")
13277 (define_insn "*fp_jcc_4_387"
13278   [(set (pc)
13279         (if_then_else (match_operator 0 "comparison_operator"
13280                         [(match_operand 1 "register_operand" "f")
13281                          (match_operand 2 "nonimmediate_operand" "fm")])
13282           (pc)
13283           (label_ref (match_operand 3 "" ""))))
13284    (clobber (reg:CCFP FPSR_REG))
13285    (clobber (reg:CCFP FLAGS_REG))
13286    (clobber (match_scratch:HI 4 "=a"))]
13287   "TARGET_80387
13288    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13289    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13290    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13291    && SELECT_CC_MODE (GET_CODE (operands[0]),
13292                       operands[1], operands[2]) == CCFPmode
13293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13294   "#")
13296 (define_insn "*fp_jcc_5_387"
13297   [(set (pc)
13298         (if_then_else (match_operator 0 "comparison_operator"
13299                         [(match_operand 1 "register_operand" "f")
13300                          (match_operand 2 "register_operand" "f")])
13301           (label_ref (match_operand 3 "" ""))
13302           (pc)))
13303    (clobber (reg:CCFP FPSR_REG))
13304    (clobber (reg:CCFP FLAGS_REG))
13305    (clobber (match_scratch:HI 4 "=a"))]
13306   "TARGET_80387
13307    && FLOAT_MODE_P (GET_MODE (operands[1]))
13308    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13309    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13310   "#")
13312 (define_insn "*fp_jcc_6_387"
13313   [(set (pc)
13314         (if_then_else (match_operator 0 "comparison_operator"
13315                         [(match_operand 1 "register_operand" "f")
13316                          (match_operand 2 "register_operand" "f")])
13317           (pc)
13318           (label_ref (match_operand 3 "" ""))))
13319    (clobber (reg:CCFP FPSR_REG))
13320    (clobber (reg:CCFP FLAGS_REG))
13321    (clobber (match_scratch:HI 4 "=a"))]
13322   "TARGET_80387
13323    && FLOAT_MODE_P (GET_MODE (operands[1]))
13324    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13325    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13326   "#")
13328 (define_insn "*fp_jcc_7_387"
13329   [(set (pc)
13330         (if_then_else (match_operator 0 "comparison_operator"
13331                         [(match_operand 1 "register_operand" "f")
13332                          (match_operand 2 "const0_operand" "X")])
13333           (label_ref (match_operand 3 "" ""))
13334           (pc)))
13335    (clobber (reg:CCFP FPSR_REG))
13336    (clobber (reg:CCFP FLAGS_REG))
13337    (clobber (match_scratch:HI 4 "=a"))]
13338   "TARGET_80387
13339    && FLOAT_MODE_P (GET_MODE (operands[1]))
13340    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13341    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13342    && SELECT_CC_MODE (GET_CODE (operands[0]),
13343                       operands[1], operands[2]) == CCFPmode
13344    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13345   "#")
13347 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13348 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13349 ;; with a precedence over other operators and is always put in the first
13350 ;; place. Swap condition and operands to match ficom instruction.
13352 (define_insn "*fp_jcc_8<mode>_387"
13353   [(set (pc)
13354         (if_then_else (match_operator 0 "comparison_operator"
13355                         [(match_operator 1 "float_operator"
13356                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13357                            (match_operand 3 "register_operand" "f,f")])
13358           (label_ref (match_operand 4 "" ""))
13359           (pc)))
13360    (clobber (reg:CCFP FPSR_REG))
13361    (clobber (reg:CCFP FLAGS_REG))
13362    (clobber (match_scratch:HI 5 "=a,a"))]
13363   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13364    && FLOAT_MODE_P (GET_MODE (operands[3]))
13365    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13366    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13367    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13368    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13369   "#")
13371 (define_split
13372   [(set (pc)
13373         (if_then_else (match_operator 0 "comparison_operator"
13374                         [(match_operand 1 "register_operand" "")
13375                          (match_operand 2 "nonimmediate_operand" "")])
13376           (match_operand 3 "" "")
13377           (match_operand 4 "" "")))
13378    (clobber (reg:CCFP FPSR_REG))
13379    (clobber (reg:CCFP FLAGS_REG))]
13380   "reload_completed"
13381   [(const_int 0)]
13383   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13384                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13385   DONE;
13388 (define_split
13389   [(set (pc)
13390         (if_then_else (match_operator 0 "comparison_operator"
13391                         [(match_operand 1 "register_operand" "")
13392                          (match_operand 2 "general_operand" "")])
13393           (match_operand 3 "" "")
13394           (match_operand 4 "" "")))
13395    (clobber (reg:CCFP FPSR_REG))
13396    (clobber (reg:CCFP FLAGS_REG))
13397    (clobber (match_scratch:HI 5 "=a"))]
13398   "reload_completed"
13399   [(const_int 0)]
13401   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13402                         operands[3], operands[4], operands[5], NULL_RTX);
13403   DONE;
13406 (define_split
13407   [(set (pc)
13408         (if_then_else (match_operator 0 "comparison_operator"
13409                         [(match_operator 1 "float_operator"
13410                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13411                            (match_operand 3 "register_operand" "")])
13412           (match_operand 4 "" "")
13413           (match_operand 5 "" "")))
13414    (clobber (reg:CCFP FPSR_REG))
13415    (clobber (reg:CCFP FLAGS_REG))
13416    (clobber (match_scratch:HI 6 "=a"))]
13417   "reload_completed"
13418   [(const_int 0)]
13420   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13421   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13422                         operands[3], operands[7],
13423                         operands[4], operands[5], operands[6], NULL_RTX);
13424   DONE;
13427 ;; %%% Kill this when reload knows how to do it.
13428 (define_split
13429   [(set (pc)
13430         (if_then_else (match_operator 0 "comparison_operator"
13431                         [(match_operator 1 "float_operator"
13432                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13433                            (match_operand 3 "register_operand" "")])
13434           (match_operand 4 "" "")
13435           (match_operand 5 "" "")))
13436    (clobber (reg:CCFP FPSR_REG))
13437    (clobber (reg:CCFP FLAGS_REG))
13438    (clobber (match_scratch:HI 6 "=a"))]
13439   "reload_completed"
13440   [(const_int 0)]
13442   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13443   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13444   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13445                         operands[3], operands[7],
13446                         operands[4], operands[5], operands[6], operands[2]);
13447   DONE;
13450 ;; Unconditional and other jump instructions
13452 (define_insn "jump"
13453   [(set (pc)
13454         (label_ref (match_operand 0 "" "")))]
13455   ""
13456   "jmp\t%l0"
13457   [(set_attr "type" "ibr")
13458    (set (attr "length")
13459            (if_then_else (and (ge (minus (match_dup 0) (pc))
13460                                   (const_int -126))
13461                               (lt (minus (match_dup 0) (pc))
13462                                   (const_int 128)))
13463              (const_int 2)
13464              (const_int 5)))
13465    (set_attr "modrm" "0")])
13467 (define_expand "indirect_jump"
13468   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13469   ""
13470   "")
13472 (define_insn "*indirect_jump"
13473   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13474   "!TARGET_64BIT"
13475   "jmp\t%A0"
13476   [(set_attr "type" "ibr")
13477    (set_attr "length_immediate" "0")])
13479 (define_insn "*indirect_jump_rtx64"
13480   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13481   "TARGET_64BIT"
13482   "jmp\t%A0"
13483   [(set_attr "type" "ibr")
13484    (set_attr "length_immediate" "0")])
13486 (define_expand "tablejump"
13487   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13488               (use (label_ref (match_operand 1 "" "")))])]
13489   ""
13491   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13492      relative.  Convert the relative address to an absolute address.  */
13493   if (flag_pic)
13494     {
13495       rtx op0, op1;
13496       enum rtx_code code;
13498       if (TARGET_64BIT)
13499         {
13500           code = PLUS;
13501           op0 = operands[0];
13502           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13503         }
13504       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13505         {
13506           code = PLUS;
13507           op0 = operands[0];
13508           op1 = pic_offset_table_rtx;
13509         }
13510       else
13511         {
13512           code = MINUS;
13513           op0 = pic_offset_table_rtx;
13514           op1 = operands[0];
13515         }
13517       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13518                                          OPTAB_DIRECT);
13519     }
13522 (define_insn "*tablejump_1"
13523   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13524    (use (label_ref (match_operand 1 "" "")))]
13525   "!TARGET_64BIT"
13526   "jmp\t%A0"
13527   [(set_attr "type" "ibr")
13528    (set_attr "length_immediate" "0")])
13530 (define_insn "*tablejump_1_rtx64"
13531   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13532    (use (label_ref (match_operand 1 "" "")))]
13533   "TARGET_64BIT"
13534   "jmp\t%A0"
13535   [(set_attr "type" "ibr")
13536    (set_attr "length_immediate" "0")])
13538 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13540 (define_peephole2
13541   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13542    (set (match_operand:QI 1 "register_operand" "")
13543         (match_operator:QI 2 "ix86_comparison_operator"
13544           [(reg FLAGS_REG) (const_int 0)]))
13545    (set (match_operand 3 "q_regs_operand" "")
13546         (zero_extend (match_dup 1)))]
13547   "(peep2_reg_dead_p (3, operands[1])
13548     || operands_match_p (operands[1], operands[3]))
13549    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13550   [(set (match_dup 4) (match_dup 0))
13551    (set (strict_low_part (match_dup 5))
13552         (match_dup 2))]
13554   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13555   operands[5] = gen_lowpart (QImode, operands[3]);
13556   ix86_expand_clear (operands[3]);
13559 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13561 (define_peephole2
13562   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13563    (set (match_operand:QI 1 "register_operand" "")
13564         (match_operator:QI 2 "ix86_comparison_operator"
13565           [(reg FLAGS_REG) (const_int 0)]))
13566    (parallel [(set (match_operand 3 "q_regs_operand" "")
13567                    (zero_extend (match_dup 1)))
13568               (clobber (reg:CC FLAGS_REG))])]
13569   "(peep2_reg_dead_p (3, operands[1])
13570     || operands_match_p (operands[1], operands[3]))
13571    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13572   [(set (match_dup 4) (match_dup 0))
13573    (set (strict_low_part (match_dup 5))
13574         (match_dup 2))]
13576   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13577   operands[5] = gen_lowpart (QImode, operands[3]);
13578   ix86_expand_clear (operands[3]);
13581 ;; Call instructions.
13583 ;; The predicates normally associated with named expanders are not properly
13584 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13585 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13587 ;; Call subroutine returning no value.
13589 (define_expand "call_pop"
13590   [(parallel [(call (match_operand:QI 0 "" "")
13591                     (match_operand:SI 1 "" ""))
13592               (set (reg:SI SP_REG)
13593                    (plus:SI (reg:SI SP_REG)
13594                             (match_operand:SI 3 "" "")))])]
13595   "!TARGET_64BIT"
13597   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13598   DONE;
13601 (define_insn "*call_pop_0"
13602   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13603          (match_operand:SI 1 "" ""))
13604    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13605                             (match_operand:SI 2 "immediate_operand" "")))]
13606   "!TARGET_64BIT"
13608   if (SIBLING_CALL_P (insn))
13609     return "jmp\t%P0";
13610   else
13611     return "call\t%P0";
13613   [(set_attr "type" "call")])
13614   
13615 (define_insn "*call_pop_1"
13616   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13617          (match_operand:SI 1 "" ""))
13618    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13619                             (match_operand:SI 2 "immediate_operand" "i")))]
13620   "!TARGET_64BIT"
13622   if (constant_call_address_operand (operands[0], Pmode))
13623     {
13624       if (SIBLING_CALL_P (insn))
13625         return "jmp\t%P0";
13626       else
13627         return "call\t%P0";
13628     }
13629   if (SIBLING_CALL_P (insn))
13630     return "jmp\t%A0";
13631   else
13632     return "call\t%A0";
13634   [(set_attr "type" "call")])
13636 (define_expand "call"
13637   [(call (match_operand:QI 0 "" "")
13638          (match_operand 1 "" ""))
13639    (use (match_operand 2 "" ""))]
13640   ""
13642   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13643   DONE;
13646 (define_expand "sibcall"
13647   [(call (match_operand:QI 0 "" "")
13648          (match_operand 1 "" ""))
13649    (use (match_operand 2 "" ""))]
13650   ""
13652   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13653   DONE;
13656 (define_insn "*call_0"
13657   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13658          (match_operand 1 "" ""))]
13659   ""
13661   if (SIBLING_CALL_P (insn))
13662     return "jmp\t%P0";
13663   else
13664     return "call\t%P0";
13666   [(set_attr "type" "call")])
13668 (define_insn "*call_1"
13669   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13670          (match_operand 1 "" ""))]
13671   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13673   if (constant_call_address_operand (operands[0], Pmode))
13674     return "call\t%P0";
13675   return "call\t%A0";
13677   [(set_attr "type" "call")])
13679 (define_insn "*sibcall_1"
13680   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13681          (match_operand 1 "" ""))]
13682   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13684   if (constant_call_address_operand (operands[0], Pmode))
13685     return "jmp\t%P0";
13686   return "jmp\t%A0";
13688   [(set_attr "type" "call")])
13690 (define_insn "*call_1_rex64"
13691   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13692          (match_operand 1 "" ""))]
13693   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13695   if (constant_call_address_operand (operands[0], Pmode))
13696     return "call\t%P0";
13697   return "call\t%A0";
13699   [(set_attr "type" "call")])
13701 (define_insn "*sibcall_1_rex64"
13702   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13703          (match_operand 1 "" ""))]
13704   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13705   "jmp\t%P0"
13706   [(set_attr "type" "call")])
13708 (define_insn "*sibcall_1_rex64_v"
13709   [(call (mem:QI (reg:DI 40))
13710          (match_operand 0 "" ""))]
13711   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13712   "jmp\t*%%r11"
13713   [(set_attr "type" "call")])
13716 ;; Call subroutine, returning value in operand 0
13718 (define_expand "call_value_pop"
13719   [(parallel [(set (match_operand 0 "" "")
13720                    (call (match_operand:QI 1 "" "")
13721                          (match_operand:SI 2 "" "")))
13722               (set (reg:SI SP_REG)
13723                    (plus:SI (reg:SI SP_REG)
13724                             (match_operand:SI 4 "" "")))])]
13725   "!TARGET_64BIT"
13727   ix86_expand_call (operands[0], operands[1], operands[2],
13728                     operands[3], operands[4], 0);
13729   DONE;
13732 (define_expand "call_value"
13733   [(set (match_operand 0 "" "")
13734         (call (match_operand:QI 1 "" "")
13735               (match_operand:SI 2 "" "")))
13736    (use (match_operand:SI 3 "" ""))]
13737   ;; Operand 2 not used on the i386.
13738   ""
13740   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13741   DONE;
13744 (define_expand "sibcall_value"
13745   [(set (match_operand 0 "" "")
13746         (call (match_operand:QI 1 "" "")
13747               (match_operand:SI 2 "" "")))
13748    (use (match_operand:SI 3 "" ""))]
13749   ;; Operand 2 not used on the i386.
13750   ""
13752   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13753   DONE;
13756 ;; Call subroutine returning any type.
13758 (define_expand "untyped_call"
13759   [(parallel [(call (match_operand 0 "" "")
13760                     (const_int 0))
13761               (match_operand 1 "" "")
13762               (match_operand 2 "" "")])]
13763   ""
13765   int i;
13767   /* In order to give reg-stack an easier job in validating two
13768      coprocessor registers as containing a possible return value,
13769      simply pretend the untyped call returns a complex long double
13770      value.  */
13772   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13773                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13774                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13775                     NULL, 0);
13777   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13778     {
13779       rtx set = XVECEXP (operands[2], 0, i);
13780       emit_move_insn (SET_DEST (set), SET_SRC (set));
13781     }
13783   /* The optimizer does not know that the call sets the function value
13784      registers we stored in the result block.  We avoid problems by
13785      claiming that all hard registers are used and clobbered at this
13786      point.  */
13787   emit_insn (gen_blockage (const0_rtx));
13789   DONE;
13792 ;; Prologue and epilogue instructions
13794 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13795 ;; all of memory.  This blocks insns from being moved across this point.
13797 (define_insn "blockage"
13798   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13799   ""
13800   ""
13801   [(set_attr "length" "0")])
13803 ;; Insn emitted into the body of a function to return from a function.
13804 ;; This is only done if the function's epilogue is known to be simple.
13805 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13807 (define_expand "return"
13808   [(return)]
13809   "ix86_can_use_return_insn_p ()"
13811   if (current_function_pops_args)
13812     {
13813       rtx popc = GEN_INT (current_function_pops_args);
13814       emit_jump_insn (gen_return_pop_internal (popc));
13815       DONE;
13816     }
13819 (define_insn "return_internal"
13820   [(return)]
13821   "reload_completed"
13822   "ret"
13823   [(set_attr "length" "1")
13824    (set_attr "length_immediate" "0")
13825    (set_attr "modrm" "0")])
13827 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13828 ;; instruction Athlon and K8 have.
13830 (define_insn "return_internal_long"
13831   [(return)
13832    (unspec [(const_int 0)] UNSPEC_REP)]
13833   "reload_completed"
13834   "rep {;} ret"
13835   [(set_attr "length" "1")
13836    (set_attr "length_immediate" "0")
13837    (set_attr "prefix_rep" "1")
13838    (set_attr "modrm" "0")])
13840 (define_insn "return_pop_internal"
13841   [(return)
13842    (use (match_operand:SI 0 "const_int_operand" ""))]
13843   "reload_completed"
13844   "ret\t%0"
13845   [(set_attr "length" "3")
13846    (set_attr "length_immediate" "2")
13847    (set_attr "modrm" "0")])
13849 (define_insn "return_indirect_internal"
13850   [(return)
13851    (use (match_operand:SI 0 "register_operand" "r"))]
13852   "reload_completed"
13853   "jmp\t%A0"
13854   [(set_attr "type" "ibr")
13855    (set_attr "length_immediate" "0")])
13857 (define_insn "nop"
13858   [(const_int 0)]
13859   ""
13860   "nop"
13861   [(set_attr "length" "1")
13862    (set_attr "length_immediate" "0")
13863    (set_attr "modrm" "0")])
13865 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13866 ;; branch prediction penalty for the third jump in a 16-byte
13867 ;; block on K8.
13869 (define_insn "align"
13870   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13871   ""
13873 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13874   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13875 #else
13876   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13877      The align insn is used to avoid 3 jump instructions in the row to improve
13878      branch prediction and the benefits hardly outweight the cost of extra 8
13879      nops on the average inserted by full alignment pseudo operation.  */
13880 #endif
13881   return "";
13883   [(set_attr "length" "16")])
13885 (define_expand "prologue"
13886   [(const_int 1)]
13887   ""
13888   "ix86_expand_prologue (); DONE;")
13890 (define_insn "set_got"
13891   [(set (match_operand:SI 0 "register_operand" "=r")
13892         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13893    (clobber (reg:CC FLAGS_REG))]
13894   "!TARGET_64BIT"
13895   { return output_set_got (operands[0], NULL_RTX); }
13896   [(set_attr "type" "multi")
13897    (set_attr "length" "12")])
13899 (define_insn "set_got_labelled"
13900   [(set (match_operand:SI 0 "register_operand" "=r")
13901         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13902          UNSPEC_SET_GOT))
13903    (clobber (reg:CC FLAGS_REG))]
13904   "!TARGET_64BIT"
13905   { return output_set_got (operands[0], operands[1]); }
13906   [(set_attr "type" "multi")
13907    (set_attr "length" "12")])
13909 (define_insn "set_got_rex64"
13910   [(set (match_operand:DI 0 "register_operand" "=r")
13911         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13912   "TARGET_64BIT"
13913   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13914   [(set_attr "type" "lea")
13915    (set_attr "length" "6")])
13917 (define_expand "epilogue"
13918   [(const_int 1)]
13919   ""
13920   "ix86_expand_epilogue (1); DONE;")
13922 (define_expand "sibcall_epilogue"
13923   [(const_int 1)]
13924   ""
13925   "ix86_expand_epilogue (0); DONE;")
13927 (define_expand "eh_return"
13928   [(use (match_operand 0 "register_operand" ""))]
13929   ""
13931   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13933   /* Tricky bit: we write the address of the handler to which we will
13934      be returning into someone else's stack frame, one word below the
13935      stack address we wish to restore.  */
13936   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13937   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13938   tmp = gen_rtx_MEM (Pmode, tmp);
13939   emit_move_insn (tmp, ra);
13941   if (Pmode == SImode)
13942     emit_jump_insn (gen_eh_return_si (sa));
13943   else
13944     emit_jump_insn (gen_eh_return_di (sa));
13945   emit_barrier ();
13946   DONE;
13949 (define_insn_and_split "eh_return_si"
13950   [(set (pc) 
13951         (unspec [(match_operand:SI 0 "register_operand" "c")]
13952                  UNSPEC_EH_RETURN))]
13953   "!TARGET_64BIT"
13954   "#"
13955   "reload_completed"
13956   [(const_int 1)]
13957   "ix86_expand_epilogue (2); DONE;")
13959 (define_insn_and_split "eh_return_di"
13960   [(set (pc) 
13961         (unspec [(match_operand:DI 0 "register_operand" "c")]
13962                  UNSPEC_EH_RETURN))]
13963   "TARGET_64BIT"
13964   "#"
13965   "reload_completed"
13966   [(const_int 1)]
13967   "ix86_expand_epilogue (2); DONE;")
13969 (define_insn "leave"
13970   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13971    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13972    (clobber (mem:BLK (scratch)))]
13973   "!TARGET_64BIT"
13974   "leave"
13975   [(set_attr "type" "leave")])
13977 (define_insn "leave_rex64"
13978   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13979    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13980    (clobber (mem:BLK (scratch)))]
13981   "TARGET_64BIT"
13982   "leave"
13983   [(set_attr "type" "leave")])
13985 (define_expand "ffssi2"
13986   [(parallel
13987      [(set (match_operand:SI 0 "register_operand" "") 
13988            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13989       (clobber (match_scratch:SI 2 ""))
13990       (clobber (reg:CC FLAGS_REG))])]
13991   ""
13992   "")
13994 (define_insn_and_split "*ffs_cmove"
13995   [(set (match_operand:SI 0 "register_operand" "=r") 
13996         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13997    (clobber (match_scratch:SI 2 "=&r"))
13998    (clobber (reg:CC FLAGS_REG))]
13999   "TARGET_CMOVE"
14000   "#"
14001   "&& reload_completed"
14002   [(set (match_dup 2) (const_int -1))
14003    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14004               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14005    (set (match_dup 0) (if_then_else:SI
14006                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14007                         (match_dup 2)
14008                         (match_dup 0)))
14009    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14010               (clobber (reg:CC FLAGS_REG))])]
14011   "")
14013 (define_insn_and_split "*ffs_no_cmove"
14014   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14015         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14016    (clobber (match_scratch:SI 2 "=&q"))
14017    (clobber (reg:CC FLAGS_REG))]
14018   ""
14019   "#"
14020   "reload_completed"
14021   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14022               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14023    (set (strict_low_part (match_dup 3))
14024         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14025    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14026               (clobber (reg:CC FLAGS_REG))])
14027    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14030               (clobber (reg:CC FLAGS_REG))])]
14032   operands[3] = gen_lowpart (QImode, operands[2]);
14033   ix86_expand_clear (operands[2]);
14036 (define_insn "*ffssi_1"
14037   [(set (reg:CCZ FLAGS_REG)
14038         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14039                      (const_int 0)))
14040    (set (match_operand:SI 0 "register_operand" "=r")
14041         (ctz:SI (match_dup 1)))]
14042   ""
14043   "bsf{l}\t{%1, %0|%0, %1}"
14044   [(set_attr "prefix_0f" "1")])
14046 (define_expand "ffsdi2"
14047   [(parallel
14048      [(set (match_operand:DI 0 "register_operand" "") 
14049            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14050       (clobber (match_scratch:DI 2 ""))
14051       (clobber (reg:CC FLAGS_REG))])]
14052   "TARGET_64BIT && TARGET_CMOVE"
14053   "")
14055 (define_insn_and_split "*ffs_rex64"
14056   [(set (match_operand:DI 0 "register_operand" "=r") 
14057         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14058    (clobber (match_scratch:DI 2 "=&r"))
14059    (clobber (reg:CC FLAGS_REG))]
14060   "TARGET_64BIT && TARGET_CMOVE"
14061   "#"
14062   "&& reload_completed"
14063   [(set (match_dup 2) (const_int -1))
14064    (parallel [(set (reg:CCZ FLAGS_REG)
14065                    (compare:CCZ (match_dup 1) (const_int 0)))
14066               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14067    (set (match_dup 0) (if_then_else:DI
14068                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14069                         (match_dup 2)
14070                         (match_dup 0)))
14071    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14072               (clobber (reg:CC FLAGS_REG))])]
14073   "")
14075 (define_insn "*ffsdi_1"
14076   [(set (reg:CCZ FLAGS_REG)
14077         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14078                      (const_int 0)))
14079    (set (match_operand:DI 0 "register_operand" "=r")
14080         (ctz:DI (match_dup 1)))]
14081   "TARGET_64BIT"
14082   "bsf{q}\t{%1, %0|%0, %1}"
14083   [(set_attr "prefix_0f" "1")])
14085 (define_insn "ctzsi2"
14086   [(set (match_operand:SI 0 "register_operand" "=r")
14087         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14088    (clobber (reg:CC FLAGS_REG))]
14089   ""
14090   "bsf{l}\t{%1, %0|%0, %1}"
14091   [(set_attr "prefix_0f" "1")])
14093 (define_insn "ctzdi2"
14094   [(set (match_operand:DI 0 "register_operand" "=r")
14095         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14096    (clobber (reg:CC FLAGS_REG))]
14097   "TARGET_64BIT"
14098   "bsf{q}\t{%1, %0|%0, %1}"
14099   [(set_attr "prefix_0f" "1")])
14101 (define_expand "clzsi2"
14102   [(parallel
14103      [(set (match_operand:SI 0 "register_operand" "")
14104            (minus:SI (const_int 31)
14105                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14106       (clobber (reg:CC FLAGS_REG))])
14107    (parallel
14108      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14109       (clobber (reg:CC FLAGS_REG))])]
14110   ""
14111   "")
14113 (define_insn "*bsr"
14114   [(set (match_operand:SI 0 "register_operand" "=r")
14115         (minus:SI (const_int 31)
14116                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14117    (clobber (reg:CC FLAGS_REG))]
14118   ""
14119   "bsr{l}\t{%1, %0|%0, %1}"
14120   [(set_attr "prefix_0f" "1")])
14122 (define_expand "clzdi2"
14123   [(parallel
14124      [(set (match_operand:DI 0 "register_operand" "")
14125            (minus:DI (const_int 63)
14126                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14127       (clobber (reg:CC FLAGS_REG))])
14128    (parallel
14129      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14130       (clobber (reg:CC FLAGS_REG))])]
14131   "TARGET_64BIT"
14132   "")
14134 (define_insn "*bsr_rex64"
14135   [(set (match_operand:DI 0 "register_operand" "=r")
14136         (minus:DI (const_int 63)
14137                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14138    (clobber (reg:CC FLAGS_REG))]
14139   "TARGET_64BIT"
14140   "bsr{q}\t{%1, %0|%0, %1}"
14141   [(set_attr "prefix_0f" "1")])
14143 ;; Thread-local storage patterns for ELF.
14145 ;; Note that these code sequences must appear exactly as shown
14146 ;; in order to allow linker relaxation.
14148 (define_insn "*tls_global_dynamic_32_gnu"
14149   [(set (match_operand:SI 0 "register_operand" "=a")
14150         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14151                     (match_operand:SI 2 "tls_symbolic_operand" "")
14152                     (match_operand:SI 3 "call_insn_operand" "")]
14153                     UNSPEC_TLS_GD))
14154    (clobber (match_scratch:SI 4 "=d"))
14155    (clobber (match_scratch:SI 5 "=c"))
14156    (clobber (reg:CC FLAGS_REG))]
14157   "!TARGET_64BIT && TARGET_GNU_TLS"
14158   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14159   [(set_attr "type" "multi")
14160    (set_attr "length" "12")])
14162 (define_insn "*tls_global_dynamic_32_sun"
14163   [(set (match_operand:SI 0 "register_operand" "=a")
14164         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14165                     (match_operand:SI 2 "tls_symbolic_operand" "")
14166                     (match_operand:SI 3 "call_insn_operand" "")]
14167                     UNSPEC_TLS_GD))
14168    (clobber (match_scratch:SI 4 "=d"))
14169    (clobber (match_scratch:SI 5 "=c"))
14170    (clobber (reg:CC FLAGS_REG))]
14171   "!TARGET_64BIT && TARGET_SUN_TLS"
14172   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14173         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14174   [(set_attr "type" "multi")
14175    (set_attr "length" "14")])
14177 (define_expand "tls_global_dynamic_32"
14178   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14179                    (unspec:SI
14180                     [(match_dup 2)
14181                      (match_operand:SI 1 "tls_symbolic_operand" "")
14182                      (match_dup 3)]
14183                     UNSPEC_TLS_GD))
14184               (clobber (match_scratch:SI 4 ""))
14185               (clobber (match_scratch:SI 5 ""))
14186               (clobber (reg:CC FLAGS_REG))])]
14187   ""
14189   if (flag_pic)
14190     operands[2] = pic_offset_table_rtx;
14191   else
14192     {
14193       operands[2] = gen_reg_rtx (Pmode);
14194       emit_insn (gen_set_got (operands[2]));
14195     }
14196   if (TARGET_GNU2_TLS)
14197     {
14198        emit_insn (gen_tls_dynamic_gnu2_32
14199                   (operands[0], operands[1], operands[2]));
14200        DONE;
14201     }
14202   operands[3] = ix86_tls_get_addr ();
14205 (define_insn "*tls_global_dynamic_64"
14206   [(set (match_operand:DI 0 "register_operand" "=a")
14207         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14208                  (match_operand:DI 3 "" "")))
14209    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14210               UNSPEC_TLS_GD)]
14211   "TARGET_64BIT"
14212   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14213   [(set_attr "type" "multi")
14214    (set_attr "length" "16")])
14216 (define_expand "tls_global_dynamic_64"
14217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14218                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14219               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14220                          UNSPEC_TLS_GD)])]
14221   ""
14223   if (TARGET_GNU2_TLS)
14224     {
14225        emit_insn (gen_tls_dynamic_gnu2_64
14226                   (operands[0], operands[1]));
14227        DONE;
14228     }
14229   operands[2] = ix86_tls_get_addr ();
14232 (define_insn "*tls_local_dynamic_base_32_gnu"
14233   [(set (match_operand:SI 0 "register_operand" "=a")
14234         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14235                     (match_operand:SI 2 "call_insn_operand" "")]
14236                    UNSPEC_TLS_LD_BASE))
14237    (clobber (match_scratch:SI 3 "=d"))
14238    (clobber (match_scratch:SI 4 "=c"))
14239    (clobber (reg:CC FLAGS_REG))]
14240   "!TARGET_64BIT && TARGET_GNU_TLS"
14241   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14242   [(set_attr "type" "multi")
14243    (set_attr "length" "11")])
14245 (define_insn "*tls_local_dynamic_base_32_sun"
14246   [(set (match_operand:SI 0 "register_operand" "=a")
14247         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14248                     (match_operand:SI 2 "call_insn_operand" "")]
14249                    UNSPEC_TLS_LD_BASE))
14250    (clobber (match_scratch:SI 3 "=d"))
14251    (clobber (match_scratch:SI 4 "=c"))
14252    (clobber (reg:CC FLAGS_REG))]
14253   "!TARGET_64BIT && TARGET_SUN_TLS"
14254   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14255         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14256   [(set_attr "type" "multi")
14257    (set_attr "length" "13")])
14259 (define_expand "tls_local_dynamic_base_32"
14260   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14261                    (unspec:SI [(match_dup 1) (match_dup 2)]
14262                               UNSPEC_TLS_LD_BASE))
14263               (clobber (match_scratch:SI 3 ""))
14264               (clobber (match_scratch:SI 4 ""))
14265               (clobber (reg:CC FLAGS_REG))])]
14266   ""
14268   if (flag_pic)
14269     operands[1] = pic_offset_table_rtx;
14270   else
14271     {
14272       operands[1] = gen_reg_rtx (Pmode);
14273       emit_insn (gen_set_got (operands[1]));
14274     }
14275   if (TARGET_GNU2_TLS)
14276     {
14277        emit_insn (gen_tls_dynamic_gnu2_32
14278                   (operands[0], ix86_tls_module_base (), operands[1]));
14279        DONE;
14280     }
14281   operands[2] = ix86_tls_get_addr ();
14284 (define_insn "*tls_local_dynamic_base_64"
14285   [(set (match_operand:DI 0 "register_operand" "=a")
14286         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14287                  (match_operand:DI 2 "" "")))
14288    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14289   "TARGET_64BIT"
14290   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14291   [(set_attr "type" "multi")
14292    (set_attr "length" "12")])
14294 (define_expand "tls_local_dynamic_base_64"
14295   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14296                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14297               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14298   ""
14300   if (TARGET_GNU2_TLS)
14301     {
14302        emit_insn (gen_tls_dynamic_gnu2_64
14303                   (operands[0], ix86_tls_module_base ()));
14304        DONE;
14305     }
14306   operands[1] = ix86_tls_get_addr ();
14309 ;; Local dynamic of a single variable is a lose.  Show combine how
14310 ;; to convert that back to global dynamic.
14312 (define_insn_and_split "*tls_local_dynamic_32_once"
14313   [(set (match_operand:SI 0 "register_operand" "=a")
14314         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14315                              (match_operand:SI 2 "call_insn_operand" "")]
14316                             UNSPEC_TLS_LD_BASE)
14317                  (const:SI (unspec:SI
14318                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14319                             UNSPEC_DTPOFF))))
14320    (clobber (match_scratch:SI 4 "=d"))
14321    (clobber (match_scratch:SI 5 "=c"))
14322    (clobber (reg:CC FLAGS_REG))]
14323   ""
14324   "#"
14325   ""
14326   [(parallel [(set (match_dup 0)
14327                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14328                               UNSPEC_TLS_GD))
14329               (clobber (match_dup 4))
14330               (clobber (match_dup 5))
14331               (clobber (reg:CC FLAGS_REG))])]
14332   "")
14334 ;; Load and add the thread base pointer from %gs:0.
14336 (define_insn "*load_tp_si"
14337   [(set (match_operand:SI 0 "register_operand" "=r")
14338         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14339   "!TARGET_64BIT"
14340   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14341   [(set_attr "type" "imov")
14342    (set_attr "modrm" "0")
14343    (set_attr "length" "7")
14344    (set_attr "memory" "load")
14345    (set_attr "imm_disp" "false")])
14347 (define_insn "*add_tp_si"
14348   [(set (match_operand:SI 0 "register_operand" "=r")
14349         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14350                  (match_operand:SI 1 "register_operand" "0")))
14351    (clobber (reg:CC FLAGS_REG))]
14352   "!TARGET_64BIT"
14353   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14354   [(set_attr "type" "alu")
14355    (set_attr "modrm" "0")
14356    (set_attr "length" "7")
14357    (set_attr "memory" "load")
14358    (set_attr "imm_disp" "false")])
14360 (define_insn "*load_tp_di"
14361   [(set (match_operand:DI 0 "register_operand" "=r")
14362         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14363   "TARGET_64BIT"
14364   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14365   [(set_attr "type" "imov")
14366    (set_attr "modrm" "0")
14367    (set_attr "length" "7")
14368    (set_attr "memory" "load")
14369    (set_attr "imm_disp" "false")])
14371 (define_insn "*add_tp_di"
14372   [(set (match_operand:DI 0 "register_operand" "=r")
14373         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14374                  (match_operand:DI 1 "register_operand" "0")))
14375    (clobber (reg:CC FLAGS_REG))]
14376   "TARGET_64BIT"
14377   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14378   [(set_attr "type" "alu")
14379    (set_attr "modrm" "0")
14380    (set_attr "length" "7")
14381    (set_attr "memory" "load")
14382    (set_attr "imm_disp" "false")])
14384 ;; GNU2 TLS patterns can be split.
14386 (define_expand "tls_dynamic_gnu2_32"
14387   [(set (match_dup 3)
14388         (plus:SI (match_operand:SI 2 "register_operand" "")
14389                  (const:SI
14390                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14391                              UNSPEC_TLSDESC))))
14392    (parallel
14393     [(set (match_operand:SI 0 "register_operand" "")
14394           (unspec:SI [(match_dup 1) (match_dup 3)
14395                       (match_dup 2) (reg:SI SP_REG)]
14396                       UNSPEC_TLSDESC))
14397      (clobber (reg:CC FLAGS_REG))])]
14398   "!TARGET_64BIT && TARGET_GNU2_TLS"
14400   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14401   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14404 (define_insn "*tls_dynamic_lea_32"
14405   [(set (match_operand:SI 0 "register_operand" "=r")
14406         (plus:SI (match_operand:SI 1 "register_operand" "b")
14407                  (const:SI
14408                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14409                               UNSPEC_TLSDESC))))]
14410   "!TARGET_64BIT && TARGET_GNU2_TLS"
14411   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14412   [(set_attr "type" "lea")
14413    (set_attr "mode" "SI")
14414    (set_attr "length" "6")
14415    (set_attr "length_address" "4")])
14417 (define_insn "*tls_dynamic_call_32"
14418   [(set (match_operand:SI 0 "register_operand" "=a")
14419         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14420                     (match_operand:SI 2 "register_operand" "0")
14421                     ;; we have to make sure %ebx still points to the GOT
14422                     (match_operand:SI 3 "register_operand" "b")
14423                     (reg:SI SP_REG)]
14424                    UNSPEC_TLSDESC))
14425    (clobber (reg:CC FLAGS_REG))]
14426   "!TARGET_64BIT && TARGET_GNU2_TLS"
14427   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14428   [(set_attr "type" "call")
14429    (set_attr "length" "2")
14430    (set_attr "length_address" "0")])
14432 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14433   [(set (match_operand:SI 0 "register_operand" "=&a")
14434         (plus:SI
14435          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14436                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14437                               (match_operand:SI 5 "" "")
14438                               (match_operand:SI 2 "register_operand" "b")
14439                               (reg:SI SP_REG)]
14440                              UNSPEC_TLSDESC))
14441          (const:SI (unspec:SI
14442                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14443                     UNSPEC_DTPOFF))))
14444    (clobber (reg:CC FLAGS_REG))]
14445   "!TARGET_64BIT && TARGET_GNU2_TLS"
14446   "#"
14447   ""
14448   [(parallel
14449     [(set (match_dup 0)
14450           (plus:SI (match_dup 3)
14451                    (match_dup 5)))
14452      (clobber (reg:CC FLAGS_REG))])]
14454   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14455   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14458 (define_expand "tls_dynamic_gnu2_64"
14459   [(set (match_dup 2)
14460         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14461                    UNSPEC_TLSDESC))
14462    (parallel
14463     [(set (match_operand:DI 0 "register_operand" "")
14464           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14465                      UNSPEC_TLSDESC))
14466      (clobber (reg:CC FLAGS_REG))])]
14467   "TARGET_64BIT && TARGET_GNU2_TLS"
14469   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14470   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14473 (define_insn "*tls_dynamic_lea_64"
14474   [(set (match_operand:DI 0 "register_operand" "=r")
14475         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14476                    UNSPEC_TLSDESC))]
14477   "TARGET_64BIT && TARGET_GNU2_TLS"
14478   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14479   [(set_attr "type" "lea")
14480    (set_attr "mode" "DI")
14481    (set_attr "length" "7")
14482    (set_attr "length_address" "4")])
14484 (define_insn "*tls_dynamic_call_64"
14485   [(set (match_operand:DI 0 "register_operand" "=a")
14486         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14487                     (match_operand:DI 2 "register_operand" "0")
14488                     (reg:DI SP_REG)]
14489                    UNSPEC_TLSDESC))
14490    (clobber (reg:CC FLAGS_REG))]
14491   "TARGET_64BIT && TARGET_GNU2_TLS"
14492   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14493   [(set_attr "type" "call")
14494    (set_attr "length" "2")
14495    (set_attr "length_address" "0")])
14497 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14498   [(set (match_operand:DI 0 "register_operand" "=&a")
14499         (plus:DI
14500          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14501                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14502                               (match_operand:DI 4 "" "")
14503                               (reg:DI SP_REG)]
14504                               UNSPEC_TLSDESC))
14505          (const:DI (unspec:DI
14506                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14507                     UNSPEC_DTPOFF))))
14508    (clobber (reg:CC FLAGS_REG))]
14509   "TARGET_64BIT && TARGET_GNU2_TLS"
14510   "#"
14511   ""
14512   [(parallel
14513     [(set (match_dup 0)
14514           (plus:DI (match_dup 2)
14515                    (match_dup 4)))
14516      (clobber (reg:CC FLAGS_REG))])]
14518   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14519   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14524 ;; These patterns match the binary 387 instructions for addM3, subM3,
14525 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14526 ;; SFmode.  The first is the normal insn, the second the same insn but
14527 ;; with one operand a conversion, and the third the same insn but with
14528 ;; the other operand a conversion.  The conversion may be SFmode or
14529 ;; SImode if the target mode DFmode, but only SImode if the target mode
14530 ;; is SFmode.
14532 ;; Gcc is slightly more smart about handling normal two address instructions
14533 ;; so use special patterns for add and mull.
14535 (define_insn "*fop_sf_comm_mixed"
14536   [(set (match_operand:SF 0 "register_operand" "=f,x")
14537         (match_operator:SF 3 "binary_fp_operator"
14538                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14539                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14540   "TARGET_MIX_SSE_I387
14541    && COMMUTATIVE_ARITH_P (operands[3])
14542    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14543   "* return output_387_binary_op (insn, operands);"
14544   [(set (attr "type") 
14545         (if_then_else (eq_attr "alternative" "1")
14546            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14547               (const_string "ssemul")
14548               (const_string "sseadd"))
14549            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14550               (const_string "fmul")
14551               (const_string "fop"))))
14552    (set_attr "mode" "SF")])
14554 (define_insn "*fop_sf_comm_sse"
14555   [(set (match_operand:SF 0 "register_operand" "=x")
14556         (match_operator:SF 3 "binary_fp_operator"
14557                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14558                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14559   "TARGET_SSE_MATH
14560    && COMMUTATIVE_ARITH_P (operands[3])
14561    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14562   "* return output_387_binary_op (insn, operands);"
14563   [(set (attr "type") 
14564         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14565            (const_string "ssemul")
14566            (const_string "sseadd")))
14567    (set_attr "mode" "SF")])
14569 (define_insn "*fop_sf_comm_i387"
14570   [(set (match_operand:SF 0 "register_operand" "=f")
14571         (match_operator:SF 3 "binary_fp_operator"
14572                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14573                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14574   "TARGET_80387
14575    && COMMUTATIVE_ARITH_P (operands[3])
14576    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14577   "* return output_387_binary_op (insn, operands);"
14578   [(set (attr "type") 
14579         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14580            (const_string "fmul")
14581            (const_string "fop")))
14582    (set_attr "mode" "SF")])
14584 (define_insn "*fop_sf_1_mixed"
14585   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14586         (match_operator:SF 3 "binary_fp_operator"
14587                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14588                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14589   "TARGET_MIX_SSE_I387
14590    && !COMMUTATIVE_ARITH_P (operands[3])
14591    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14592   "* return output_387_binary_op (insn, operands);"
14593   [(set (attr "type") 
14594         (cond [(and (eq_attr "alternative" "2")
14595                     (match_operand:SF 3 "mult_operator" ""))
14596                  (const_string "ssemul")
14597                (and (eq_attr "alternative" "2")
14598                     (match_operand:SF 3 "div_operator" ""))
14599                  (const_string "ssediv")
14600                (eq_attr "alternative" "2")
14601                  (const_string "sseadd")
14602                (match_operand:SF 3 "mult_operator" "") 
14603                  (const_string "fmul")
14604                (match_operand:SF 3 "div_operator" "") 
14605                  (const_string "fdiv")
14606               ]
14607               (const_string "fop")))
14608    (set_attr "mode" "SF")])
14610 (define_insn "*fop_sf_1_sse"
14611   [(set (match_operand:SF 0 "register_operand" "=x")
14612         (match_operator:SF 3 "binary_fp_operator"
14613                         [(match_operand:SF 1 "register_operand" "0")
14614                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14615   "TARGET_SSE_MATH
14616    && !COMMUTATIVE_ARITH_P (operands[3])"
14617   "* return output_387_binary_op (insn, operands);"
14618   [(set (attr "type") 
14619         (cond [(match_operand:SF 3 "mult_operator" "")
14620                  (const_string "ssemul")
14621                (match_operand:SF 3 "div_operator" "")
14622                  (const_string "ssediv")
14623               ]
14624               (const_string "sseadd")))
14625    (set_attr "mode" "SF")])
14627 ;; This pattern is not fully shadowed by the pattern above.
14628 (define_insn "*fop_sf_1_i387"
14629   [(set (match_operand:SF 0 "register_operand" "=f,f")
14630         (match_operator:SF 3 "binary_fp_operator"
14631                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14632                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14633   "TARGET_80387 && !TARGET_SSE_MATH
14634    && !COMMUTATIVE_ARITH_P (operands[3])
14635    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14636   "* return output_387_binary_op (insn, operands);"
14637   [(set (attr "type") 
14638         (cond [(match_operand:SF 3 "mult_operator" "") 
14639                  (const_string "fmul")
14640                (match_operand:SF 3 "div_operator" "") 
14641                  (const_string "fdiv")
14642               ]
14643               (const_string "fop")))
14644    (set_attr "mode" "SF")])
14646 ;; ??? Add SSE splitters for these!
14647 (define_insn "*fop_sf_2<mode>_i387"
14648   [(set (match_operand:SF 0 "register_operand" "=f,f")
14649         (match_operator:SF 3 "binary_fp_operator"
14650           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14651            (match_operand:SF 2 "register_operand" "0,0")]))]
14652   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14653   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14654   [(set (attr "type") 
14655         (cond [(match_operand:SF 3 "mult_operator" "") 
14656                  (const_string "fmul")
14657                (match_operand:SF 3 "div_operator" "") 
14658                  (const_string "fdiv")
14659               ]
14660               (const_string "fop")))
14661    (set_attr "fp_int_src" "true")
14662    (set_attr "mode" "<MODE>")])
14664 (define_insn "*fop_sf_3<mode>_i387"
14665   [(set (match_operand:SF 0 "register_operand" "=f,f")
14666         (match_operator:SF 3 "binary_fp_operator"
14667           [(match_operand:SF 1 "register_operand" "0,0")
14668            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14669   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14670   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14671   [(set (attr "type") 
14672         (cond [(match_operand:SF 3 "mult_operator" "") 
14673                  (const_string "fmul")
14674                (match_operand:SF 3 "div_operator" "") 
14675                  (const_string "fdiv")
14676               ]
14677               (const_string "fop")))
14678    (set_attr "fp_int_src" "true")
14679    (set_attr "mode" "<MODE>")])
14681 (define_insn "*fop_df_comm_mixed"
14682   [(set (match_operand:DF 0 "register_operand" "=f,Y")
14683         (match_operator:DF 3 "binary_fp_operator"
14684                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14685                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14686   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14687    && COMMUTATIVE_ARITH_P (operands[3])
14688    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14689   "* return output_387_binary_op (insn, operands);"
14690   [(set (attr "type") 
14691         (if_then_else (eq_attr "alternative" "1")
14692            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14693               (const_string "ssemul")
14694               (const_string "sseadd"))
14695            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14696               (const_string "fmul")
14697               (const_string "fop"))))
14698    (set_attr "mode" "DF")])
14700 (define_insn "*fop_df_comm_sse"
14701   [(set (match_operand:DF 0 "register_operand" "=Y")
14702         (match_operator:DF 3 "binary_fp_operator"
14703                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14704                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14705   "TARGET_SSE2 && TARGET_SSE_MATH
14706    && COMMUTATIVE_ARITH_P (operands[3])
14707    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14708   "* return output_387_binary_op (insn, operands);"
14709   [(set (attr "type") 
14710         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14711            (const_string "ssemul")
14712            (const_string "sseadd")))
14713    (set_attr "mode" "DF")])
14715 (define_insn "*fop_df_comm_i387"
14716   [(set (match_operand:DF 0 "register_operand" "=f")
14717         (match_operator:DF 3 "binary_fp_operator"
14718                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14719                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14720   "TARGET_80387
14721    && COMMUTATIVE_ARITH_P (operands[3])
14722    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14723   "* return output_387_binary_op (insn, operands);"
14724   [(set (attr "type") 
14725         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14726            (const_string "fmul")
14727            (const_string "fop")))
14728    (set_attr "mode" "DF")])
14730 (define_insn "*fop_df_1_mixed"
14731   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14732         (match_operator:DF 3 "binary_fp_operator"
14733                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14734                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14735   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14736    && !COMMUTATIVE_ARITH_P (operands[3])
14737    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14738   "* return output_387_binary_op (insn, operands);"
14739   [(set (attr "type") 
14740         (cond [(and (eq_attr "alternative" "2")
14741                     (match_operand:SF 3 "mult_operator" ""))
14742                  (const_string "ssemul")
14743                (and (eq_attr "alternative" "2")
14744                     (match_operand:SF 3 "div_operator" ""))
14745                  (const_string "ssediv")
14746                (eq_attr "alternative" "2")
14747                  (const_string "sseadd")
14748                (match_operand:DF 3 "mult_operator" "") 
14749                  (const_string "fmul")
14750                (match_operand:DF 3 "div_operator" "") 
14751                  (const_string "fdiv")
14752               ]
14753               (const_string "fop")))
14754    (set_attr "mode" "DF")])
14756 (define_insn "*fop_df_1_sse"
14757   [(set (match_operand:DF 0 "register_operand" "=Y")
14758         (match_operator:DF 3 "binary_fp_operator"
14759                         [(match_operand:DF 1 "register_operand" "0")
14760                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14761   "TARGET_SSE2 && TARGET_SSE_MATH
14762    && !COMMUTATIVE_ARITH_P (operands[3])"
14763   "* return output_387_binary_op (insn, operands);"
14764   [(set_attr "mode" "DF")
14765    (set (attr "type") 
14766         (cond [(match_operand:SF 3 "mult_operator" "")
14767                  (const_string "ssemul")
14768                (match_operand:SF 3 "div_operator" "")
14769                  (const_string "ssediv")
14770               ]
14771               (const_string "sseadd")))])
14773 ;; This pattern is not fully shadowed by the pattern above.
14774 (define_insn "*fop_df_1_i387"
14775   [(set (match_operand:DF 0 "register_operand" "=f,f")
14776         (match_operator:DF 3 "binary_fp_operator"
14777                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14778                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14779   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14780    && !COMMUTATIVE_ARITH_P (operands[3])
14781    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14782   "* return output_387_binary_op (insn, operands);"
14783   [(set (attr "type") 
14784         (cond [(match_operand:DF 3 "mult_operator" "") 
14785                  (const_string "fmul")
14786                (match_operand:DF 3 "div_operator" "")
14787                  (const_string "fdiv")
14788               ]
14789               (const_string "fop")))
14790    (set_attr "mode" "DF")])
14792 ;; ??? Add SSE splitters for these!
14793 (define_insn "*fop_df_2<mode>_i387"
14794   [(set (match_operand:DF 0 "register_operand" "=f,f")
14795         (match_operator:DF 3 "binary_fp_operator"
14796            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14797             (match_operand:DF 2 "register_operand" "0,0")]))]
14798   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14799    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14800   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14801   [(set (attr "type") 
14802         (cond [(match_operand:DF 3 "mult_operator" "") 
14803                  (const_string "fmul")
14804                (match_operand:DF 3 "div_operator" "") 
14805                  (const_string "fdiv")
14806               ]
14807               (const_string "fop")))
14808    (set_attr "fp_int_src" "true")
14809    (set_attr "mode" "<MODE>")])
14811 (define_insn "*fop_df_3<mode>_i387"
14812   [(set (match_operand:DF 0 "register_operand" "=f,f")
14813         (match_operator:DF 3 "binary_fp_operator"
14814            [(match_operand:DF 1 "register_operand" "0,0")
14815             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14816   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14817    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14818   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14819   [(set (attr "type") 
14820         (cond [(match_operand:DF 3 "mult_operator" "") 
14821                  (const_string "fmul")
14822                (match_operand:DF 3 "div_operator" "") 
14823                  (const_string "fdiv")
14824               ]
14825               (const_string "fop")))
14826    (set_attr "fp_int_src" "true")
14827    (set_attr "mode" "<MODE>")])
14829 (define_insn "*fop_df_4_i387"
14830   [(set (match_operand:DF 0 "register_operand" "=f,f")
14831         (match_operator:DF 3 "binary_fp_operator"
14832            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14833             (match_operand:DF 2 "register_operand" "0,f")]))]
14834   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14835    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14836   "* return output_387_binary_op (insn, operands);"
14837   [(set (attr "type") 
14838         (cond [(match_operand:DF 3 "mult_operator" "") 
14839                  (const_string "fmul")
14840                (match_operand:DF 3 "div_operator" "") 
14841                  (const_string "fdiv")
14842               ]
14843               (const_string "fop")))
14844    (set_attr "mode" "SF")])
14846 (define_insn "*fop_df_5_i387"
14847   [(set (match_operand:DF 0 "register_operand" "=f,f")
14848         (match_operator:DF 3 "binary_fp_operator"
14849           [(match_operand:DF 1 "register_operand" "0,f")
14850            (float_extend:DF
14851             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14852   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14853   "* return output_387_binary_op (insn, operands);"
14854   [(set (attr "type") 
14855         (cond [(match_operand:DF 3 "mult_operator" "") 
14856                  (const_string "fmul")
14857                (match_operand:DF 3 "div_operator" "") 
14858                  (const_string "fdiv")
14859               ]
14860               (const_string "fop")))
14861    (set_attr "mode" "SF")])
14863 (define_insn "*fop_df_6_i387"
14864   [(set (match_operand:DF 0 "register_operand" "=f,f")
14865         (match_operator:DF 3 "binary_fp_operator"
14866           [(float_extend:DF
14867             (match_operand:SF 1 "register_operand" "0,f"))
14868            (float_extend:DF
14869             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14870   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14871   "* return output_387_binary_op (insn, operands);"
14872   [(set (attr "type") 
14873         (cond [(match_operand:DF 3 "mult_operator" "") 
14874                  (const_string "fmul")
14875                (match_operand:DF 3 "div_operator" "") 
14876                  (const_string "fdiv")
14877               ]
14878               (const_string "fop")))
14879    (set_attr "mode" "SF")])
14881 (define_insn "*fop_xf_comm_i387"
14882   [(set (match_operand:XF 0 "register_operand" "=f")
14883         (match_operator:XF 3 "binary_fp_operator"
14884                         [(match_operand:XF 1 "register_operand" "%0")
14885                          (match_operand:XF 2 "register_operand" "f")]))]
14886   "TARGET_80387
14887    && COMMUTATIVE_ARITH_P (operands[3])"
14888   "* return output_387_binary_op (insn, operands);"
14889   [(set (attr "type") 
14890         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14891            (const_string "fmul")
14892            (const_string "fop")))
14893    (set_attr "mode" "XF")])
14895 (define_insn "*fop_xf_1_i387"
14896   [(set (match_operand:XF 0 "register_operand" "=f,f")
14897         (match_operator:XF 3 "binary_fp_operator"
14898                         [(match_operand:XF 1 "register_operand" "0,f")
14899                          (match_operand:XF 2 "register_operand" "f,0")]))]
14900   "TARGET_80387
14901    && !COMMUTATIVE_ARITH_P (operands[3])"
14902   "* return output_387_binary_op (insn, operands);"
14903   [(set (attr "type") 
14904         (cond [(match_operand:XF 3 "mult_operator" "") 
14905                  (const_string "fmul")
14906                (match_operand:XF 3 "div_operator" "") 
14907                  (const_string "fdiv")
14908               ]
14909               (const_string "fop")))
14910    (set_attr "mode" "XF")])
14912 (define_insn "*fop_xf_2<mode>_i387"
14913   [(set (match_operand:XF 0 "register_operand" "=f,f")
14914         (match_operator:XF 3 "binary_fp_operator"
14915            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14916             (match_operand:XF 2 "register_operand" "0,0")]))]
14917   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14918   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14919   [(set (attr "type") 
14920         (cond [(match_operand:XF 3 "mult_operator" "") 
14921                  (const_string "fmul")
14922                (match_operand:XF 3 "div_operator" "") 
14923                  (const_string "fdiv")
14924               ]
14925               (const_string "fop")))
14926    (set_attr "fp_int_src" "true")
14927    (set_attr "mode" "<MODE>")])
14929 (define_insn "*fop_xf_3<mode>_i387"
14930   [(set (match_operand:XF 0 "register_operand" "=f,f")
14931         (match_operator:XF 3 "binary_fp_operator"
14932           [(match_operand:XF 1 "register_operand" "0,0")
14933            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14934   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14935   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14936   [(set (attr "type") 
14937         (cond [(match_operand:XF 3 "mult_operator" "") 
14938                  (const_string "fmul")
14939                (match_operand:XF 3 "div_operator" "") 
14940                  (const_string "fdiv")
14941               ]
14942               (const_string "fop")))
14943    (set_attr "fp_int_src" "true")
14944    (set_attr "mode" "<MODE>")])
14946 (define_insn "*fop_xf_4_i387"
14947   [(set (match_operand:XF 0 "register_operand" "=f,f")
14948         (match_operator:XF 3 "binary_fp_operator"
14949            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14950             (match_operand:XF 2 "register_operand" "0,f")]))]
14951   "TARGET_80387"
14952   "* return output_387_binary_op (insn, operands);"
14953   [(set (attr "type") 
14954         (cond [(match_operand:XF 3 "mult_operator" "") 
14955                  (const_string "fmul")
14956                (match_operand:XF 3 "div_operator" "") 
14957                  (const_string "fdiv")
14958               ]
14959               (const_string "fop")))
14960    (set_attr "mode" "SF")])
14962 (define_insn "*fop_xf_5_i387"
14963   [(set (match_operand:XF 0 "register_operand" "=f,f")
14964         (match_operator:XF 3 "binary_fp_operator"
14965           [(match_operand:XF 1 "register_operand" "0,f")
14966            (float_extend:XF
14967             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14968   "TARGET_80387"
14969   "* return output_387_binary_op (insn, operands);"
14970   [(set (attr "type") 
14971         (cond [(match_operand:XF 3 "mult_operator" "") 
14972                  (const_string "fmul")
14973                (match_operand:XF 3 "div_operator" "") 
14974                  (const_string "fdiv")
14975               ]
14976               (const_string "fop")))
14977    (set_attr "mode" "SF")])
14979 (define_insn "*fop_xf_6_i387"
14980   [(set (match_operand:XF 0 "register_operand" "=f,f")
14981         (match_operator:XF 3 "binary_fp_operator"
14982           [(float_extend:XF
14983             (match_operand 1 "register_operand" "0,f"))
14984            (float_extend:XF
14985             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14986   "TARGET_80387"
14987   "* return output_387_binary_op (insn, operands);"
14988   [(set (attr "type") 
14989         (cond [(match_operand:XF 3 "mult_operator" "") 
14990                  (const_string "fmul")
14991                (match_operand:XF 3 "div_operator" "") 
14992                  (const_string "fdiv")
14993               ]
14994               (const_string "fop")))
14995    (set_attr "mode" "SF")])
14997 (define_split
14998   [(set (match_operand 0 "register_operand" "")
14999         (match_operator 3 "binary_fp_operator"
15000            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15001             (match_operand 2 "register_operand" "")]))]
15002   "TARGET_80387 && reload_completed
15003    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15004   [(const_int 0)]
15006   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15007   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15008   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15009                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15010                                           GET_MODE (operands[3]),
15011                                           operands[4],
15012                                           operands[2])));
15013   ix86_free_from_memory (GET_MODE (operands[1]));
15014   DONE;
15017 (define_split
15018   [(set (match_operand 0 "register_operand" "")
15019         (match_operator 3 "binary_fp_operator"
15020            [(match_operand 1 "register_operand" "")
15021             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15022   "TARGET_80387 && reload_completed
15023    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15024   [(const_int 0)]
15026   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15027   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15028   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15029                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15030                                           GET_MODE (operands[3]),
15031                                           operands[1],
15032                                           operands[4])));
15033   ix86_free_from_memory (GET_MODE (operands[2]));
15034   DONE;
15037 ;; FPU special functions.
15039 (define_expand "sqrtsf2"
15040   [(set (match_operand:SF 0 "register_operand" "")
15041         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15042   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15044   if (!TARGET_SSE_MATH)
15045     operands[1] = force_reg (SFmode, operands[1]);
15048 (define_insn "*sqrtsf2_mixed"
15049   [(set (match_operand:SF 0 "register_operand" "=f,x")
15050         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15051   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15052   "@
15053    fsqrt
15054    sqrtss\t{%1, %0|%0, %1}"
15055   [(set_attr "type" "fpspc,sse")
15056    (set_attr "mode" "SF,SF")
15057    (set_attr "athlon_decode" "direct,*")])
15059 (define_insn "*sqrtsf2_sse"
15060   [(set (match_operand:SF 0 "register_operand" "=x")
15061         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15062   "TARGET_SSE_MATH"
15063   "sqrtss\t{%1, %0|%0, %1}"
15064   [(set_attr "type" "sse")
15065    (set_attr "mode" "SF")
15066    (set_attr "athlon_decode" "*")])
15068 (define_insn "*sqrtsf2_i387"
15069   [(set (match_operand:SF 0 "register_operand" "=f")
15070         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15071   "TARGET_USE_FANCY_MATH_387"
15072   "fsqrt"
15073   [(set_attr "type" "fpspc")
15074    (set_attr "mode" "SF")
15075    (set_attr "athlon_decode" "direct")])
15077 (define_expand "sqrtdf2"
15078   [(set (match_operand:DF 0 "register_operand" "")
15079         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15080   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15082   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15083     operands[1] = force_reg (DFmode, operands[1]);
15086 (define_insn "*sqrtdf2_mixed"
15087   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15088         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15089   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15090   "@
15091    fsqrt
15092    sqrtsd\t{%1, %0|%0, %1}"
15093   [(set_attr "type" "fpspc,sse")
15094    (set_attr "mode" "DF,DF")
15095    (set_attr "athlon_decode" "direct,*")])
15097 (define_insn "*sqrtdf2_sse"
15098   [(set (match_operand:DF 0 "register_operand" "=Y")
15099         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15100   "TARGET_SSE2 && TARGET_SSE_MATH"
15101   "sqrtsd\t{%1, %0|%0, %1}"
15102   [(set_attr "type" "sse")
15103    (set_attr "mode" "DF")
15104    (set_attr "athlon_decode" "*")])
15106 (define_insn "*sqrtdf2_i387"
15107   [(set (match_operand:DF 0 "register_operand" "=f")
15108         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15109   "TARGET_USE_FANCY_MATH_387"
15110   "fsqrt"
15111   [(set_attr "type" "fpspc")
15112    (set_attr "mode" "DF")
15113    (set_attr "athlon_decode" "direct")])
15115 (define_insn "*sqrtextendsfdf2_i387"
15116   [(set (match_operand:DF 0 "register_operand" "=f")
15117         (sqrt:DF (float_extend:DF
15118                   (match_operand:SF 1 "register_operand" "0"))))]
15119   "TARGET_USE_FANCY_MATH_387
15120    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15121   "fsqrt"
15122   [(set_attr "type" "fpspc")
15123    (set_attr "mode" "DF")
15124    (set_attr "athlon_decode" "direct")])
15126 (define_insn "sqrtxf2"
15127   [(set (match_operand:XF 0 "register_operand" "=f")
15128         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15129   "TARGET_USE_FANCY_MATH_387 
15130    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15131   "fsqrt"
15132   [(set_attr "type" "fpspc")
15133    (set_attr "mode" "XF")
15134    (set_attr "athlon_decode" "direct")])
15136 (define_insn "*sqrtextendsfxf2_i387"
15137   [(set (match_operand:XF 0 "register_operand" "=f")
15138         (sqrt:XF (float_extend:XF
15139                   (match_operand:SF 1 "register_operand" "0"))))]
15140   "TARGET_USE_FANCY_MATH_387"
15141   "fsqrt"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "XF")
15144    (set_attr "athlon_decode" "direct")])
15146 (define_insn "*sqrtextenddfxf2_i387"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (sqrt:XF (float_extend:XF
15149                   (match_operand:DF 1 "register_operand" "0"))))]
15150   "TARGET_USE_FANCY_MATH_387"
15151   "fsqrt"
15152   [(set_attr "type" "fpspc")
15153    (set_attr "mode" "XF")
15154    (set_attr "athlon_decode" "direct")])
15156 (define_insn "fpremxf4"
15157   [(set (match_operand:XF 0 "register_operand" "=f")
15158         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15159                     (match_operand:XF 3 "register_operand" "1")]
15160                    UNSPEC_FPREM_F))
15161    (set (match_operand:XF 1 "register_operand" "=u")
15162         (unspec:XF [(match_dup 2) (match_dup 3)]
15163                    UNSPEC_FPREM_U))
15164    (set (reg:CCFP FPSR_REG)
15165         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && flag_unsafe_math_optimizations"
15168   "fprem"
15169   [(set_attr "type" "fpspc")
15170    (set_attr "mode" "XF")])
15172 (define_expand "fmodsf3"
15173   [(use (match_operand:SF 0 "register_operand" ""))
15174    (use (match_operand:SF 1 "register_operand" ""))
15175    (use (match_operand:SF 2 "register_operand" ""))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15178    && flag_unsafe_math_optimizations"
15180   rtx label = gen_label_rtx ();
15182   rtx op1 = gen_reg_rtx (XFmode);
15183   rtx op2 = gen_reg_rtx (XFmode);
15185   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15186   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15188   emit_label (label);
15190   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15191   ix86_emit_fp_unordered_jump (label);
15193   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15194   DONE;
15197 (define_expand "fmoddf3"
15198   [(use (match_operand:DF 0 "register_operand" ""))
15199    (use (match_operand:DF 1 "register_operand" ""))
15200    (use (match_operand:DF 2 "register_operand" ""))]
15201   "TARGET_USE_FANCY_MATH_387
15202    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15203    && flag_unsafe_math_optimizations"
15205   rtx label = gen_label_rtx ();
15207   rtx op1 = gen_reg_rtx (XFmode);
15208   rtx op2 = gen_reg_rtx (XFmode);
15210   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15211   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15213   emit_label (label);
15215   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15216   ix86_emit_fp_unordered_jump (label);
15218   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15219   DONE;
15222 (define_expand "fmodxf3"
15223   [(use (match_operand:XF 0 "register_operand" ""))
15224    (use (match_operand:XF 1 "register_operand" ""))
15225    (use (match_operand:XF 2 "register_operand" ""))]
15226   "TARGET_USE_FANCY_MATH_387
15227    && flag_unsafe_math_optimizations"
15229   rtx label = gen_label_rtx ();
15231   emit_label (label);
15233   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15234                            operands[1], operands[2]));
15235   ix86_emit_fp_unordered_jump (label);
15237   emit_move_insn (operands[0], operands[1]);
15238   DONE;
15241 (define_insn "fprem1xf4"
15242   [(set (match_operand:XF 0 "register_operand" "=f")
15243         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15244                     (match_operand:XF 3 "register_operand" "1")]
15245                    UNSPEC_FPREM1_F))
15246    (set (match_operand:XF 1 "register_operand" "=u")
15247         (unspec:XF [(match_dup 2) (match_dup 3)]
15248                    UNSPEC_FPREM1_U))
15249    (set (reg:CCFP FPSR_REG)
15250         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15251   "TARGET_USE_FANCY_MATH_387
15252    && flag_unsafe_math_optimizations"
15253   "fprem1"
15254   [(set_attr "type" "fpspc")
15255    (set_attr "mode" "XF")])
15257 (define_expand "dremsf3"
15258   [(use (match_operand:SF 0 "register_operand" ""))
15259    (use (match_operand:SF 1 "register_operand" ""))
15260    (use (match_operand:SF 2 "register_operand" ""))]
15261   "TARGET_USE_FANCY_MATH_387
15262    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15263    && flag_unsafe_math_optimizations"
15265   rtx label = gen_label_rtx ();
15267   rtx op1 = gen_reg_rtx (XFmode);
15268   rtx op2 = gen_reg_rtx (XFmode);
15270   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15271   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15273   emit_label (label);
15275   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15276   ix86_emit_fp_unordered_jump (label);
15278   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15279   DONE;
15282 (define_expand "dremdf3"
15283   [(use (match_operand:DF 0 "register_operand" ""))
15284    (use (match_operand:DF 1 "register_operand" ""))
15285    (use (match_operand:DF 2 "register_operand" ""))]
15286   "TARGET_USE_FANCY_MATH_387
15287    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15288    && flag_unsafe_math_optimizations"
15290   rtx label = gen_label_rtx ();
15292   rtx op1 = gen_reg_rtx (XFmode);
15293   rtx op2 = gen_reg_rtx (XFmode);
15295   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15296   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15298   emit_label (label);
15300   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15301   ix86_emit_fp_unordered_jump (label);
15303   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15304   DONE;
15307 (define_expand "dremxf3"
15308   [(use (match_operand:XF 0 "register_operand" ""))
15309    (use (match_operand:XF 1 "register_operand" ""))
15310    (use (match_operand:XF 2 "register_operand" ""))]
15311   "TARGET_USE_FANCY_MATH_387
15312    && flag_unsafe_math_optimizations"
15314   rtx label = gen_label_rtx ();
15316   emit_label (label);
15318   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15319                             operands[1], operands[2]));
15320   ix86_emit_fp_unordered_jump (label);
15322   emit_move_insn (operands[0], operands[1]);
15323   DONE;
15326 (define_insn "*sindf2"
15327   [(set (match_operand:DF 0 "register_operand" "=f")
15328         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15331    && flag_unsafe_math_optimizations"
15332   "fsin"
15333   [(set_attr "type" "fpspc")
15334    (set_attr "mode" "DF")])
15336 (define_insn "*sinsf2"
15337   [(set (match_operand:SF 0 "register_operand" "=f")
15338         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15339   "TARGET_USE_FANCY_MATH_387
15340    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15341    && flag_unsafe_math_optimizations"
15342   "fsin"
15343   [(set_attr "type" "fpspc")
15344    (set_attr "mode" "SF")])
15346 (define_insn "*sinextendsfdf2"
15347   [(set (match_operand:DF 0 "register_operand" "=f")
15348         (unspec:DF [(float_extend:DF
15349                      (match_operand:SF 1 "register_operand" "0"))]
15350                    UNSPEC_SIN))]
15351   "TARGET_USE_FANCY_MATH_387
15352    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15353    && flag_unsafe_math_optimizations"
15354   "fsin"
15355   [(set_attr "type" "fpspc")
15356    (set_attr "mode" "DF")])
15358 (define_insn "*sinxf2"
15359   [(set (match_operand:XF 0 "register_operand" "=f")
15360         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15361   "TARGET_USE_FANCY_MATH_387
15362    && flag_unsafe_math_optimizations"
15363   "fsin"
15364   [(set_attr "type" "fpspc")
15365    (set_attr "mode" "XF")])
15367 (define_insn "*cosdf2"
15368   [(set (match_operand:DF 0 "register_operand" "=f")
15369         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15370   "TARGET_USE_FANCY_MATH_387
15371    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15372    && flag_unsafe_math_optimizations"
15373   "fcos"
15374   [(set_attr "type" "fpspc")
15375    (set_attr "mode" "DF")])
15377 (define_insn "*cossf2"
15378   [(set (match_operand:SF 0 "register_operand" "=f")
15379         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15380   "TARGET_USE_FANCY_MATH_387
15381    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15382    && flag_unsafe_math_optimizations"
15383   "fcos"
15384   [(set_attr "type" "fpspc")
15385    (set_attr "mode" "SF")])
15387 (define_insn "*cosextendsfdf2"
15388   [(set (match_operand:DF 0 "register_operand" "=f")
15389         (unspec:DF [(float_extend:DF
15390                      (match_operand:SF 1 "register_operand" "0"))]
15391                    UNSPEC_COS))]
15392   "TARGET_USE_FANCY_MATH_387
15393    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15394    && flag_unsafe_math_optimizations"
15395   "fcos"
15396   [(set_attr "type" "fpspc")
15397    (set_attr "mode" "DF")])
15399 (define_insn "*cosxf2"
15400   [(set (match_operand:XF 0 "register_operand" "=f")
15401         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15402   "TARGET_USE_FANCY_MATH_387
15403    && flag_unsafe_math_optimizations"
15404   "fcos"
15405   [(set_attr "type" "fpspc")
15406    (set_attr "mode" "XF")])
15408 ;; With sincos pattern defined, sin and cos builtin function will be
15409 ;; expanded to sincos pattern with one of its outputs left unused. 
15410 ;; Cse pass  will detected, if two sincos patterns can be combined,
15411 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15412 ;; depending on the unused output.
15414 (define_insn "sincosdf3"
15415   [(set (match_operand:DF 0 "register_operand" "=f")
15416         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15417                    UNSPEC_SINCOS_COS))
15418    (set (match_operand:DF 1 "register_operand" "=u")
15419         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15420   "TARGET_USE_FANCY_MATH_387
15421    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15422    && flag_unsafe_math_optimizations"
15423   "fsincos"
15424   [(set_attr "type" "fpspc")
15425    (set_attr "mode" "DF")])
15427 (define_split
15428   [(set (match_operand:DF 0 "register_operand" "")
15429         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15430                    UNSPEC_SINCOS_COS))
15431    (set (match_operand:DF 1 "register_operand" "")
15432         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15433   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15434    && !reload_completed && !reload_in_progress"
15435   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15436   "")
15438 (define_split
15439   [(set (match_operand:DF 0 "register_operand" "")
15440         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15441                    UNSPEC_SINCOS_COS))
15442    (set (match_operand:DF 1 "register_operand" "")
15443         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15444   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15445    && !reload_completed && !reload_in_progress"
15446   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15447   "")
15449 (define_insn "sincossf3"
15450   [(set (match_operand:SF 0 "register_operand" "=f")
15451         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15452                    UNSPEC_SINCOS_COS))
15453    (set (match_operand:SF 1 "register_operand" "=u")
15454         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15455   "TARGET_USE_FANCY_MATH_387
15456    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15457    && flag_unsafe_math_optimizations"
15458   "fsincos"
15459   [(set_attr "type" "fpspc")
15460    (set_attr "mode" "SF")])
15462 (define_split
15463   [(set (match_operand:SF 0 "register_operand" "")
15464         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15465                    UNSPEC_SINCOS_COS))
15466    (set (match_operand:SF 1 "register_operand" "")
15467         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15468   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15469    && !reload_completed && !reload_in_progress"
15470   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15471   "")
15473 (define_split
15474   [(set (match_operand:SF 0 "register_operand" "")
15475         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15476                    UNSPEC_SINCOS_COS))
15477    (set (match_operand:SF 1 "register_operand" "")
15478         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15479   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15480    && !reload_completed && !reload_in_progress"
15481   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15482   "")
15484 (define_insn "*sincosextendsfdf3"
15485   [(set (match_operand:DF 0 "register_operand" "=f")
15486         (unspec:DF [(float_extend:DF
15487                      (match_operand:SF 2 "register_operand" "0"))]
15488                    UNSPEC_SINCOS_COS))
15489    (set (match_operand:DF 1 "register_operand" "=u")
15490         (unspec:DF [(float_extend:DF
15491                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15492   "TARGET_USE_FANCY_MATH_387
15493    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15494    && flag_unsafe_math_optimizations"
15495   "fsincos"
15496   [(set_attr "type" "fpspc")
15497    (set_attr "mode" "DF")])
15499 (define_split
15500   [(set (match_operand:DF 0 "register_operand" "")
15501         (unspec:DF [(float_extend:DF
15502                      (match_operand:SF 2 "register_operand" ""))]
15503                    UNSPEC_SINCOS_COS))
15504    (set (match_operand:DF 1 "register_operand" "")
15505         (unspec:DF [(float_extend:DF
15506                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15507   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15508    && !reload_completed && !reload_in_progress"
15509   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15510                                    (match_dup 2))] UNSPEC_SIN))]
15511   "")
15513 (define_split
15514   [(set (match_operand:DF 0 "register_operand" "")
15515         (unspec:DF [(float_extend:DF
15516                      (match_operand:SF 2 "register_operand" ""))]
15517                    UNSPEC_SINCOS_COS))
15518    (set (match_operand:DF 1 "register_operand" "")
15519         (unspec:DF [(float_extend:DF
15520                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15521   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15522    && !reload_completed && !reload_in_progress"
15523   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15524                                    (match_dup 2))] UNSPEC_COS))]
15525   "")
15527 (define_insn "sincosxf3"
15528   [(set (match_operand:XF 0 "register_operand" "=f")
15529         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15530                    UNSPEC_SINCOS_COS))
15531    (set (match_operand:XF 1 "register_operand" "=u")
15532         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && flag_unsafe_math_optimizations"
15535   "fsincos"
15536   [(set_attr "type" "fpspc")
15537    (set_attr "mode" "XF")])
15539 (define_split
15540   [(set (match_operand:XF 0 "register_operand" "")
15541         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15542                    UNSPEC_SINCOS_COS))
15543    (set (match_operand:XF 1 "register_operand" "")
15544         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15545   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15546    && !reload_completed && !reload_in_progress"
15547   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15548   "")
15550 (define_split
15551   [(set (match_operand:XF 0 "register_operand" "")
15552         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15553                    UNSPEC_SINCOS_COS))
15554    (set (match_operand:XF 1 "register_operand" "")
15555         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15556   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15557    && !reload_completed && !reload_in_progress"
15558   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15559   "")
15561 (define_insn "*tandf3_1"
15562   [(set (match_operand:DF 0 "register_operand" "=f")
15563         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15564                    UNSPEC_TAN_ONE))
15565    (set (match_operand:DF 1 "register_operand" "=u")
15566         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15569    && flag_unsafe_math_optimizations"
15570   "fptan"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "DF")])
15574 ;; optimize sequence: fptan
15575 ;;                    fstp    %st(0)
15576 ;;                    fld1
15577 ;; into fptan insn.
15579 (define_peephole2
15580   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15581                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15582                              UNSPEC_TAN_ONE))
15583              (set (match_operand:DF 1 "register_operand" "")
15584                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15585    (set (match_dup 0)
15586         (match_operand:DF 3 "immediate_operand" ""))]
15587   "standard_80387_constant_p (operands[3]) == 2"
15588   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15589              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15590   "")
15592 (define_expand "tandf2"
15593   [(parallel [(set (match_dup 2)
15594                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15595                               UNSPEC_TAN_ONE))
15596               (set (match_operand:DF 0 "register_operand" "")
15597                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15598   "TARGET_USE_FANCY_MATH_387
15599    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15600    && flag_unsafe_math_optimizations"
15602   operands[2] = gen_reg_rtx (DFmode);
15605 (define_insn "*tansf3_1"
15606   [(set (match_operand:SF 0 "register_operand" "=f")
15607         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15608                    UNSPEC_TAN_ONE))
15609    (set (match_operand:SF 1 "register_operand" "=u")
15610         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15611   "TARGET_USE_FANCY_MATH_387
15612    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15613    && flag_unsafe_math_optimizations"
15614   "fptan"
15615   [(set_attr "type" "fpspc")
15616    (set_attr "mode" "SF")])
15618 ;; optimize sequence: fptan
15619 ;;                    fstp    %st(0)
15620 ;;                    fld1
15621 ;; into fptan insn.
15623 (define_peephole2
15624   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15625                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15626                              UNSPEC_TAN_ONE))
15627              (set (match_operand:SF 1 "register_operand" "")
15628                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15629    (set (match_dup 0)
15630         (match_operand:SF 3 "immediate_operand" ""))]
15631   "standard_80387_constant_p (operands[3]) == 2"
15632   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15633              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15634   "")
15636 (define_expand "tansf2"
15637   [(parallel [(set (match_dup 2)
15638                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15639                               UNSPEC_TAN_ONE))
15640               (set (match_operand:SF 0 "register_operand" "")
15641                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15642   "TARGET_USE_FANCY_MATH_387
15643    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15644    && flag_unsafe_math_optimizations"
15646   operands[2] = gen_reg_rtx (SFmode);
15649 (define_insn "*tanxf3_1"
15650   [(set (match_operand:XF 0 "register_operand" "=f")
15651         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15652                    UNSPEC_TAN_ONE))
15653    (set (match_operand:XF 1 "register_operand" "=u")
15654         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15655   "TARGET_USE_FANCY_MATH_387
15656    && flag_unsafe_math_optimizations"
15657   "fptan"
15658   [(set_attr "type" "fpspc")
15659    (set_attr "mode" "XF")])
15661 ;; optimize sequence: fptan
15662 ;;                    fstp    %st(0)
15663 ;;                    fld1
15664 ;; into fptan insn.
15666 (define_peephole2
15667   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15668                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15669                              UNSPEC_TAN_ONE))
15670              (set (match_operand:XF 1 "register_operand" "")
15671                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15672    (set (match_dup 0)
15673         (match_operand:XF 3 "immediate_operand" ""))]
15674   "standard_80387_constant_p (operands[3]) == 2"
15675   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15676              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15677   "")
15679 (define_expand "tanxf2"
15680   [(parallel [(set (match_dup 2)
15681                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15682                               UNSPEC_TAN_ONE))
15683               (set (match_operand:XF 0 "register_operand" "")
15684                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15685   "TARGET_USE_FANCY_MATH_387
15686    && flag_unsafe_math_optimizations"
15688   operands[2] = gen_reg_rtx (XFmode);
15691 (define_insn "atan2df3_1"
15692   [(set (match_operand:DF 0 "register_operand" "=f")
15693         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15694                     (match_operand:DF 1 "register_operand" "u")]
15695                    UNSPEC_FPATAN))
15696    (clobber (match_scratch:DF 3 "=1"))]
15697   "TARGET_USE_FANCY_MATH_387
15698    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15699    && flag_unsafe_math_optimizations"
15700   "fpatan"
15701   [(set_attr "type" "fpspc")
15702    (set_attr "mode" "DF")])
15704 (define_expand "atan2df3"
15705   [(use (match_operand:DF 0 "register_operand" ""))
15706    (use (match_operand:DF 2 "register_operand" ""))
15707    (use (match_operand:DF 1 "register_operand" ""))]
15708   "TARGET_USE_FANCY_MATH_387
15709    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15710    && flag_unsafe_math_optimizations"
15712   rtx copy = gen_reg_rtx (DFmode);
15713   emit_move_insn (copy, operands[1]);
15714   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15715   DONE;
15718 (define_expand "atandf2"
15719   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15720                    (unspec:DF [(match_dup 2)
15721                                (match_operand:DF 1 "register_operand" "")]
15722                     UNSPEC_FPATAN))
15723               (clobber (match_scratch:DF 3 ""))])]
15724   "TARGET_USE_FANCY_MATH_387
15725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15726    && flag_unsafe_math_optimizations"
15728   operands[2] = gen_reg_rtx (DFmode);
15729   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15732 (define_insn "atan2sf3_1"
15733   [(set (match_operand:SF 0 "register_operand" "=f")
15734         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15735                     (match_operand:SF 1 "register_operand" "u")]
15736                    UNSPEC_FPATAN))
15737    (clobber (match_scratch:SF 3 "=1"))]
15738   "TARGET_USE_FANCY_MATH_387
15739    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15740    && flag_unsafe_math_optimizations"
15741   "fpatan"
15742   [(set_attr "type" "fpspc")
15743    (set_attr "mode" "SF")])
15745 (define_expand "atan2sf3"
15746   [(use (match_operand:SF 0 "register_operand" ""))
15747    (use (match_operand:SF 2 "register_operand" ""))
15748    (use (match_operand:SF 1 "register_operand" ""))]
15749   "TARGET_USE_FANCY_MATH_387
15750    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15751    && flag_unsafe_math_optimizations"
15753   rtx copy = gen_reg_rtx (SFmode);
15754   emit_move_insn (copy, operands[1]);
15755   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15756   DONE;
15759 (define_expand "atansf2"
15760   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15761                    (unspec:SF [(match_dup 2)
15762                                (match_operand:SF 1 "register_operand" "")]
15763                     UNSPEC_FPATAN))
15764               (clobber (match_scratch:SF 3 ""))])]
15765   "TARGET_USE_FANCY_MATH_387
15766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15767    && flag_unsafe_math_optimizations"
15769   operands[2] = gen_reg_rtx (SFmode);
15770   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15773 (define_insn "atan2xf3_1"
15774   [(set (match_operand:XF 0 "register_operand" "=f")
15775         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15776                     (match_operand:XF 1 "register_operand" "u")]
15777                    UNSPEC_FPATAN))
15778    (clobber (match_scratch:XF 3 "=1"))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && flag_unsafe_math_optimizations"
15781   "fpatan"
15782   [(set_attr "type" "fpspc")
15783    (set_attr "mode" "XF")])
15785 (define_expand "atan2xf3"
15786   [(use (match_operand:XF 0 "register_operand" ""))
15787    (use (match_operand:XF 2 "register_operand" ""))
15788    (use (match_operand:XF 1 "register_operand" ""))]
15789   "TARGET_USE_FANCY_MATH_387
15790    && flag_unsafe_math_optimizations"
15792   rtx copy = gen_reg_rtx (XFmode);
15793   emit_move_insn (copy, operands[1]);
15794   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15795   DONE;
15798 (define_expand "atanxf2"
15799   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15800                    (unspec:XF [(match_dup 2)
15801                                (match_operand:XF 1 "register_operand" "")]
15802                     UNSPEC_FPATAN))
15803               (clobber (match_scratch:XF 3 ""))])]
15804   "TARGET_USE_FANCY_MATH_387
15805    && flag_unsafe_math_optimizations"
15807   operands[2] = gen_reg_rtx (XFmode);
15808   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15811 (define_expand "asindf2"
15812   [(set (match_dup 2)
15813         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15814    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15815    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15816    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15817    (parallel [(set (match_dup 7)
15818                    (unspec:XF [(match_dup 6) (match_dup 2)]
15819                               UNSPEC_FPATAN))
15820               (clobber (match_scratch:XF 8 ""))])
15821    (set (match_operand:DF 0 "register_operand" "")
15822         (float_truncate:DF (match_dup 7)))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825    && flag_unsafe_math_optimizations"
15827   int i;
15829   for (i=2; i<8; i++)
15830     operands[i] = gen_reg_rtx (XFmode);
15832   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15835 (define_expand "asinsf2"
15836   [(set (match_dup 2)
15837         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15838    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15839    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15840    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15841    (parallel [(set (match_dup 7)
15842                    (unspec:XF [(match_dup 6) (match_dup 2)]
15843                               UNSPEC_FPATAN))
15844               (clobber (match_scratch:XF 8 ""))])
15845    (set (match_operand:SF 0 "register_operand" "")
15846         (float_truncate:SF (match_dup 7)))]
15847   "TARGET_USE_FANCY_MATH_387
15848    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15849    && flag_unsafe_math_optimizations"
15851   int i;
15853   for (i=2; i<8; i++)
15854     operands[i] = gen_reg_rtx (XFmode);
15856   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15859 (define_expand "asinxf2"
15860   [(set (match_dup 2)
15861         (mult:XF (match_operand:XF 1 "register_operand" "")
15862                  (match_dup 1)))
15863    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15864    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15865    (parallel [(set (match_operand:XF 0 "register_operand" "")
15866                    (unspec:XF [(match_dup 5) (match_dup 1)]
15867                               UNSPEC_FPATAN))
15868               (clobber (match_scratch:XF 6 ""))])]
15869   "TARGET_USE_FANCY_MATH_387
15870    && flag_unsafe_math_optimizations"
15872   int i;
15874   for (i=2; i<6; i++)
15875     operands[i] = gen_reg_rtx (XFmode);
15877   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15880 (define_expand "acosdf2"
15881   [(set (match_dup 2)
15882         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15883    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15884    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15885    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15886    (parallel [(set (match_dup 7)
15887                    (unspec:XF [(match_dup 2) (match_dup 6)]
15888                               UNSPEC_FPATAN))
15889               (clobber (match_scratch:XF 8 ""))])
15890    (set (match_operand:DF 0 "register_operand" "")
15891         (float_truncate:DF (match_dup 7)))]
15892   "TARGET_USE_FANCY_MATH_387
15893    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15894    && flag_unsafe_math_optimizations"
15896   int i;
15898   for (i=2; i<8; i++)
15899     operands[i] = gen_reg_rtx (XFmode);
15901   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15904 (define_expand "acossf2"
15905   [(set (match_dup 2)
15906         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15907    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15908    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15909    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15910    (parallel [(set (match_dup 7)
15911                    (unspec:XF [(match_dup 2) (match_dup 6)]
15912                               UNSPEC_FPATAN))
15913               (clobber (match_scratch:XF 8 ""))])
15914    (set (match_operand:SF 0 "register_operand" "")
15915         (float_truncate:SF (match_dup 7)))]
15916   "TARGET_USE_FANCY_MATH_387
15917    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15918    && flag_unsafe_math_optimizations"
15920   int i;
15922   for (i=2; i<8; i++)
15923     operands[i] = gen_reg_rtx (XFmode);
15925   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15928 (define_expand "acosxf2"
15929   [(set (match_dup 2)
15930         (mult:XF (match_operand:XF 1 "register_operand" "")
15931                  (match_dup 1)))
15932    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15933    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15934    (parallel [(set (match_operand:XF 0 "register_operand" "")
15935                    (unspec:XF [(match_dup 1) (match_dup 5)]
15936                               UNSPEC_FPATAN))
15937               (clobber (match_scratch:XF 6 ""))])]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15941   int i;
15943   for (i=2; i<6; i++)
15944     operands[i] = gen_reg_rtx (XFmode);
15946   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15949 (define_insn "fyl2x_xf3"
15950   [(set (match_operand:XF 0 "register_operand" "=f")
15951         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15952                     (match_operand:XF 1 "register_operand" "u")]
15953                    UNSPEC_FYL2X))
15954    (clobber (match_scratch:XF 3 "=1"))]
15955   "TARGET_USE_FANCY_MATH_387
15956    && flag_unsafe_math_optimizations"
15957   "fyl2x"
15958   [(set_attr "type" "fpspc")
15959    (set_attr "mode" "XF")])
15961 (define_expand "logsf2"
15962   [(set (match_dup 2)
15963         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15964    (parallel [(set (match_dup 4)
15965                    (unspec:XF [(match_dup 2)
15966                                (match_dup 3)] UNSPEC_FYL2X))
15967               (clobber (match_scratch:XF 5 ""))])
15968    (set (match_operand:SF 0 "register_operand" "")
15969         (float_truncate:SF (match_dup 4)))]
15970   "TARGET_USE_FANCY_MATH_387
15971    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15972    && flag_unsafe_math_optimizations"
15974   rtx temp;
15976   operands[2] = gen_reg_rtx (XFmode);
15977   operands[3] = gen_reg_rtx (XFmode);
15978   operands[4] = gen_reg_rtx (XFmode);
15980   temp = standard_80387_constant_rtx (4); /* fldln2 */
15981   emit_move_insn (operands[3], temp);
15984 (define_expand "logdf2"
15985   [(set (match_dup 2)
15986         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15987    (parallel [(set (match_dup 4)
15988                    (unspec:XF [(match_dup 2)
15989                                (match_dup 3)] UNSPEC_FYL2X))
15990               (clobber (match_scratch:XF 5 ""))])
15991    (set (match_operand:DF 0 "register_operand" "")
15992         (float_truncate:DF (match_dup 4)))]
15993   "TARGET_USE_FANCY_MATH_387
15994    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15995    && flag_unsafe_math_optimizations"
15997   rtx temp;
15999   operands[2] = gen_reg_rtx (XFmode);
16000   operands[3] = gen_reg_rtx (XFmode);
16001   operands[4] = gen_reg_rtx (XFmode);
16003   temp = standard_80387_constant_rtx (4); /* fldln2 */
16004   emit_move_insn (operands[3], temp);
16007 (define_expand "logxf2"
16008   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16009                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16010                                (match_dup 2)] UNSPEC_FYL2X))
16011               (clobber (match_scratch:XF 3 ""))])]
16012   "TARGET_USE_FANCY_MATH_387
16013    && flag_unsafe_math_optimizations"
16015   rtx temp;
16017   operands[2] = gen_reg_rtx (XFmode);
16018   temp = standard_80387_constant_rtx (4); /* fldln2 */
16019   emit_move_insn (operands[2], temp);
16022 (define_expand "log10sf2"
16023   [(set (match_dup 2)
16024         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16025    (parallel [(set (match_dup 4)
16026                    (unspec:XF [(match_dup 2)
16027                                (match_dup 3)] UNSPEC_FYL2X))
16028               (clobber (match_scratch:XF 5 ""))])
16029    (set (match_operand:SF 0 "register_operand" "")
16030         (float_truncate:SF (match_dup 4)))]
16031   "TARGET_USE_FANCY_MATH_387
16032    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16033    && flag_unsafe_math_optimizations"
16035   rtx temp;
16037   operands[2] = gen_reg_rtx (XFmode);
16038   operands[3] = gen_reg_rtx (XFmode);
16039   operands[4] = gen_reg_rtx (XFmode);
16041   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16042   emit_move_insn (operands[3], temp);
16045 (define_expand "log10df2"
16046   [(set (match_dup 2)
16047         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16048    (parallel [(set (match_dup 4)
16049                    (unspec:XF [(match_dup 2)
16050                                (match_dup 3)] UNSPEC_FYL2X))
16051               (clobber (match_scratch:XF 5 ""))])
16052    (set (match_operand:DF 0 "register_operand" "")
16053         (float_truncate:DF (match_dup 4)))]
16054   "TARGET_USE_FANCY_MATH_387
16055    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16056    && flag_unsafe_math_optimizations"
16058   rtx temp;
16060   operands[2] = gen_reg_rtx (XFmode);
16061   operands[3] = gen_reg_rtx (XFmode);
16062   operands[4] = gen_reg_rtx (XFmode);
16064   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16065   emit_move_insn (operands[3], temp);
16068 (define_expand "log10xf2"
16069   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16070                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16071                                (match_dup 2)] UNSPEC_FYL2X))
16072               (clobber (match_scratch:XF 3 ""))])]
16073   "TARGET_USE_FANCY_MATH_387
16074    && flag_unsafe_math_optimizations"
16076   rtx temp;
16078   operands[2] = gen_reg_rtx (XFmode);
16079   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16080   emit_move_insn (operands[2], temp);
16083 (define_expand "log2sf2"
16084   [(set (match_dup 2)
16085         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16086    (parallel [(set (match_dup 4)
16087                    (unspec:XF [(match_dup 2)
16088                                (match_dup 3)] UNSPEC_FYL2X))
16089               (clobber (match_scratch:XF 5 ""))])
16090    (set (match_operand:SF 0 "register_operand" "")
16091         (float_truncate:SF (match_dup 4)))]
16092   "TARGET_USE_FANCY_MATH_387
16093    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16094    && flag_unsafe_math_optimizations"
16096   operands[2] = gen_reg_rtx (XFmode);
16097   operands[3] = gen_reg_rtx (XFmode);
16098   operands[4] = gen_reg_rtx (XFmode);
16100   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16103 (define_expand "log2df2"
16104   [(set (match_dup 2)
16105         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16106    (parallel [(set (match_dup 4)
16107                    (unspec:XF [(match_dup 2)
16108                                (match_dup 3)] UNSPEC_FYL2X))
16109               (clobber (match_scratch:XF 5 ""))])
16110    (set (match_operand:DF 0 "register_operand" "")
16111         (float_truncate:DF (match_dup 4)))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16114    && flag_unsafe_math_optimizations"
16116   operands[2] = gen_reg_rtx (XFmode);
16117   operands[3] = gen_reg_rtx (XFmode);
16118   operands[4] = gen_reg_rtx (XFmode);
16120   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16123 (define_expand "log2xf2"
16124   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16125                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16126                                (match_dup 2)] UNSPEC_FYL2X))
16127               (clobber (match_scratch:XF 3 ""))])]
16128   "TARGET_USE_FANCY_MATH_387
16129    && flag_unsafe_math_optimizations"
16131   operands[2] = gen_reg_rtx (XFmode);
16132   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16135 (define_insn "fyl2xp1_xf3"
16136   [(set (match_operand:XF 0 "register_operand" "=f")
16137         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16138                     (match_operand:XF 1 "register_operand" "u")]
16139                    UNSPEC_FYL2XP1))
16140    (clobber (match_scratch:XF 3 "=1"))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && flag_unsafe_math_optimizations"
16143   "fyl2xp1"
16144   [(set_attr "type" "fpspc")
16145    (set_attr "mode" "XF")])
16147 (define_expand "log1psf2"
16148   [(use (match_operand:SF 0 "register_operand" ""))
16149    (use (match_operand:SF 1 "register_operand" ""))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16152    && flag_unsafe_math_optimizations"
16154   rtx op0 = gen_reg_rtx (XFmode);
16155   rtx op1 = gen_reg_rtx (XFmode);
16157   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16158   ix86_emit_i387_log1p (op0, op1);
16159   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16160   DONE;
16163 (define_expand "log1pdf2"
16164   [(use (match_operand:DF 0 "register_operand" ""))
16165    (use (match_operand:DF 1 "register_operand" ""))]
16166   "TARGET_USE_FANCY_MATH_387
16167    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16168    && flag_unsafe_math_optimizations"
16170   rtx op0 = gen_reg_rtx (XFmode);
16171   rtx op1 = gen_reg_rtx (XFmode);
16173   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16174   ix86_emit_i387_log1p (op0, op1);
16175   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16176   DONE;
16179 (define_expand "log1pxf2"
16180   [(use (match_operand:XF 0 "register_operand" ""))
16181    (use (match_operand:XF 1 "register_operand" ""))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && flag_unsafe_math_optimizations"
16185   ix86_emit_i387_log1p (operands[0], operands[1]);
16186   DONE;
16189 (define_insn "*fxtractxf3"
16190   [(set (match_operand:XF 0 "register_operand" "=f")
16191         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16192                    UNSPEC_XTRACT_FRACT))
16193    (set (match_operand:XF 1 "register_operand" "=u")
16194         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16195   "TARGET_USE_FANCY_MATH_387
16196    && flag_unsafe_math_optimizations"
16197   "fxtract"
16198   [(set_attr "type" "fpspc")
16199    (set_attr "mode" "XF")])
16201 (define_expand "logbsf2"
16202   [(set (match_dup 2)
16203         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16204    (parallel [(set (match_dup 3)
16205                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16206               (set (match_dup 4)
16207                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16208    (set (match_operand:SF 0 "register_operand" "")
16209         (float_truncate:SF (match_dup 4)))]
16210   "TARGET_USE_FANCY_MATH_387
16211    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16212    && flag_unsafe_math_optimizations"
16214   operands[2] = gen_reg_rtx (XFmode);
16215   operands[3] = gen_reg_rtx (XFmode);
16216   operands[4] = gen_reg_rtx (XFmode);
16219 (define_expand "logbdf2"
16220   [(set (match_dup 2)
16221         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16222    (parallel [(set (match_dup 3)
16223                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16224               (set (match_dup 4)
16225                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16226    (set (match_operand:DF 0 "register_operand" "")
16227         (float_truncate:DF (match_dup 4)))]
16228   "TARGET_USE_FANCY_MATH_387
16229    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16230    && flag_unsafe_math_optimizations"
16232   operands[2] = gen_reg_rtx (XFmode);
16233   operands[3] = gen_reg_rtx (XFmode);
16234   operands[4] = gen_reg_rtx (XFmode);
16237 (define_expand "logbxf2"
16238   [(parallel [(set (match_dup 2)
16239                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16240                               UNSPEC_XTRACT_FRACT))
16241               (set (match_operand:XF 0 "register_operand" "")
16242                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16243   "TARGET_USE_FANCY_MATH_387
16244    && flag_unsafe_math_optimizations"
16246   operands[2] = gen_reg_rtx (XFmode);
16249 (define_expand "ilogbsi2"
16250   [(parallel [(set (match_dup 2)
16251                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16252                               UNSPEC_XTRACT_FRACT))
16253               (set (match_operand:XF 3 "register_operand" "")
16254                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16255    (parallel [(set (match_operand:SI 0 "register_operand" "")
16256                    (fix:SI (match_dup 3)))
16257               (clobber (reg:CC FLAGS_REG))])]
16258   "TARGET_USE_FANCY_MATH_387
16259    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16260    && flag_unsafe_math_optimizations"
16262   operands[2] = gen_reg_rtx (XFmode);
16263   operands[3] = gen_reg_rtx (XFmode);
16266 (define_insn "*f2xm1xf2"
16267   [(set (match_operand:XF 0 "register_operand" "=f")
16268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16269          UNSPEC_F2XM1))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && flag_unsafe_math_optimizations"
16272   "f2xm1"
16273   [(set_attr "type" "fpspc")
16274    (set_attr "mode" "XF")])
16276 (define_insn "*fscalexf4"
16277   [(set (match_operand:XF 0 "register_operand" "=f")
16278         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16279                     (match_operand:XF 3 "register_operand" "1")]
16280                    UNSPEC_FSCALE_FRACT))
16281    (set (match_operand:XF 1 "register_operand" "=u")
16282         (unspec:XF [(match_dup 2) (match_dup 3)]
16283                    UNSPEC_FSCALE_EXP))]
16284   "TARGET_USE_FANCY_MATH_387
16285    && flag_unsafe_math_optimizations"
16286   "fscale"
16287   [(set_attr "type" "fpspc")
16288    (set_attr "mode" "XF")])
16290 (define_expand "expsf2"
16291   [(set (match_dup 2)
16292         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16293    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16294    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16295    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16296    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16297    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16298    (parallel [(set (match_dup 10)
16299                    (unspec:XF [(match_dup 9) (match_dup 5)]
16300                               UNSPEC_FSCALE_FRACT))
16301               (set (match_dup 11)
16302                    (unspec:XF [(match_dup 9) (match_dup 5)]
16303                               UNSPEC_FSCALE_EXP))])
16304    (set (match_operand:SF 0 "register_operand" "")
16305         (float_truncate:SF (match_dup 10)))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16308    && flag_unsafe_math_optimizations"
16310   rtx temp;
16311   int i;
16313   for (i=2; i<12; i++)
16314     operands[i] = gen_reg_rtx (XFmode);
16315   temp = standard_80387_constant_rtx (5); /* fldl2e */
16316   emit_move_insn (operands[3], temp);
16317   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16320 (define_expand "expdf2"
16321   [(set (match_dup 2)
16322         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16324    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16325    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16326    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16327    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16328    (parallel [(set (match_dup 10)
16329                    (unspec:XF [(match_dup 9) (match_dup 5)]
16330                               UNSPEC_FSCALE_FRACT))
16331               (set (match_dup 11)
16332                    (unspec:XF [(match_dup 9) (match_dup 5)]
16333                               UNSPEC_FSCALE_EXP))])
16334    (set (match_operand:DF 0 "register_operand" "")
16335         (float_truncate:DF (match_dup 10)))]
16336   "TARGET_USE_FANCY_MATH_387
16337    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16338    && flag_unsafe_math_optimizations"
16340   rtx temp;
16341   int i;
16343   for (i=2; i<12; i++)
16344     operands[i] = gen_reg_rtx (XFmode);
16345   temp = standard_80387_constant_rtx (5); /* fldl2e */
16346   emit_move_insn (operands[3], temp);
16347   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16350 (define_expand "expxf2"
16351   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16352                                (match_dup 2)))
16353    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16354    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16355    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16356    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16357    (parallel [(set (match_operand:XF 0 "register_operand" "")
16358                    (unspec:XF [(match_dup 8) (match_dup 4)]
16359                               UNSPEC_FSCALE_FRACT))
16360               (set (match_dup 9)
16361                    (unspec:XF [(match_dup 8) (match_dup 4)]
16362                               UNSPEC_FSCALE_EXP))])]
16363   "TARGET_USE_FANCY_MATH_387
16364    && flag_unsafe_math_optimizations"
16366   rtx temp;
16367   int i;
16369   for (i=2; i<10; i++)
16370     operands[i] = gen_reg_rtx (XFmode);
16371   temp = standard_80387_constant_rtx (5); /* fldl2e */
16372   emit_move_insn (operands[2], temp);
16373   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16376 (define_expand "exp10sf2"
16377   [(set (match_dup 2)
16378         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16379    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16380    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16381    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16382    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16383    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16384    (parallel [(set (match_dup 10)
16385                    (unspec:XF [(match_dup 9) (match_dup 5)]
16386                               UNSPEC_FSCALE_FRACT))
16387               (set (match_dup 11)
16388                    (unspec:XF [(match_dup 9) (match_dup 5)]
16389                               UNSPEC_FSCALE_EXP))])
16390    (set (match_operand:SF 0 "register_operand" "")
16391         (float_truncate:SF (match_dup 10)))]
16392   "TARGET_USE_FANCY_MATH_387
16393    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16394    && flag_unsafe_math_optimizations"
16396   rtx temp;
16397   int i;
16399   for (i=2; i<12; i++)
16400     operands[i] = gen_reg_rtx (XFmode);
16401   temp = standard_80387_constant_rtx (6); /* fldl2t */
16402   emit_move_insn (operands[3], temp);
16403   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16406 (define_expand "exp10df2"
16407   [(set (match_dup 2)
16408         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16409    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16410    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16411    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16412    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16413    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16414    (parallel [(set (match_dup 10)
16415                    (unspec:XF [(match_dup 9) (match_dup 5)]
16416                               UNSPEC_FSCALE_FRACT))
16417               (set (match_dup 11)
16418                    (unspec:XF [(match_dup 9) (match_dup 5)]
16419                               UNSPEC_FSCALE_EXP))])
16420    (set (match_operand:DF 0 "register_operand" "")
16421         (float_truncate:DF (match_dup 10)))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16424    && flag_unsafe_math_optimizations"
16426   rtx temp;
16427   int i;
16429   for (i=2; i<12; i++)
16430     operands[i] = gen_reg_rtx (XFmode);
16431   temp = standard_80387_constant_rtx (6); /* fldl2t */
16432   emit_move_insn (operands[3], temp);
16433   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16436 (define_expand "exp10xf2"
16437   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16438                                (match_dup 2)))
16439    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16440    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16441    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16442    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16443    (parallel [(set (match_operand:XF 0 "register_operand" "")
16444                    (unspec:XF [(match_dup 8) (match_dup 4)]
16445                               UNSPEC_FSCALE_FRACT))
16446               (set (match_dup 9)
16447                    (unspec:XF [(match_dup 8) (match_dup 4)]
16448                               UNSPEC_FSCALE_EXP))])]
16449   "TARGET_USE_FANCY_MATH_387
16450    && flag_unsafe_math_optimizations"
16452   rtx temp;
16453   int i;
16455   for (i=2; i<10; i++)
16456     operands[i] = gen_reg_rtx (XFmode);
16457   temp = standard_80387_constant_rtx (6); /* fldl2t */
16458   emit_move_insn (operands[2], temp);
16459   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16462 (define_expand "exp2sf2"
16463   [(set (match_dup 2)
16464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16466    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16467    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16468    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16469    (parallel [(set (match_dup 8)
16470                    (unspec:XF [(match_dup 7) (match_dup 3)]
16471                               UNSPEC_FSCALE_FRACT))
16472               (set (match_dup 9)
16473                    (unspec:XF [(match_dup 7) (match_dup 3)]
16474                               UNSPEC_FSCALE_EXP))])
16475    (set (match_operand:SF 0 "register_operand" "")
16476         (float_truncate:SF (match_dup 8)))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16479    && flag_unsafe_math_optimizations"
16481   int i;
16483   for (i=2; i<10; i++)
16484     operands[i] = gen_reg_rtx (XFmode);
16485   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16488 (define_expand "exp2df2"
16489   [(set (match_dup 2)
16490         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16491    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16492    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16493    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16494    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16495    (parallel [(set (match_dup 8)
16496                    (unspec:XF [(match_dup 7) (match_dup 3)]
16497                               UNSPEC_FSCALE_FRACT))
16498               (set (match_dup 9)
16499                    (unspec:XF [(match_dup 7) (match_dup 3)]
16500                               UNSPEC_FSCALE_EXP))])
16501    (set (match_operand:DF 0 "register_operand" "")
16502         (float_truncate:DF (match_dup 8)))]
16503   "TARGET_USE_FANCY_MATH_387
16504    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16505    && flag_unsafe_math_optimizations"
16507   int i;
16509   for (i=2; i<10; i++)
16510     operands[i] = gen_reg_rtx (XFmode);
16511   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16514 (define_expand "exp2xf2"
16515   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16516    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16517    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16518    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16519    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16520    (parallel [(set (match_operand:XF 0 "register_operand" "")
16521                    (unspec:XF [(match_dup 7) (match_dup 3)]
16522                               UNSPEC_FSCALE_FRACT))
16523               (set (match_dup 8)
16524                    (unspec:XF [(match_dup 7) (match_dup 3)]
16525                               UNSPEC_FSCALE_EXP))])]
16526   "TARGET_USE_FANCY_MATH_387
16527    && flag_unsafe_math_optimizations"
16529   int i;
16531   for (i=2; i<9; i++)
16532     operands[i] = gen_reg_rtx (XFmode);
16533   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16536 (define_expand "expm1df2"
16537   [(set (match_dup 2)
16538         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16539    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16540    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16541    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16542    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16543    (parallel [(set (match_dup 8)
16544                    (unspec:XF [(match_dup 7) (match_dup 5)]
16545                               UNSPEC_FSCALE_FRACT))
16546                    (set (match_dup 9)
16547                    (unspec:XF [(match_dup 7) (match_dup 5)]
16548                               UNSPEC_FSCALE_EXP))])
16549    (parallel [(set (match_dup 11)
16550                    (unspec:XF [(match_dup 10) (match_dup 9)]
16551                               UNSPEC_FSCALE_FRACT))
16552               (set (match_dup 12)
16553                    (unspec:XF [(match_dup 10) (match_dup 9)]
16554                               UNSPEC_FSCALE_EXP))])
16555    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16556    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16557    (set (match_operand:DF 0 "register_operand" "")
16558         (float_truncate:DF (match_dup 14)))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16561    && flag_unsafe_math_optimizations"
16563   rtx temp;
16564   int i;
16566   for (i=2; i<15; i++)
16567     operands[i] = gen_reg_rtx (XFmode);
16568   temp = standard_80387_constant_rtx (5); /* fldl2e */
16569   emit_move_insn (operands[3], temp);
16570   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16573 (define_expand "expm1sf2"
16574   [(set (match_dup 2)
16575         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16576    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16577    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16578    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16579    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16580    (parallel [(set (match_dup 8)
16581                    (unspec:XF [(match_dup 7) (match_dup 5)]
16582                               UNSPEC_FSCALE_FRACT))
16583                    (set (match_dup 9)
16584                    (unspec:XF [(match_dup 7) (match_dup 5)]
16585                               UNSPEC_FSCALE_EXP))])
16586    (parallel [(set (match_dup 11)
16587                    (unspec:XF [(match_dup 10) (match_dup 9)]
16588                               UNSPEC_FSCALE_FRACT))
16589               (set (match_dup 12)
16590                    (unspec:XF [(match_dup 10) (match_dup 9)]
16591                               UNSPEC_FSCALE_EXP))])
16592    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16593    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16594    (set (match_operand:SF 0 "register_operand" "")
16595         (float_truncate:SF (match_dup 14)))]
16596   "TARGET_USE_FANCY_MATH_387
16597    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16598    && flag_unsafe_math_optimizations"
16600   rtx temp;
16601   int i;
16603   for (i=2; i<15; i++)
16604     operands[i] = gen_reg_rtx (XFmode);
16605   temp = standard_80387_constant_rtx (5); /* fldl2e */
16606   emit_move_insn (operands[3], temp);
16607   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16610 (define_expand "expm1xf2"
16611   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16612                                (match_dup 2)))
16613    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16614    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16615    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16616    (parallel [(set (match_dup 7)
16617                    (unspec:XF [(match_dup 6) (match_dup 4)]
16618                               UNSPEC_FSCALE_FRACT))
16619                    (set (match_dup 8)
16620                    (unspec:XF [(match_dup 6) (match_dup 4)]
16621                               UNSPEC_FSCALE_EXP))])
16622    (parallel [(set (match_dup 10)
16623                    (unspec:XF [(match_dup 9) (match_dup 8)]
16624                               UNSPEC_FSCALE_FRACT))
16625               (set (match_dup 11)
16626                    (unspec:XF [(match_dup 9) (match_dup 8)]
16627                               UNSPEC_FSCALE_EXP))])
16628    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16629    (set (match_operand:XF 0 "register_operand" "")
16630         (plus:XF (match_dup 12) (match_dup 7)))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && flag_unsafe_math_optimizations"
16634   rtx temp;
16635   int i;
16637   for (i=2; i<13; i++)
16638     operands[i] = gen_reg_rtx (XFmode);
16639   temp = standard_80387_constant_rtx (5); /* fldl2e */
16640   emit_move_insn (operands[2], temp);
16641   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16644 (define_expand "ldexpdf3"
16645   [(set (match_dup 3)
16646         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16647    (set (match_dup 4)
16648         (float:XF (match_operand:SI 2 "register_operand" "")))
16649    (parallel [(set (match_dup 5)
16650                    (unspec:XF [(match_dup 3) (match_dup 4)]
16651                               UNSPEC_FSCALE_FRACT))
16652               (set (match_dup 6)
16653                    (unspec:XF [(match_dup 3) (match_dup 4)]
16654                               UNSPEC_FSCALE_EXP))])
16655    (set (match_operand:DF 0 "register_operand" "")
16656         (float_truncate:DF (match_dup 5)))]
16657   "TARGET_USE_FANCY_MATH_387
16658    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16659    && flag_unsafe_math_optimizations"
16661   int i;
16663   for (i=3; i<7; i++)
16664     operands[i] = gen_reg_rtx (XFmode);
16667 (define_expand "ldexpsf3"
16668   [(set (match_dup 3)
16669         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16670    (set (match_dup 4)
16671         (float:XF (match_operand:SI 2 "register_operand" "")))
16672    (parallel [(set (match_dup 5)
16673                    (unspec:XF [(match_dup 3) (match_dup 4)]
16674                               UNSPEC_FSCALE_FRACT))
16675               (set (match_dup 6)
16676                    (unspec:XF [(match_dup 3) (match_dup 4)]
16677                               UNSPEC_FSCALE_EXP))])
16678    (set (match_operand:SF 0 "register_operand" "")
16679         (float_truncate:SF (match_dup 5)))]
16680   "TARGET_USE_FANCY_MATH_387
16681    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16682    && flag_unsafe_math_optimizations"
16684   int i;
16686   for (i=3; i<7; i++)
16687     operands[i] = gen_reg_rtx (XFmode);
16690 (define_expand "ldexpxf3"
16691   [(set (match_dup 3)
16692         (float:XF (match_operand:SI 2 "register_operand" "")))
16693    (parallel [(set (match_operand:XF 0 " register_operand" "")
16694                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16695                                (match_dup 3)]
16696                               UNSPEC_FSCALE_FRACT))
16697               (set (match_dup 4)
16698                    (unspec:XF [(match_dup 1) (match_dup 3)]
16699                               UNSPEC_FSCALE_EXP))])]
16700   "TARGET_USE_FANCY_MATH_387
16701    && flag_unsafe_math_optimizations"
16703   int i;
16705   for (i=3; i<5; i++)
16706     operands[i] = gen_reg_rtx (XFmode);
16710 (define_insn "frndintxf2"
16711   [(set (match_operand:XF 0 "register_operand" "=f")
16712         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16713          UNSPEC_FRNDINT))]
16714   "TARGET_USE_FANCY_MATH_387
16715    && flag_unsafe_math_optimizations"
16716   "frndint"
16717   [(set_attr "type" "fpspc")
16718    (set_attr "mode" "XF")])
16720 (define_expand "rintdf2"
16721   [(use (match_operand:DF 0 "register_operand" ""))
16722    (use (match_operand:DF 1 "register_operand" ""))]
16723   "TARGET_USE_FANCY_MATH_387
16724    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16725    && flag_unsafe_math_optimizations"
16727   rtx op0 = gen_reg_rtx (XFmode);
16728   rtx op1 = gen_reg_rtx (XFmode);
16730   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16731   emit_insn (gen_frndintxf2 (op0, op1));
16733   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16734   DONE;
16737 (define_expand "rintsf2"
16738   [(use (match_operand:SF 0 "register_operand" ""))
16739    (use (match_operand:SF 1 "register_operand" ""))]
16740   "TARGET_USE_FANCY_MATH_387
16741    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16742    && flag_unsafe_math_optimizations"
16744   rtx op0 = gen_reg_rtx (XFmode);
16745   rtx op1 = gen_reg_rtx (XFmode);
16747   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16748   emit_insn (gen_frndintxf2 (op0, op1));
16750   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16751   DONE;
16754 (define_expand "rintxf2"
16755   [(use (match_operand:XF 0 "register_operand" ""))
16756    (use (match_operand:XF 1 "register_operand" ""))]
16757   "TARGET_USE_FANCY_MATH_387
16758    && flag_unsafe_math_optimizations"
16760   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16761   DONE;
16764 (define_insn_and_split "*fistdi2_1"
16765   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16766         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16767          UNSPEC_FIST))]
16768   "TARGET_USE_FANCY_MATH_387
16769    && flag_unsafe_math_optimizations
16770    && !(reload_completed || reload_in_progress)"
16771   "#"
16772   "&& 1"
16773   [(const_int 0)]
16775   if (memory_operand (operands[0], VOIDmode))
16776     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16777   else
16778     {
16779       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16780       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16781                                          operands[2]));
16782     }
16783   DONE;
16785   [(set_attr "type" "fpspc")
16786    (set_attr "mode" "DI")])
16788 (define_insn "fistdi2"
16789   [(set (match_operand:DI 0 "memory_operand" "=m")
16790         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16791          UNSPEC_FIST))
16792    (clobber (match_scratch:XF 2 "=&1f"))]
16793   "TARGET_USE_FANCY_MATH_387
16794    && flag_unsafe_math_optimizations"
16795   "* return output_fix_trunc (insn, operands, 0);"
16796   [(set_attr "type" "fpspc")
16797    (set_attr "mode" "DI")])
16799 (define_insn "fistdi2_with_temp"
16800   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16801         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16802          UNSPEC_FIST))
16803    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16804    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16805   "TARGET_USE_FANCY_MATH_387
16806    && flag_unsafe_math_optimizations"
16807   "#"
16808   [(set_attr "type" "fpspc")
16809    (set_attr "mode" "DI")])
16811 (define_split 
16812   [(set (match_operand:DI 0 "register_operand" "")
16813         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16814          UNSPEC_FIST))
16815    (clobber (match_operand:DI 2 "memory_operand" ""))
16816    (clobber (match_scratch 3 ""))]
16817   "reload_completed"
16818   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16819               (clobber (match_dup 3))])
16820    (set (match_dup 0) (match_dup 2))]
16821   "")
16823 (define_split 
16824   [(set (match_operand:DI 0 "memory_operand" "")
16825         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16826          UNSPEC_FIST))
16827    (clobber (match_operand:DI 2 "memory_operand" ""))
16828    (clobber (match_scratch 3 ""))]
16829   "reload_completed"
16830   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16831               (clobber (match_dup 3))])]
16832   "")
16834 (define_insn_and_split "*fist<mode>2_1"
16835   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16836         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16837          UNSPEC_FIST))]
16838   "TARGET_USE_FANCY_MATH_387
16839    && flag_unsafe_math_optimizations
16840    && !(reload_completed || reload_in_progress)"
16841   "#"
16842   "&& 1"
16843   [(const_int 0)]
16845   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16846   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16847                                         operands[2]));
16848   DONE;
16850   [(set_attr "type" "fpspc")
16851    (set_attr "mode" "<MODE>")])
16853 (define_insn "fist<mode>2"
16854   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16855         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16856          UNSPEC_FIST))]
16857   "TARGET_USE_FANCY_MATH_387
16858    && flag_unsafe_math_optimizations"
16859   "* return output_fix_trunc (insn, operands, 0);"
16860   [(set_attr "type" "fpspc")
16861    (set_attr "mode" "<MODE>")])
16863 (define_insn "fist<mode>2_with_temp"
16864   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16865         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16866          UNSPEC_FIST))
16867    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16868   "TARGET_USE_FANCY_MATH_387
16869    && flag_unsafe_math_optimizations"
16870   "#"
16871   [(set_attr "type" "fpspc")
16872    (set_attr "mode" "<MODE>")])
16874 (define_split 
16875   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16876         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16877          UNSPEC_FIST))
16878    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16879   "reload_completed"
16880   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16881                        UNSPEC_FIST))
16882    (set (match_dup 0) (match_dup 2))]
16883   "")
16885 (define_split 
16886   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16887         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16888          UNSPEC_FIST))
16889    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16890   "reload_completed"
16891   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16892                        UNSPEC_FIST))]
16893   "")
16895 (define_expand "lrint<mode>2"
16896   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16897         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16898          UNSPEC_FIST))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16901    && flag_unsafe_math_optimizations"
16902   "")
16904 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16905 (define_insn_and_split "frndintxf2_floor"
16906   [(set (match_operand:XF 0 "register_operand" "=f")
16907         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16908          UNSPEC_FRNDINT_FLOOR))
16909    (clobber (reg:CC FLAGS_REG))]
16910   "TARGET_USE_FANCY_MATH_387
16911    && flag_unsafe_math_optimizations
16912    && !(reload_completed || reload_in_progress)"
16913   "#"
16914   "&& 1"
16915   [(const_int 0)]
16917   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16919   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16920   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16922   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16923                                         operands[2], operands[3]));
16924   DONE;
16926   [(set_attr "type" "frndint")
16927    (set_attr "i387_cw" "floor")
16928    (set_attr "mode" "XF")])
16930 (define_insn "frndintxf2_floor_i387"
16931   [(set (match_operand:XF 0 "register_operand" "=f")
16932         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16933          UNSPEC_FRNDINT_FLOOR))
16934    (use (match_operand:HI 2 "memory_operand" "m"))
16935    (use (match_operand:HI 3 "memory_operand" "m"))]
16936   "TARGET_USE_FANCY_MATH_387
16937    && flag_unsafe_math_optimizations"
16938   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16939   [(set_attr "type" "frndint")
16940    (set_attr "i387_cw" "floor")
16941    (set_attr "mode" "XF")])
16943 (define_expand "floorxf2"
16944   [(use (match_operand:XF 0 "register_operand" ""))
16945    (use (match_operand:XF 1 "register_operand" ""))]
16946   "TARGET_USE_FANCY_MATH_387
16947    && flag_unsafe_math_optimizations"
16949   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16950   DONE;
16953 (define_expand "floordf2"
16954   [(use (match_operand:DF 0 "register_operand" ""))
16955    (use (match_operand:DF 1 "register_operand" ""))]
16956   "TARGET_USE_FANCY_MATH_387
16957    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16958    && flag_unsafe_math_optimizations"
16960   rtx op0 = gen_reg_rtx (XFmode);
16961   rtx op1 = gen_reg_rtx (XFmode);
16963   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16964   emit_insn (gen_frndintxf2_floor (op0, op1));
16966   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16967   DONE;
16970 (define_expand "floorsf2"
16971   [(use (match_operand:SF 0 "register_operand" ""))
16972    (use (match_operand:SF 1 "register_operand" ""))]
16973   "TARGET_USE_FANCY_MATH_387
16974    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16975    && flag_unsafe_math_optimizations"
16977   rtx op0 = gen_reg_rtx (XFmode);
16978   rtx op1 = gen_reg_rtx (XFmode);
16980   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16981   emit_insn (gen_frndintxf2_floor (op0, op1));
16983   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16984   DONE;
16987 (define_insn_and_split "*fist<mode>2_floor_1"
16988   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16989         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16990          UNSPEC_FIST_FLOOR))
16991    (clobber (reg:CC FLAGS_REG))]
16992   "TARGET_USE_FANCY_MATH_387
16993    && flag_unsafe_math_optimizations
16994    && !(reload_completed || reload_in_progress)"
16995   "#"
16996   "&& 1"
16997   [(const_int 0)]
16999   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17001   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17002   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17003   if (memory_operand (operands[0], VOIDmode))
17004     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17005                                       operands[2], operands[3]));
17006   else
17007     {
17008       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17009       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17010                                                   operands[2], operands[3],
17011                                                   operands[4]));
17012     }
17013   DONE;
17015   [(set_attr "type" "fistp")
17016    (set_attr "i387_cw" "floor")
17017    (set_attr "mode" "<MODE>")])
17019 (define_insn "fistdi2_floor"
17020   [(set (match_operand:DI 0 "memory_operand" "=m")
17021         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17022          UNSPEC_FIST_FLOOR))
17023    (use (match_operand:HI 2 "memory_operand" "m"))
17024    (use (match_operand:HI 3 "memory_operand" "m"))
17025    (clobber (match_scratch:XF 4 "=&1f"))]
17026   "TARGET_USE_FANCY_MATH_387
17027    && flag_unsafe_math_optimizations"
17028   "* return output_fix_trunc (insn, operands, 0);"
17029   [(set_attr "type" "fistp")
17030    (set_attr "i387_cw" "floor")
17031    (set_attr "mode" "DI")])
17033 (define_insn "fistdi2_floor_with_temp"
17034   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17035         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17036          UNSPEC_FIST_FLOOR))
17037    (use (match_operand:HI 2 "memory_operand" "m,m"))
17038    (use (match_operand:HI 3 "memory_operand" "m,m"))
17039    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17040    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17041   "TARGET_USE_FANCY_MATH_387
17042    && flag_unsafe_math_optimizations"
17043   "#"
17044   [(set_attr "type" "fistp")
17045    (set_attr "i387_cw" "floor")
17046    (set_attr "mode" "DI")])
17048 (define_split 
17049   [(set (match_operand:DI 0 "register_operand" "")
17050         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17051          UNSPEC_FIST_FLOOR))
17052    (use (match_operand:HI 2 "memory_operand" ""))
17053    (use (match_operand:HI 3 "memory_operand" ""))
17054    (clobber (match_operand:DI 4 "memory_operand" ""))
17055    (clobber (match_scratch 5 ""))]
17056   "reload_completed"
17057   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17058               (use (match_dup 2))
17059               (use (match_dup 3))
17060               (clobber (match_dup 5))])
17061    (set (match_dup 0) (match_dup 4))]
17062   "")
17064 (define_split 
17065   [(set (match_operand:DI 0 "memory_operand" "")
17066         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17067          UNSPEC_FIST_FLOOR))
17068    (use (match_operand:HI 2 "memory_operand" ""))
17069    (use (match_operand:HI 3 "memory_operand" ""))
17070    (clobber (match_operand:DI 4 "memory_operand" ""))
17071    (clobber (match_scratch 5 ""))]
17072   "reload_completed"
17073   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17074               (use (match_dup 2))
17075               (use (match_dup 3))
17076               (clobber (match_dup 5))])]
17077   "")
17079 (define_insn "fist<mode>2_floor"
17080   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17081         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17082          UNSPEC_FIST_FLOOR))
17083    (use (match_operand:HI 2 "memory_operand" "m"))
17084    (use (match_operand:HI 3 "memory_operand" "m"))]
17085   "TARGET_USE_FANCY_MATH_387
17086    && flag_unsafe_math_optimizations"
17087   "* return output_fix_trunc (insn, operands, 0);"
17088   [(set_attr "type" "fistp")
17089    (set_attr "i387_cw" "floor")
17090    (set_attr "mode" "<MODE>")])
17092 (define_insn "fist<mode>2_floor_with_temp"
17093   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17094         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17095          UNSPEC_FIST_FLOOR))
17096    (use (match_operand:HI 2 "memory_operand" "m,m"))
17097    (use (match_operand:HI 3 "memory_operand" "m,m"))
17098    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17099   "TARGET_USE_FANCY_MATH_387
17100    && flag_unsafe_math_optimizations"
17101   "#"
17102   [(set_attr "type" "fistp")
17103    (set_attr "i387_cw" "floor")
17104    (set_attr "mode" "<MODE>")])
17106 (define_split 
17107   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17108         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17109          UNSPEC_FIST_FLOOR))
17110    (use (match_operand:HI 2 "memory_operand" ""))
17111    (use (match_operand:HI 3 "memory_operand" ""))
17112    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17113   "reload_completed"
17114   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17115                                   UNSPEC_FIST_FLOOR))
17116               (use (match_dup 2))
17117               (use (match_dup 3))])
17118    (set (match_dup 0) (match_dup 4))]
17119   "")
17121 (define_split 
17122   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17123         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17124          UNSPEC_FIST_FLOOR))
17125    (use (match_operand:HI 2 "memory_operand" ""))
17126    (use (match_operand:HI 3 "memory_operand" ""))
17127    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17128   "reload_completed"
17129   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17130                                   UNSPEC_FIST_FLOOR))
17131               (use (match_dup 2))
17132               (use (match_dup 3))])]
17133   "")
17135 (define_expand "lfloor<mode>2"
17136   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17137                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17138                     UNSPEC_FIST_FLOOR))
17139               (clobber (reg:CC FLAGS_REG))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17142    && flag_unsafe_math_optimizations"
17143   "")
17145 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17146 (define_insn_and_split "frndintxf2_ceil"
17147   [(set (match_operand:XF 0 "register_operand" "=f")
17148         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17149          UNSPEC_FRNDINT_CEIL))
17150    (clobber (reg:CC FLAGS_REG))]
17151   "TARGET_USE_FANCY_MATH_387
17152    && flag_unsafe_math_optimizations
17153    && !(reload_completed || reload_in_progress)"
17154   "#"
17155   "&& 1"
17156   [(const_int 0)]
17158   ix86_optimize_mode_switching[I387_CEIL] = 1;
17160   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17161   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17163   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17164                                        operands[2], operands[3]));
17165   DONE;
17167   [(set_attr "type" "frndint")
17168    (set_attr "i387_cw" "ceil")
17169    (set_attr "mode" "XF")])
17171 (define_insn "frndintxf2_ceil_i387"
17172   [(set (match_operand:XF 0 "register_operand" "=f")
17173         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17174          UNSPEC_FRNDINT_CEIL))
17175    (use (match_operand:HI 2 "memory_operand" "m"))
17176    (use (match_operand:HI 3 "memory_operand" "m"))]
17177   "TARGET_USE_FANCY_MATH_387
17178    && flag_unsafe_math_optimizations"
17179   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17180   [(set_attr "type" "frndint")
17181    (set_attr "i387_cw" "ceil")
17182    (set_attr "mode" "XF")])
17184 (define_expand "ceilxf2"
17185   [(use (match_operand:XF 0 "register_operand" ""))
17186    (use (match_operand:XF 1 "register_operand" ""))]
17187   "TARGET_USE_FANCY_MATH_387
17188    && flag_unsafe_math_optimizations"
17190   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17191   DONE;
17194 (define_expand "ceildf2"
17195   [(use (match_operand:DF 0 "register_operand" ""))
17196    (use (match_operand:DF 1 "register_operand" ""))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17199    && flag_unsafe_math_optimizations"
17201   rtx op0 = gen_reg_rtx (XFmode);
17202   rtx op1 = gen_reg_rtx (XFmode);
17204   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17205   emit_insn (gen_frndintxf2_ceil (op0, op1));
17207   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17208   DONE;
17211 (define_expand "ceilsf2"
17212   [(use (match_operand:SF 0 "register_operand" ""))
17213    (use (match_operand:SF 1 "register_operand" ""))]
17214   "TARGET_USE_FANCY_MATH_387
17215    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17216    && flag_unsafe_math_optimizations"
17218   rtx op0 = gen_reg_rtx (XFmode);
17219   rtx op1 = gen_reg_rtx (XFmode);
17221   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17222   emit_insn (gen_frndintxf2_ceil (op0, op1));
17224   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17225   DONE;
17228 (define_insn_and_split "*fist<mode>2_ceil_1"
17229   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17230         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17231          UNSPEC_FIST_CEIL))
17232    (clobber (reg:CC FLAGS_REG))]
17233   "TARGET_USE_FANCY_MATH_387
17234    && flag_unsafe_math_optimizations
17235    && !(reload_completed || reload_in_progress)"
17236   "#"
17237   "&& 1"
17238   [(const_int 0)]
17240   ix86_optimize_mode_switching[I387_CEIL] = 1;
17242   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17243   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17244   if (memory_operand (operands[0], VOIDmode))
17245     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17246                                      operands[2], operands[3]));
17247   else
17248     {
17249       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17250       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17251                                                  operands[2], operands[3],
17252                                                  operands[4]));
17253     }
17254   DONE;
17256   [(set_attr "type" "fistp")
17257    (set_attr "i387_cw" "ceil")
17258    (set_attr "mode" "<MODE>")])
17260 (define_insn "fistdi2_ceil"
17261   [(set (match_operand:DI 0 "memory_operand" "=m")
17262         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17263          UNSPEC_FIST_CEIL))
17264    (use (match_operand:HI 2 "memory_operand" "m"))
17265    (use (match_operand:HI 3 "memory_operand" "m"))
17266    (clobber (match_scratch:XF 4 "=&1f"))]
17267   "TARGET_USE_FANCY_MATH_387
17268    && flag_unsafe_math_optimizations"
17269   "* return output_fix_trunc (insn, operands, 0);"
17270   [(set_attr "type" "fistp")
17271    (set_attr "i387_cw" "ceil")
17272    (set_attr "mode" "DI")])
17274 (define_insn "fistdi2_ceil_with_temp"
17275   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17276         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17277          UNSPEC_FIST_CEIL))
17278    (use (match_operand:HI 2 "memory_operand" "m,m"))
17279    (use (match_operand:HI 3 "memory_operand" "m,m"))
17280    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17281    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17282   "TARGET_USE_FANCY_MATH_387
17283    && flag_unsafe_math_optimizations"
17284   "#"
17285   [(set_attr "type" "fistp")
17286    (set_attr "i387_cw" "ceil")
17287    (set_attr "mode" "DI")])
17289 (define_split 
17290   [(set (match_operand:DI 0 "register_operand" "")
17291         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17292          UNSPEC_FIST_CEIL))
17293    (use (match_operand:HI 2 "memory_operand" ""))
17294    (use (match_operand:HI 3 "memory_operand" ""))
17295    (clobber (match_operand:DI 4 "memory_operand" ""))
17296    (clobber (match_scratch 5 ""))]
17297   "reload_completed"
17298   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17299               (use (match_dup 2))
17300               (use (match_dup 3))
17301               (clobber (match_dup 5))])
17302    (set (match_dup 0) (match_dup 4))]
17303   "")
17305 (define_split 
17306   [(set (match_operand:DI 0 "memory_operand" "")
17307         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17308          UNSPEC_FIST_CEIL))
17309    (use (match_operand:HI 2 "memory_operand" ""))
17310    (use (match_operand:HI 3 "memory_operand" ""))
17311    (clobber (match_operand:DI 4 "memory_operand" ""))
17312    (clobber (match_scratch 5 ""))]
17313   "reload_completed"
17314   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17315               (use (match_dup 2))
17316               (use (match_dup 3))
17317               (clobber (match_dup 5))])]
17318   "")
17320 (define_insn "fist<mode>2_ceil"
17321   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17322         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17323          UNSPEC_FIST_CEIL))
17324    (use (match_operand:HI 2 "memory_operand" "m"))
17325    (use (match_operand:HI 3 "memory_operand" "m"))]
17326   "TARGET_USE_FANCY_MATH_387
17327    && flag_unsafe_math_optimizations"
17328   "* return output_fix_trunc (insn, operands, 0);"
17329   [(set_attr "type" "fistp")
17330    (set_attr "i387_cw" "ceil")
17331    (set_attr "mode" "<MODE>")])
17333 (define_insn "fist<mode>2_ceil_with_temp"
17334   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17335         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17336          UNSPEC_FIST_CEIL))
17337    (use (match_operand:HI 2 "memory_operand" "m,m"))
17338    (use (match_operand:HI 3 "memory_operand" "m,m"))
17339    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17340   "TARGET_USE_FANCY_MATH_387
17341    && flag_unsafe_math_optimizations"
17342   "#"
17343   [(set_attr "type" "fistp")
17344    (set_attr "i387_cw" "ceil")
17345    (set_attr "mode" "<MODE>")])
17347 (define_split 
17348   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17349         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17350          UNSPEC_FIST_CEIL))
17351    (use (match_operand:HI 2 "memory_operand" ""))
17352    (use (match_operand:HI 3 "memory_operand" ""))
17353    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17354   "reload_completed"
17355   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17356                                   UNSPEC_FIST_CEIL))
17357               (use (match_dup 2))
17358               (use (match_dup 3))])
17359    (set (match_dup 0) (match_dup 4))]
17360   "")
17362 (define_split 
17363   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17364         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17365          UNSPEC_FIST_CEIL))
17366    (use (match_operand:HI 2 "memory_operand" ""))
17367    (use (match_operand:HI 3 "memory_operand" ""))
17368    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17369   "reload_completed"
17370   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17371                                   UNSPEC_FIST_CEIL))
17372               (use (match_dup 2))
17373               (use (match_dup 3))])]
17374   "")
17376 (define_expand "lceil<mode>2"
17377   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17378                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17379                     UNSPEC_FIST_CEIL))
17380               (clobber (reg:CC FLAGS_REG))])]
17381   "TARGET_USE_FANCY_MATH_387
17382    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17383    && flag_unsafe_math_optimizations"
17384   "")
17386 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17387 (define_insn_and_split "frndintxf2_trunc"
17388   [(set (match_operand:XF 0 "register_operand" "=f")
17389         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17390          UNSPEC_FRNDINT_TRUNC))
17391    (clobber (reg:CC FLAGS_REG))]
17392   "TARGET_USE_FANCY_MATH_387
17393    && flag_unsafe_math_optimizations
17394    && !(reload_completed || reload_in_progress)"
17395   "#"
17396   "&& 1"
17397   [(const_int 0)]
17399   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17401   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17402   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17404   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17405                                         operands[2], operands[3]));
17406   DONE;
17408   [(set_attr "type" "frndint")
17409    (set_attr "i387_cw" "trunc")
17410    (set_attr "mode" "XF")])
17412 (define_insn "frndintxf2_trunc_i387"
17413   [(set (match_operand:XF 0 "register_operand" "=f")
17414         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17415          UNSPEC_FRNDINT_TRUNC))
17416    (use (match_operand:HI 2 "memory_operand" "m"))
17417    (use (match_operand:HI 3 "memory_operand" "m"))]
17418   "TARGET_USE_FANCY_MATH_387
17419    && flag_unsafe_math_optimizations"
17420   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17421   [(set_attr "type" "frndint")
17422    (set_attr "i387_cw" "trunc")
17423    (set_attr "mode" "XF")])
17425 (define_expand "btruncxf2"
17426   [(use (match_operand:XF 0 "register_operand" ""))
17427    (use (match_operand:XF 1 "register_operand" ""))]
17428   "TARGET_USE_FANCY_MATH_387
17429    && flag_unsafe_math_optimizations"
17431   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17432   DONE;
17435 (define_expand "btruncdf2"
17436   [(use (match_operand:DF 0 "register_operand" ""))
17437    (use (match_operand:DF 1 "register_operand" ""))]
17438   "TARGET_USE_FANCY_MATH_387
17439    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17440    && flag_unsafe_math_optimizations"
17442   rtx op0 = gen_reg_rtx (XFmode);
17443   rtx op1 = gen_reg_rtx (XFmode);
17445   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17446   emit_insn (gen_frndintxf2_trunc (op0, op1));
17448   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17449   DONE;
17452 (define_expand "btruncsf2"
17453   [(use (match_operand:SF 0 "register_operand" ""))
17454    (use (match_operand:SF 1 "register_operand" ""))]
17455   "TARGET_USE_FANCY_MATH_387
17456    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17457    && flag_unsafe_math_optimizations"
17459   rtx op0 = gen_reg_rtx (XFmode);
17460   rtx op1 = gen_reg_rtx (XFmode);
17462   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17463   emit_insn (gen_frndintxf2_trunc (op0, op1));
17465   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17466   DONE;
17469 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17470 (define_insn_and_split "frndintxf2_mask_pm"
17471   [(set (match_operand:XF 0 "register_operand" "=f")
17472         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17473          UNSPEC_FRNDINT_MASK_PM))
17474    (clobber (reg:CC FLAGS_REG))]
17475   "TARGET_USE_FANCY_MATH_387
17476    && flag_unsafe_math_optimizations
17477    && !(reload_completed || reload_in_progress)"
17478   "#"
17479   "&& 1"
17480   [(const_int 0)]
17482   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17484   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17485   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17487   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17488                                           operands[2], operands[3]));
17489   DONE;
17491   [(set_attr "type" "frndint")
17492    (set_attr "i387_cw" "mask_pm")
17493    (set_attr "mode" "XF")])
17495 (define_insn "frndintxf2_mask_pm_i387"
17496   [(set (match_operand:XF 0 "register_operand" "=f")
17497         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17498          UNSPEC_FRNDINT_MASK_PM))
17499    (use (match_operand:HI 2 "memory_operand" "m"))
17500    (use (match_operand:HI 3 "memory_operand" "m"))]
17501   "TARGET_USE_FANCY_MATH_387
17502    && flag_unsafe_math_optimizations"
17503   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17504   [(set_attr "type" "frndint")
17505    (set_attr "i387_cw" "mask_pm")
17506    (set_attr "mode" "XF")])
17508 (define_expand "nearbyintxf2"
17509   [(use (match_operand:XF 0 "register_operand" ""))
17510    (use (match_operand:XF 1 "register_operand" ""))]
17511   "TARGET_USE_FANCY_MATH_387
17512    && flag_unsafe_math_optimizations"
17514   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17516   DONE;
17519 (define_expand "nearbyintdf2"
17520   [(use (match_operand:DF 0 "register_operand" ""))
17521    (use (match_operand:DF 1 "register_operand" ""))]
17522   "TARGET_USE_FANCY_MATH_387
17523    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17524    && flag_unsafe_math_optimizations"
17526   rtx op0 = gen_reg_rtx (XFmode);
17527   rtx op1 = gen_reg_rtx (XFmode);
17529   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17530   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17532   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17533   DONE;
17536 (define_expand "nearbyintsf2"
17537   [(use (match_operand:SF 0 "register_operand" ""))
17538    (use (match_operand:SF 1 "register_operand" ""))]
17539   "TARGET_USE_FANCY_MATH_387
17540    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17541    && flag_unsafe_math_optimizations"
17543   rtx op0 = gen_reg_rtx (XFmode);
17544   rtx op1 = gen_reg_rtx (XFmode);
17546   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17547   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17549   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17550   DONE;
17554 ;; Block operation instructions
17556 (define_insn "cld"
17557  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17558  ""
17559  "cld"
17560   [(set_attr "type" "cld")])
17562 (define_expand "movmemsi"
17563   [(use (match_operand:BLK 0 "memory_operand" ""))
17564    (use (match_operand:BLK 1 "memory_operand" ""))
17565    (use (match_operand:SI 2 "nonmemory_operand" ""))
17566    (use (match_operand:SI 3 "const_int_operand" ""))]
17567   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17569  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17570    DONE;
17571  else
17572    FAIL;
17575 (define_expand "movmemdi"
17576   [(use (match_operand:BLK 0 "memory_operand" ""))
17577    (use (match_operand:BLK 1 "memory_operand" ""))
17578    (use (match_operand:DI 2 "nonmemory_operand" ""))
17579    (use (match_operand:DI 3 "const_int_operand" ""))]
17580   "TARGET_64BIT"
17582  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17583    DONE;
17584  else
17585    FAIL;
17588 ;; Most CPUs don't like single string operations
17589 ;; Handle this case here to simplify previous expander.
17591 (define_expand "strmov"
17592   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17593    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17594    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17595               (clobber (reg:CC FLAGS_REG))])
17596    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17597               (clobber (reg:CC FLAGS_REG))])]
17598   ""
17600   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17602   /* If .md ever supports :P for Pmode, these can be directly
17603      in the pattern above.  */
17604   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17605   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17607   if (TARGET_SINGLE_STRINGOP || optimize_size)
17608     {
17609       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17610                                       operands[2], operands[3],
17611                                       operands[5], operands[6]));
17612       DONE;
17613     }
17615   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17618 (define_expand "strmov_singleop"
17619   [(parallel [(set (match_operand 1 "memory_operand" "")
17620                    (match_operand 3 "memory_operand" ""))
17621               (set (match_operand 0 "register_operand" "")
17622                    (match_operand 4 "" ""))
17623               (set (match_operand 2 "register_operand" "")
17624                    (match_operand 5 "" ""))
17625               (use (reg:SI DIRFLAG_REG))])]
17626   "TARGET_SINGLE_STRINGOP || optimize_size"
17627   "")
17629 (define_insn "*strmovdi_rex_1"
17630   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17631         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17632    (set (match_operand:DI 0 "register_operand" "=D")
17633         (plus:DI (match_dup 2)
17634                  (const_int 8)))
17635    (set (match_operand:DI 1 "register_operand" "=S")
17636         (plus:DI (match_dup 3)
17637                  (const_int 8)))
17638    (use (reg:SI DIRFLAG_REG))]
17639   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17640   "movsq"
17641   [(set_attr "type" "str")
17642    (set_attr "mode" "DI")
17643    (set_attr "memory" "both")])
17645 (define_insn "*strmovsi_1"
17646   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17647         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17648    (set (match_operand:SI 0 "register_operand" "=D")
17649         (plus:SI (match_dup 2)
17650                  (const_int 4)))
17651    (set (match_operand:SI 1 "register_operand" "=S")
17652         (plus:SI (match_dup 3)
17653                  (const_int 4)))
17654    (use (reg:SI DIRFLAG_REG))]
17655   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17656   "{movsl|movsd}"
17657   [(set_attr "type" "str")
17658    (set_attr "mode" "SI")
17659    (set_attr "memory" "both")])
17661 (define_insn "*strmovsi_rex_1"
17662   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17663         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17664    (set (match_operand:DI 0 "register_operand" "=D")
17665         (plus:DI (match_dup 2)
17666                  (const_int 4)))
17667    (set (match_operand:DI 1 "register_operand" "=S")
17668         (plus:DI (match_dup 3)
17669                  (const_int 4)))
17670    (use (reg:SI DIRFLAG_REG))]
17671   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17672   "{movsl|movsd}"
17673   [(set_attr "type" "str")
17674    (set_attr "mode" "SI")
17675    (set_attr "memory" "both")])
17677 (define_insn "*strmovhi_1"
17678   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17679         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17680    (set (match_operand:SI 0 "register_operand" "=D")
17681         (plus:SI (match_dup 2)
17682                  (const_int 2)))
17683    (set (match_operand:SI 1 "register_operand" "=S")
17684         (plus:SI (match_dup 3)
17685                  (const_int 2)))
17686    (use (reg:SI DIRFLAG_REG))]
17687   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17688   "movsw"
17689   [(set_attr "type" "str")
17690    (set_attr "memory" "both")
17691    (set_attr "mode" "HI")])
17693 (define_insn "*strmovhi_rex_1"
17694   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17695         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17696    (set (match_operand:DI 0 "register_operand" "=D")
17697         (plus:DI (match_dup 2)
17698                  (const_int 2)))
17699    (set (match_operand:DI 1 "register_operand" "=S")
17700         (plus:DI (match_dup 3)
17701                  (const_int 2)))
17702    (use (reg:SI DIRFLAG_REG))]
17703   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17704   "movsw"
17705   [(set_attr "type" "str")
17706    (set_attr "memory" "both")
17707    (set_attr "mode" "HI")])
17709 (define_insn "*strmovqi_1"
17710   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17711         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17712    (set (match_operand:SI 0 "register_operand" "=D")
17713         (plus:SI (match_dup 2)
17714                  (const_int 1)))
17715    (set (match_operand:SI 1 "register_operand" "=S")
17716         (plus:SI (match_dup 3)
17717                  (const_int 1)))
17718    (use (reg:SI DIRFLAG_REG))]
17719   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17720   "movsb"
17721   [(set_attr "type" "str")
17722    (set_attr "memory" "both")
17723    (set_attr "mode" "QI")])
17725 (define_insn "*strmovqi_rex_1"
17726   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17727         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17728    (set (match_operand:DI 0 "register_operand" "=D")
17729         (plus:DI (match_dup 2)
17730                  (const_int 1)))
17731    (set (match_operand:DI 1 "register_operand" "=S")
17732         (plus:DI (match_dup 3)
17733                  (const_int 1)))
17734    (use (reg:SI DIRFLAG_REG))]
17735   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17736   "movsb"
17737   [(set_attr "type" "str")
17738    (set_attr "memory" "both")
17739    (set_attr "mode" "QI")])
17741 (define_expand "rep_mov"
17742   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17743               (set (match_operand 0 "register_operand" "")
17744                    (match_operand 5 "" ""))
17745               (set (match_operand 2 "register_operand" "")
17746                    (match_operand 6 "" ""))
17747               (set (match_operand 1 "memory_operand" "")
17748                    (match_operand 3 "memory_operand" ""))
17749               (use (match_dup 4))
17750               (use (reg:SI DIRFLAG_REG))])]
17751   ""
17752   "")
17754 (define_insn "*rep_movdi_rex64"
17755   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17756    (set (match_operand:DI 0 "register_operand" "=D") 
17757         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17758                             (const_int 3))
17759                  (match_operand:DI 3 "register_operand" "0")))
17760    (set (match_operand:DI 1 "register_operand" "=S") 
17761         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17762                  (match_operand:DI 4 "register_operand" "1")))
17763    (set (mem:BLK (match_dup 3))
17764         (mem:BLK (match_dup 4)))
17765    (use (match_dup 5))
17766    (use (reg:SI DIRFLAG_REG))]
17767   "TARGET_64BIT"
17768   "{rep\;movsq|rep movsq}"
17769   [(set_attr "type" "str")
17770    (set_attr "prefix_rep" "1")
17771    (set_attr "memory" "both")
17772    (set_attr "mode" "DI")])
17774 (define_insn "*rep_movsi"
17775   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17776    (set (match_operand:SI 0 "register_operand" "=D") 
17777         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17778                             (const_int 2))
17779                  (match_operand:SI 3 "register_operand" "0")))
17780    (set (match_operand:SI 1 "register_operand" "=S") 
17781         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17782                  (match_operand:SI 4 "register_operand" "1")))
17783    (set (mem:BLK (match_dup 3))
17784         (mem:BLK (match_dup 4)))
17785    (use (match_dup 5))
17786    (use (reg:SI DIRFLAG_REG))]
17787   "!TARGET_64BIT"
17788   "{rep\;movsl|rep movsd}"
17789   [(set_attr "type" "str")
17790    (set_attr "prefix_rep" "1")
17791    (set_attr "memory" "both")
17792    (set_attr "mode" "SI")])
17794 (define_insn "*rep_movsi_rex64"
17795   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17796    (set (match_operand:DI 0 "register_operand" "=D") 
17797         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17798                             (const_int 2))
17799                  (match_operand:DI 3 "register_operand" "0")))
17800    (set (match_operand:DI 1 "register_operand" "=S") 
17801         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17802                  (match_operand:DI 4 "register_operand" "1")))
17803    (set (mem:BLK (match_dup 3))
17804         (mem:BLK (match_dup 4)))
17805    (use (match_dup 5))
17806    (use (reg:SI DIRFLAG_REG))]
17807   "TARGET_64BIT"
17808   "{rep\;movsl|rep movsd}"
17809   [(set_attr "type" "str")
17810    (set_attr "prefix_rep" "1")
17811    (set_attr "memory" "both")
17812    (set_attr "mode" "SI")])
17814 (define_insn "*rep_movqi"
17815   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17816    (set (match_operand:SI 0 "register_operand" "=D") 
17817         (plus:SI (match_operand:SI 3 "register_operand" "0")
17818                  (match_operand:SI 5 "register_operand" "2")))
17819    (set (match_operand:SI 1 "register_operand" "=S") 
17820         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17821    (set (mem:BLK (match_dup 3))
17822         (mem:BLK (match_dup 4)))
17823    (use (match_dup 5))
17824    (use (reg:SI DIRFLAG_REG))]
17825   "!TARGET_64BIT"
17826   "{rep\;movsb|rep movsb}"
17827   [(set_attr "type" "str")
17828    (set_attr "prefix_rep" "1")
17829    (set_attr "memory" "both")
17830    (set_attr "mode" "SI")])
17832 (define_insn "*rep_movqi_rex64"
17833   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17834    (set (match_operand:DI 0 "register_operand" "=D") 
17835         (plus:DI (match_operand:DI 3 "register_operand" "0")
17836                  (match_operand:DI 5 "register_operand" "2")))
17837    (set (match_operand:DI 1 "register_operand" "=S") 
17838         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17839    (set (mem:BLK (match_dup 3))
17840         (mem:BLK (match_dup 4)))
17841    (use (match_dup 5))
17842    (use (reg:SI DIRFLAG_REG))]
17843   "TARGET_64BIT"
17844   "{rep\;movsb|rep movsb}"
17845   [(set_attr "type" "str")
17846    (set_attr "prefix_rep" "1")
17847    (set_attr "memory" "both")
17848    (set_attr "mode" "SI")])
17850 (define_expand "setmemsi"
17851    [(use (match_operand:BLK 0 "memory_operand" ""))
17852     (use (match_operand:SI 1 "nonmemory_operand" ""))
17853     (use (match_operand 2 "const_int_operand" ""))
17854     (use (match_operand 3 "const_int_operand" ""))]
17855   ""
17857  /* If value to set is not zero, use the library routine.  */
17858  if (operands[2] != const0_rtx)
17859    FAIL;
17861  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17862    DONE;
17863  else
17864    FAIL;
17867 (define_expand "setmemdi"
17868    [(use (match_operand:BLK 0 "memory_operand" ""))
17869     (use (match_operand:DI 1 "nonmemory_operand" ""))
17870     (use (match_operand 2 "const_int_operand" ""))
17871     (use (match_operand 3 "const_int_operand" ""))]
17872   "TARGET_64BIT"
17874  /* If value to set is not zero, use the library routine.  */
17875  if (operands[2] != const0_rtx)
17876    FAIL;
17878  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17879    DONE;
17880  else
17881    FAIL;
17884 ;; Most CPUs don't like single string operations
17885 ;; Handle this case here to simplify previous expander.
17887 (define_expand "strset"
17888   [(set (match_operand 1 "memory_operand" "")
17889         (match_operand 2 "register_operand" ""))
17890    (parallel [(set (match_operand 0 "register_operand" "")
17891                    (match_dup 3))
17892               (clobber (reg:CC FLAGS_REG))])]
17893   ""
17895   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17896     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17898   /* If .md ever supports :P for Pmode, this can be directly
17899      in the pattern above.  */
17900   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17901                               GEN_INT (GET_MODE_SIZE (GET_MODE
17902                                                       (operands[2]))));
17903   if (TARGET_SINGLE_STRINGOP || optimize_size)
17904     {
17905       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17906                                       operands[3]));
17907       DONE;
17908     }
17911 (define_expand "strset_singleop"
17912   [(parallel [(set (match_operand 1 "memory_operand" "")
17913                    (match_operand 2 "register_operand" ""))
17914               (set (match_operand 0 "register_operand" "")
17915                    (match_operand 3 "" ""))
17916               (use (reg:SI DIRFLAG_REG))])]
17917   "TARGET_SINGLE_STRINGOP || optimize_size"
17918   "")
17920 (define_insn "*strsetdi_rex_1"
17921   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17922         (match_operand:DI 2 "register_operand" "a"))
17923    (set (match_operand:DI 0 "register_operand" "=D")
17924         (plus:DI (match_dup 1)
17925                  (const_int 8)))
17926    (use (reg:SI DIRFLAG_REG))]
17927   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17928   "stosq"
17929   [(set_attr "type" "str")
17930    (set_attr "memory" "store")
17931    (set_attr "mode" "DI")])
17933 (define_insn "*strsetsi_1"
17934   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17935         (match_operand:SI 2 "register_operand" "a"))
17936    (set (match_operand:SI 0 "register_operand" "=D")
17937         (plus:SI (match_dup 1)
17938                  (const_int 4)))
17939    (use (reg:SI DIRFLAG_REG))]
17940   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17941   "{stosl|stosd}"
17942   [(set_attr "type" "str")
17943    (set_attr "memory" "store")
17944    (set_attr "mode" "SI")])
17946 (define_insn "*strsetsi_rex_1"
17947   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17948         (match_operand:SI 2 "register_operand" "a"))
17949    (set (match_operand:DI 0 "register_operand" "=D")
17950         (plus:DI (match_dup 1)
17951                  (const_int 4)))
17952    (use (reg:SI DIRFLAG_REG))]
17953   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17954   "{stosl|stosd}"
17955   [(set_attr "type" "str")
17956    (set_attr "memory" "store")
17957    (set_attr "mode" "SI")])
17959 (define_insn "*strsethi_1"
17960   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17961         (match_operand:HI 2 "register_operand" "a"))
17962    (set (match_operand:SI 0 "register_operand" "=D")
17963         (plus:SI (match_dup 1)
17964                  (const_int 2)))
17965    (use (reg:SI DIRFLAG_REG))]
17966   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17967   "stosw"
17968   [(set_attr "type" "str")
17969    (set_attr "memory" "store")
17970    (set_attr "mode" "HI")])
17972 (define_insn "*strsethi_rex_1"
17973   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17974         (match_operand:HI 2 "register_operand" "a"))
17975    (set (match_operand:DI 0 "register_operand" "=D")
17976         (plus:DI (match_dup 1)
17977                  (const_int 2)))
17978    (use (reg:SI DIRFLAG_REG))]
17979   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17980   "stosw"
17981   [(set_attr "type" "str")
17982    (set_attr "memory" "store")
17983    (set_attr "mode" "HI")])
17985 (define_insn "*strsetqi_1"
17986   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17987         (match_operand:QI 2 "register_operand" "a"))
17988    (set (match_operand:SI 0 "register_operand" "=D")
17989         (plus:SI (match_dup 1)
17990                  (const_int 1)))
17991    (use (reg:SI DIRFLAG_REG))]
17992   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17993   "stosb"
17994   [(set_attr "type" "str")
17995    (set_attr "memory" "store")
17996    (set_attr "mode" "QI")])
17998 (define_insn "*strsetqi_rex_1"
17999   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18000         (match_operand:QI 2 "register_operand" "a"))
18001    (set (match_operand:DI 0 "register_operand" "=D")
18002         (plus:DI (match_dup 1)
18003                  (const_int 1)))
18004    (use (reg:SI DIRFLAG_REG))]
18005   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18006   "stosb"
18007   [(set_attr "type" "str")
18008    (set_attr "memory" "store")
18009    (set_attr "mode" "QI")])
18011 (define_expand "rep_stos"
18012   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18013               (set (match_operand 0 "register_operand" "")
18014                    (match_operand 4 "" ""))
18015               (set (match_operand 2 "memory_operand" "") (const_int 0))
18016               (use (match_operand 3 "register_operand" ""))
18017               (use (match_dup 1))
18018               (use (reg:SI DIRFLAG_REG))])]
18019   ""
18020   "")
18022 (define_insn "*rep_stosdi_rex64"
18023   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18024    (set (match_operand:DI 0 "register_operand" "=D") 
18025         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18026                             (const_int 3))
18027                  (match_operand:DI 3 "register_operand" "0")))
18028    (set (mem:BLK (match_dup 3))
18029         (const_int 0))
18030    (use (match_operand:DI 2 "register_operand" "a"))
18031    (use (match_dup 4))
18032    (use (reg:SI DIRFLAG_REG))]
18033   "TARGET_64BIT"
18034   "{rep\;stosq|rep stosq}"
18035   [(set_attr "type" "str")
18036    (set_attr "prefix_rep" "1")
18037    (set_attr "memory" "store")
18038    (set_attr "mode" "DI")])
18040 (define_insn "*rep_stossi"
18041   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18042    (set (match_operand:SI 0 "register_operand" "=D") 
18043         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18044                             (const_int 2))
18045                  (match_operand:SI 3 "register_operand" "0")))
18046    (set (mem:BLK (match_dup 3))
18047         (const_int 0))
18048    (use (match_operand:SI 2 "register_operand" "a"))
18049    (use (match_dup 4))
18050    (use (reg:SI DIRFLAG_REG))]
18051   "!TARGET_64BIT"
18052   "{rep\;stosl|rep stosd}"
18053   [(set_attr "type" "str")
18054    (set_attr "prefix_rep" "1")
18055    (set_attr "memory" "store")
18056    (set_attr "mode" "SI")])
18058 (define_insn "*rep_stossi_rex64"
18059   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18060    (set (match_operand:DI 0 "register_operand" "=D") 
18061         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18062                             (const_int 2))
18063                  (match_operand:DI 3 "register_operand" "0")))
18064    (set (mem:BLK (match_dup 3))
18065         (const_int 0))
18066    (use (match_operand:SI 2 "register_operand" "a"))
18067    (use (match_dup 4))
18068    (use (reg:SI DIRFLAG_REG))]
18069   "TARGET_64BIT"
18070   "{rep\;stosl|rep stosd}"
18071   [(set_attr "type" "str")
18072    (set_attr "prefix_rep" "1")
18073    (set_attr "memory" "store")
18074    (set_attr "mode" "SI")])
18076 (define_insn "*rep_stosqi"
18077   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18078    (set (match_operand:SI 0 "register_operand" "=D") 
18079         (plus:SI (match_operand:SI 3 "register_operand" "0")
18080                  (match_operand:SI 4 "register_operand" "1")))
18081    (set (mem:BLK (match_dup 3))
18082         (const_int 0))
18083    (use (match_operand:QI 2 "register_operand" "a"))
18084    (use (match_dup 4))
18085    (use (reg:SI DIRFLAG_REG))]
18086   "!TARGET_64BIT"
18087   "{rep\;stosb|rep stosb}"
18088   [(set_attr "type" "str")
18089    (set_attr "prefix_rep" "1")
18090    (set_attr "memory" "store")
18091    (set_attr "mode" "QI")])
18093 (define_insn "*rep_stosqi_rex64"
18094   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18095    (set (match_operand:DI 0 "register_operand" "=D") 
18096         (plus:DI (match_operand:DI 3 "register_operand" "0")
18097                  (match_operand:DI 4 "register_operand" "1")))
18098    (set (mem:BLK (match_dup 3))
18099         (const_int 0))
18100    (use (match_operand:QI 2 "register_operand" "a"))
18101    (use (match_dup 4))
18102    (use (reg:SI DIRFLAG_REG))]
18103   "TARGET_64BIT"
18104   "{rep\;stosb|rep stosb}"
18105   [(set_attr "type" "str")
18106    (set_attr "prefix_rep" "1")
18107    (set_attr "memory" "store")
18108    (set_attr "mode" "QI")])
18110 (define_expand "cmpstrnsi"
18111   [(set (match_operand:SI 0 "register_operand" "")
18112         (compare:SI (match_operand:BLK 1 "general_operand" "")
18113                     (match_operand:BLK 2 "general_operand" "")))
18114    (use (match_operand 3 "general_operand" ""))
18115    (use (match_operand 4 "immediate_operand" ""))]
18116   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18118   rtx addr1, addr2, out, outlow, count, countreg, align;
18120   /* Can't use this if the user has appropriated esi or edi.  */
18121   if (global_regs[4] || global_regs[5])
18122     FAIL;
18124   out = operands[0];
18125   if (GET_CODE (out) != REG)
18126     out = gen_reg_rtx (SImode);
18128   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18129   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18130   if (addr1 != XEXP (operands[1], 0))
18131     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18132   if (addr2 != XEXP (operands[2], 0))
18133     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18135   count = operands[3];
18136   countreg = ix86_zero_extend_to_Pmode (count);
18138   /* %%% Iff we are testing strict equality, we can use known alignment
18139      to good advantage.  This may be possible with combine, particularly
18140      once cc0 is dead.  */
18141   align = operands[4];
18143   emit_insn (gen_cld ());
18144   if (GET_CODE (count) == CONST_INT)
18145     {
18146       if (INTVAL (count) == 0)
18147         {
18148           emit_move_insn (operands[0], const0_rtx);
18149           DONE;
18150         }
18151       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18152                                      operands[1], operands[2]));
18153     }
18154   else
18155     {
18156       if (TARGET_64BIT)
18157         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18158       else
18159         emit_insn (gen_cmpsi_1 (countreg, countreg));
18160       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18161                                   operands[1], operands[2]));
18162     }
18164   outlow = gen_lowpart (QImode, out);
18165   emit_insn (gen_cmpintqi (outlow));
18166   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18168   if (operands[0] != out)
18169     emit_move_insn (operands[0], out);
18171   DONE;
18174 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18176 (define_expand "cmpintqi"
18177   [(set (match_dup 1)
18178         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18179    (set (match_dup 2)
18180         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181    (parallel [(set (match_operand:QI 0 "register_operand" "")
18182                    (minus:QI (match_dup 1)
18183                              (match_dup 2)))
18184               (clobber (reg:CC FLAGS_REG))])]
18185   ""
18186   "operands[1] = gen_reg_rtx (QImode);
18187    operands[2] = gen_reg_rtx (QImode);")
18189 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18190 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18192 (define_expand "cmpstrnqi_nz_1"
18193   [(parallel [(set (reg:CC FLAGS_REG)
18194                    (compare:CC (match_operand 4 "memory_operand" "")
18195                                (match_operand 5 "memory_operand" "")))
18196               (use (match_operand 2 "register_operand" ""))
18197               (use (match_operand:SI 3 "immediate_operand" ""))
18198               (use (reg:SI DIRFLAG_REG))
18199               (clobber (match_operand 0 "register_operand" ""))
18200               (clobber (match_operand 1 "register_operand" ""))
18201               (clobber (match_dup 2))])]
18202   ""
18203   "")
18205 (define_insn "*cmpstrnqi_nz_1"
18206   [(set (reg:CC FLAGS_REG)
18207         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18208                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18209    (use (match_operand:SI 6 "register_operand" "2"))
18210    (use (match_operand:SI 3 "immediate_operand" "i"))
18211    (use (reg:SI DIRFLAG_REG))
18212    (clobber (match_operand:SI 0 "register_operand" "=S"))
18213    (clobber (match_operand:SI 1 "register_operand" "=D"))
18214    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18215   "!TARGET_64BIT"
18216   "repz{\;| }cmpsb"
18217   [(set_attr "type" "str")
18218    (set_attr "mode" "QI")
18219    (set_attr "prefix_rep" "1")])
18221 (define_insn "*cmpstrnqi_nz_rex_1"
18222   [(set (reg:CC FLAGS_REG)
18223         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18224                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18225    (use (match_operand:DI 6 "register_operand" "2"))
18226    (use (match_operand:SI 3 "immediate_operand" "i"))
18227    (use (reg:SI DIRFLAG_REG))
18228    (clobber (match_operand:DI 0 "register_operand" "=S"))
18229    (clobber (match_operand:DI 1 "register_operand" "=D"))
18230    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18231   "TARGET_64BIT"
18232   "repz{\;| }cmpsb"
18233   [(set_attr "type" "str")
18234    (set_attr "mode" "QI")
18235    (set_attr "prefix_rep" "1")])
18237 ;; The same, but the count is not known to not be zero.
18239 (define_expand "cmpstrnqi_1"
18240   [(parallel [(set (reg:CC FLAGS_REG)
18241                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18242                                      (const_int 0))
18243                   (compare:CC (match_operand 4 "memory_operand" "")
18244                               (match_operand 5 "memory_operand" ""))
18245                   (const_int 0)))
18246               (use (match_operand:SI 3 "immediate_operand" ""))
18247               (use (reg:CC FLAGS_REG))
18248               (use (reg:SI DIRFLAG_REG))
18249               (clobber (match_operand 0 "register_operand" ""))
18250               (clobber (match_operand 1 "register_operand" ""))
18251               (clobber (match_dup 2))])]
18252   ""
18253   "")
18255 (define_insn "*cmpstrnqi_1"
18256   [(set (reg:CC FLAGS_REG)
18257         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18258                              (const_int 0))
18259           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18260                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18261           (const_int 0)))
18262    (use (match_operand:SI 3 "immediate_operand" "i"))
18263    (use (reg:CC FLAGS_REG))
18264    (use (reg:SI DIRFLAG_REG))
18265    (clobber (match_operand:SI 0 "register_operand" "=S"))
18266    (clobber (match_operand:SI 1 "register_operand" "=D"))
18267    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18268   "!TARGET_64BIT"
18269   "repz{\;| }cmpsb"
18270   [(set_attr "type" "str")
18271    (set_attr "mode" "QI")
18272    (set_attr "prefix_rep" "1")])
18274 (define_insn "*cmpstrnqi_rex_1"
18275   [(set (reg:CC FLAGS_REG)
18276         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18277                              (const_int 0))
18278           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18279                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18280           (const_int 0)))
18281    (use (match_operand:SI 3 "immediate_operand" "i"))
18282    (use (reg:CC FLAGS_REG))
18283    (use (reg:SI DIRFLAG_REG))
18284    (clobber (match_operand:DI 0 "register_operand" "=S"))
18285    (clobber (match_operand:DI 1 "register_operand" "=D"))
18286    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18287   "TARGET_64BIT"
18288   "repz{\;| }cmpsb"
18289   [(set_attr "type" "str")
18290    (set_attr "mode" "QI")
18291    (set_attr "prefix_rep" "1")])
18293 (define_expand "strlensi"
18294   [(set (match_operand:SI 0 "register_operand" "")
18295         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18296                     (match_operand:QI 2 "immediate_operand" "")
18297                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18298   ""
18300  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18301    DONE;
18302  else
18303    FAIL;
18306 (define_expand "strlendi"
18307   [(set (match_operand:DI 0 "register_operand" "")
18308         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18309                     (match_operand:QI 2 "immediate_operand" "")
18310                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18311   ""
18313  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18314    DONE;
18315  else
18316    FAIL;
18319 (define_expand "strlenqi_1"
18320   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18321               (use (reg:SI DIRFLAG_REG))
18322               (clobber (match_operand 1 "register_operand" ""))
18323               (clobber (reg:CC FLAGS_REG))])]
18324   ""
18325   "")
18327 (define_insn "*strlenqi_1"
18328   [(set (match_operand:SI 0 "register_operand" "=&c")
18329         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18330                     (match_operand:QI 2 "register_operand" "a")
18331                     (match_operand:SI 3 "immediate_operand" "i")
18332                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18333    (use (reg:SI DIRFLAG_REG))
18334    (clobber (match_operand:SI 1 "register_operand" "=D"))
18335    (clobber (reg:CC FLAGS_REG))]
18336   "!TARGET_64BIT"
18337   "repnz{\;| }scasb"
18338   [(set_attr "type" "str")
18339    (set_attr "mode" "QI")
18340    (set_attr "prefix_rep" "1")])
18342 (define_insn "*strlenqi_rex_1"
18343   [(set (match_operand:DI 0 "register_operand" "=&c")
18344         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18345                     (match_operand:QI 2 "register_operand" "a")
18346                     (match_operand:DI 3 "immediate_operand" "i")
18347                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18348    (use (reg:SI DIRFLAG_REG))
18349    (clobber (match_operand:DI 1 "register_operand" "=D"))
18350    (clobber (reg:CC FLAGS_REG))]
18351   "TARGET_64BIT"
18352   "repnz{\;| }scasb"
18353   [(set_attr "type" "str")
18354    (set_attr "mode" "QI")
18355    (set_attr "prefix_rep" "1")])
18357 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18358 ;; handled in combine, but it is not currently up to the task.
18359 ;; When used for their truth value, the cmpstrn* expanders generate
18360 ;; code like this:
18362 ;;   repz cmpsb
18363 ;;   seta       %al
18364 ;;   setb       %dl
18365 ;;   cmpb       %al, %dl
18366 ;;   jcc        label
18368 ;; The intermediate three instructions are unnecessary.
18370 ;; This one handles cmpstrn*_nz_1...
18371 (define_peephole2
18372   [(parallel[
18373      (set (reg:CC FLAGS_REG)
18374           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18375                       (mem:BLK (match_operand 5 "register_operand" ""))))
18376      (use (match_operand 6 "register_operand" ""))
18377      (use (match_operand:SI 3 "immediate_operand" ""))
18378      (use (reg:SI DIRFLAG_REG))
18379      (clobber (match_operand 0 "register_operand" ""))
18380      (clobber (match_operand 1 "register_operand" ""))
18381      (clobber (match_operand 2 "register_operand" ""))])
18382    (set (match_operand:QI 7 "register_operand" "")
18383         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18384    (set (match_operand:QI 8 "register_operand" "")
18385         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18386    (set (reg FLAGS_REG)
18387         (compare (match_dup 7) (match_dup 8)))
18388   ]
18389   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18390   [(parallel[
18391      (set (reg:CC FLAGS_REG)
18392           (compare:CC (mem:BLK (match_dup 4))
18393                       (mem:BLK (match_dup 5))))
18394      (use (match_dup 6))
18395      (use (match_dup 3))
18396      (use (reg:SI DIRFLAG_REG))
18397      (clobber (match_dup 0))
18398      (clobber (match_dup 1))
18399      (clobber (match_dup 2))])]
18400   "")
18402 ;; ...and this one handles cmpstrn*_1.
18403 (define_peephole2
18404   [(parallel[
18405      (set (reg:CC FLAGS_REG)
18406           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18407                                (const_int 0))
18408             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18409                         (mem:BLK (match_operand 5 "register_operand" "")))
18410             (const_int 0)))
18411      (use (match_operand:SI 3 "immediate_operand" ""))
18412      (use (reg:CC FLAGS_REG))
18413      (use (reg:SI DIRFLAG_REG))
18414      (clobber (match_operand 0 "register_operand" ""))
18415      (clobber (match_operand 1 "register_operand" ""))
18416      (clobber (match_operand 2 "register_operand" ""))])
18417    (set (match_operand:QI 7 "register_operand" "")
18418         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18419    (set (match_operand:QI 8 "register_operand" "")
18420         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18421    (set (reg FLAGS_REG)
18422         (compare (match_dup 7) (match_dup 8)))
18423   ]
18424   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18425   [(parallel[
18426      (set (reg:CC FLAGS_REG)
18427           (if_then_else:CC (ne (match_dup 6)
18428                                (const_int 0))
18429             (compare:CC (mem:BLK (match_dup 4))
18430                         (mem:BLK (match_dup 5)))
18431             (const_int 0)))
18432      (use (match_dup 3))
18433      (use (reg:CC FLAGS_REG))
18434      (use (reg:SI DIRFLAG_REG))
18435      (clobber (match_dup 0))
18436      (clobber (match_dup 1))
18437      (clobber (match_dup 2))])]
18438   "")
18442 ;; Conditional move instructions.
18444 (define_expand "movdicc"
18445   [(set (match_operand:DI 0 "register_operand" "")
18446         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18447                          (match_operand:DI 2 "general_operand" "")
18448                          (match_operand:DI 3 "general_operand" "")))]
18449   "TARGET_64BIT"
18450   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18452 (define_insn "x86_movdicc_0_m1_rex64"
18453   [(set (match_operand:DI 0 "register_operand" "=r")
18454         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18455           (const_int -1)
18456           (const_int 0)))
18457    (clobber (reg:CC FLAGS_REG))]
18458   "TARGET_64BIT"
18459   "sbb{q}\t%0, %0"
18460   ; Since we don't have the proper number of operands for an alu insn,
18461   ; fill in all the blanks.
18462   [(set_attr "type" "alu")
18463    (set_attr "pent_pair" "pu")
18464    (set_attr "memory" "none")
18465    (set_attr "imm_disp" "false")
18466    (set_attr "mode" "DI")
18467    (set_attr "length_immediate" "0")])
18469 (define_insn "*movdicc_c_rex64"
18470   [(set (match_operand:DI 0 "register_operand" "=r,r")
18471         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18472                                 [(reg FLAGS_REG) (const_int 0)])
18473                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18474                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18475   "TARGET_64BIT && TARGET_CMOVE
18476    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18477   "@
18478    cmov%O2%C1\t{%2, %0|%0, %2}
18479    cmov%O2%c1\t{%3, %0|%0, %3}"
18480   [(set_attr "type" "icmov")
18481    (set_attr "mode" "DI")])
18483 (define_expand "movsicc"
18484   [(set (match_operand:SI 0 "register_operand" "")
18485         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18486                          (match_operand:SI 2 "general_operand" "")
18487                          (match_operand:SI 3 "general_operand" "")))]
18488   ""
18489   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18491 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18492 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18493 ;; So just document what we're doing explicitly.
18495 (define_insn "x86_movsicc_0_m1"
18496   [(set (match_operand:SI 0 "register_operand" "=r")
18497         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18498           (const_int -1)
18499           (const_int 0)))
18500    (clobber (reg:CC FLAGS_REG))]
18501   ""
18502   "sbb{l}\t%0, %0"
18503   ; Since we don't have the proper number of operands for an alu insn,
18504   ; fill in all the blanks.
18505   [(set_attr "type" "alu")
18506    (set_attr "pent_pair" "pu")
18507    (set_attr "memory" "none")
18508    (set_attr "imm_disp" "false")
18509    (set_attr "mode" "SI")
18510    (set_attr "length_immediate" "0")])
18512 (define_insn "*movsicc_noc"
18513   [(set (match_operand:SI 0 "register_operand" "=r,r")
18514         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18515                                 [(reg FLAGS_REG) (const_int 0)])
18516                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18517                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18518   "TARGET_CMOVE
18519    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18520   "@
18521    cmov%O2%C1\t{%2, %0|%0, %2}
18522    cmov%O2%c1\t{%3, %0|%0, %3}"
18523   [(set_attr "type" "icmov")
18524    (set_attr "mode" "SI")])
18526 (define_expand "movhicc"
18527   [(set (match_operand:HI 0 "register_operand" "")
18528         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18529                          (match_operand:HI 2 "general_operand" "")
18530                          (match_operand:HI 3 "general_operand" "")))]
18531   "TARGET_HIMODE_MATH"
18532   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18534 (define_insn "*movhicc_noc"
18535   [(set (match_operand:HI 0 "register_operand" "=r,r")
18536         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18537                                 [(reg FLAGS_REG) (const_int 0)])
18538                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18539                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18540   "TARGET_CMOVE
18541    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18542   "@
18543    cmov%O2%C1\t{%2, %0|%0, %2}
18544    cmov%O2%c1\t{%3, %0|%0, %3}"
18545   [(set_attr "type" "icmov")
18546    (set_attr "mode" "HI")])
18548 (define_expand "movqicc"
18549   [(set (match_operand:QI 0 "register_operand" "")
18550         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18551                          (match_operand:QI 2 "general_operand" "")
18552                          (match_operand:QI 3 "general_operand" "")))]
18553   "TARGET_QIMODE_MATH"
18554   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18556 (define_insn_and_split "*movqicc_noc"
18557   [(set (match_operand:QI 0 "register_operand" "=r,r")
18558         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18559                                 [(match_operand 4 "flags_reg_operand" "")
18560                                  (const_int 0)])
18561                       (match_operand:QI 2 "register_operand" "r,0")
18562                       (match_operand:QI 3 "register_operand" "0,r")))]
18563   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18564   "#"
18565   "&& reload_completed"
18566   [(set (match_dup 0)
18567         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18568                       (match_dup 2)
18569                       (match_dup 3)))]
18570   "operands[0] = gen_lowpart (SImode, operands[0]);
18571    operands[2] = gen_lowpart (SImode, operands[2]);
18572    operands[3] = gen_lowpart (SImode, operands[3]);"
18573   [(set_attr "type" "icmov")
18574    (set_attr "mode" "SI")])
18576 (define_expand "movsfcc"
18577   [(set (match_operand:SF 0 "register_operand" "")
18578         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18579                          (match_operand:SF 2 "register_operand" "")
18580                          (match_operand:SF 3 "register_operand" "")))]
18581   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18582   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18584 (define_insn "*movsfcc_1_387"
18585   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18586         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18587                                 [(reg FLAGS_REG) (const_int 0)])
18588                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18589                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18590   "TARGET_80387 && TARGET_CMOVE
18591    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18592   "@
18593    fcmov%F1\t{%2, %0|%0, %2}
18594    fcmov%f1\t{%3, %0|%0, %3}
18595    cmov%O2%C1\t{%2, %0|%0, %2}
18596    cmov%O2%c1\t{%3, %0|%0, %3}"
18597   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18598    (set_attr "mode" "SF,SF,SI,SI")])
18600 (define_expand "movdfcc"
18601   [(set (match_operand:DF 0 "register_operand" "")
18602         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18603                          (match_operand:DF 2 "register_operand" "")
18604                          (match_operand:DF 3 "register_operand" "")))]
18605   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18606   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18608 (define_insn "*movdfcc_1"
18609   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18610         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18611                                 [(reg FLAGS_REG) (const_int 0)])
18612                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18613                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18614   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18615    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18616   "@
18617    fcmov%F1\t{%2, %0|%0, %2}
18618    fcmov%f1\t{%3, %0|%0, %3}
18619    #
18620    #"
18621   [(set_attr "type" "fcmov,fcmov,multi,multi")
18622    (set_attr "mode" "DF")])
18624 (define_insn "*movdfcc_1_rex64"
18625   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18626         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18627                                 [(reg FLAGS_REG) (const_int 0)])
18628                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18629                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18630   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18631    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18632   "@
18633    fcmov%F1\t{%2, %0|%0, %2}
18634    fcmov%f1\t{%3, %0|%0, %3}
18635    cmov%O2%C1\t{%2, %0|%0, %2}
18636    cmov%O2%c1\t{%3, %0|%0, %3}"
18637   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18638    (set_attr "mode" "DF")])
18640 (define_split
18641   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18642         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18643                                 [(match_operand 4 "flags_reg_operand" "")
18644                                  (const_int 0)])
18645                       (match_operand:DF 2 "nonimmediate_operand" "")
18646                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18647   "!TARGET_64BIT && reload_completed"
18648   [(set (match_dup 2)
18649         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18650                       (match_dup 5)
18651                       (match_dup 7)))
18652    (set (match_dup 3)
18653         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18654                       (match_dup 6)
18655                       (match_dup 8)))]
18656   "split_di (operands+2, 1, operands+5, operands+6);
18657    split_di (operands+3, 1, operands+7, operands+8);
18658    split_di (operands, 1, operands+2, operands+3);")
18660 (define_expand "movxfcc"
18661   [(set (match_operand:XF 0 "register_operand" "")
18662         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18663                          (match_operand:XF 2 "register_operand" "")
18664                          (match_operand:XF 3 "register_operand" "")))]
18665   "TARGET_80387 && TARGET_CMOVE"
18666   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18668 (define_insn "*movxfcc_1"
18669   [(set (match_operand:XF 0 "register_operand" "=f,f")
18670         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18671                                 [(reg FLAGS_REG) (const_int 0)])
18672                       (match_operand:XF 2 "register_operand" "f,0")
18673                       (match_operand:XF 3 "register_operand" "0,f")))]
18674   "TARGET_80387 && TARGET_CMOVE"
18675   "@
18676    fcmov%F1\t{%2, %0|%0, %2}
18677    fcmov%f1\t{%3, %0|%0, %3}"
18678   [(set_attr "type" "fcmov")
18679    (set_attr "mode" "XF")])
18681 ;; These versions of the min/max patterns are intentionally ignorant of
18682 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18683 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18684 ;; are undefined in this condition, we're certain this is correct.
18686 (define_insn "sminsf3"
18687   [(set (match_operand:SF 0 "register_operand" "=x")
18688         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18689                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18690   "TARGET_SSE_MATH"
18691   "minss\t{%2, %0|%0, %2}"
18692   [(set_attr "type" "sseadd")
18693    (set_attr "mode" "SF")])
18695 (define_insn "smaxsf3"
18696   [(set (match_operand:SF 0 "register_operand" "=x")
18697         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18698                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18699   "TARGET_SSE_MATH"
18700   "maxss\t{%2, %0|%0, %2}"
18701   [(set_attr "type" "sseadd")
18702    (set_attr "mode" "SF")])
18704 (define_insn "smindf3"
18705   [(set (match_operand:DF 0 "register_operand" "=x")
18706         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18707                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18708   "TARGET_SSE2 && TARGET_SSE_MATH"
18709   "minsd\t{%2, %0|%0, %2}"
18710   [(set_attr "type" "sseadd")
18711    (set_attr "mode" "DF")])
18713 (define_insn "smaxdf3"
18714   [(set (match_operand:DF 0 "register_operand" "=x")
18715         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18716                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18717   "TARGET_SSE2 && TARGET_SSE_MATH"
18718   "maxsd\t{%2, %0|%0, %2}"
18719   [(set_attr "type" "sseadd")
18720    (set_attr "mode" "DF")])
18722 ;; These versions of the min/max patterns implement exactly the operations
18723 ;;   min = (op1 < op2 ? op1 : op2)
18724 ;;   max = (!(op1 < op2) ? op1 : op2)
18725 ;; Their operands are not commutative, and thus they may be used in the
18726 ;; presence of -0.0 and NaN.
18728 (define_insn "*ieee_sminsf3"
18729   [(set (match_operand:SF 0 "register_operand" "=x")
18730         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18731                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18732                    UNSPEC_IEEE_MIN))]
18733   "TARGET_SSE_MATH"
18734   "minss\t{%2, %0|%0, %2}"
18735   [(set_attr "type" "sseadd")
18736    (set_attr "mode" "SF")])
18738 (define_insn "*ieee_smaxsf3"
18739   [(set (match_operand:SF 0 "register_operand" "=x")
18740         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18741                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18742                    UNSPEC_IEEE_MAX))]
18743   "TARGET_SSE_MATH"
18744   "maxss\t{%2, %0|%0, %2}"
18745   [(set_attr "type" "sseadd")
18746    (set_attr "mode" "SF")])
18748 (define_insn "*ieee_smindf3"
18749   [(set (match_operand:DF 0 "register_operand" "=x")
18750         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18751                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18752                    UNSPEC_IEEE_MIN))]
18753   "TARGET_SSE2 && TARGET_SSE_MATH"
18754   "minsd\t{%2, %0|%0, %2}"
18755   [(set_attr "type" "sseadd")
18756    (set_attr "mode" "DF")])
18758 (define_insn "*ieee_smaxdf3"
18759   [(set (match_operand:DF 0 "register_operand" "=x")
18760         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18761                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18762                    UNSPEC_IEEE_MAX))]
18763   "TARGET_SSE2 && TARGET_SSE_MATH"
18764   "maxsd\t{%2, %0|%0, %2}"
18765   [(set_attr "type" "sseadd")
18766    (set_attr "mode" "DF")])
18768 ;; Conditional addition patterns
18769 (define_expand "addqicc"
18770   [(match_operand:QI 0 "register_operand" "")
18771    (match_operand 1 "comparison_operator" "")
18772    (match_operand:QI 2 "register_operand" "")
18773    (match_operand:QI 3 "const_int_operand" "")]
18774   ""
18775   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18777 (define_expand "addhicc"
18778   [(match_operand:HI 0 "register_operand" "")
18779    (match_operand 1 "comparison_operator" "")
18780    (match_operand:HI 2 "register_operand" "")
18781    (match_operand:HI 3 "const_int_operand" "")]
18782   ""
18783   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18785 (define_expand "addsicc"
18786   [(match_operand:SI 0 "register_operand" "")
18787    (match_operand 1 "comparison_operator" "")
18788    (match_operand:SI 2 "register_operand" "")
18789    (match_operand:SI 3 "const_int_operand" "")]
18790   ""
18791   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18793 (define_expand "adddicc"
18794   [(match_operand:DI 0 "register_operand" "")
18795    (match_operand 1 "comparison_operator" "")
18796    (match_operand:DI 2 "register_operand" "")
18797    (match_operand:DI 3 "const_int_operand" "")]
18798   "TARGET_64BIT"
18799   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18802 ;; Misc patterns (?)
18804 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18805 ;; Otherwise there will be nothing to keep
18806 ;; 
18807 ;; [(set (reg ebp) (reg esp))]
18808 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18809 ;;  (clobber (eflags)]
18810 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18812 ;; in proper program order.
18813 (define_insn "pro_epilogue_adjust_stack_1"
18814   [(set (match_operand:SI 0 "register_operand" "=r,r")
18815         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18816                  (match_operand:SI 2 "immediate_operand" "i,i")))
18817    (clobber (reg:CC FLAGS_REG))
18818    (clobber (mem:BLK (scratch)))]
18819   "!TARGET_64BIT"
18821   switch (get_attr_type (insn))
18822     {
18823     case TYPE_IMOV:
18824       return "mov{l}\t{%1, %0|%0, %1}";
18826     case TYPE_ALU:
18827       if (GET_CODE (operands[2]) == CONST_INT
18828           && (INTVAL (operands[2]) == 128
18829               || (INTVAL (operands[2]) < 0
18830                   && INTVAL (operands[2]) != -128)))
18831         {
18832           operands[2] = GEN_INT (-INTVAL (operands[2]));
18833           return "sub{l}\t{%2, %0|%0, %2}";
18834         }
18835       return "add{l}\t{%2, %0|%0, %2}";
18837     case TYPE_LEA:
18838       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18839       return "lea{l}\t{%a2, %0|%0, %a2}";
18841     default:
18842       gcc_unreachable ();
18843     }
18845   [(set (attr "type")
18846         (cond [(eq_attr "alternative" "0")
18847                  (const_string "alu")
18848                (match_operand:SI 2 "const0_operand" "")
18849                  (const_string "imov")
18850               ]
18851               (const_string "lea")))
18852    (set_attr "mode" "SI")])
18854 (define_insn "pro_epilogue_adjust_stack_rex64"
18855   [(set (match_operand:DI 0 "register_operand" "=r,r")
18856         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18857                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18858    (clobber (reg:CC FLAGS_REG))
18859    (clobber (mem:BLK (scratch)))]
18860   "TARGET_64BIT"
18862   switch (get_attr_type (insn))
18863     {
18864     case TYPE_IMOV:
18865       return "mov{q}\t{%1, %0|%0, %1}";
18867     case TYPE_ALU:
18868       if (GET_CODE (operands[2]) == CONST_INT
18869           /* Avoid overflows.  */
18870           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18871           && (INTVAL (operands[2]) == 128
18872               || (INTVAL (operands[2]) < 0
18873                   && INTVAL (operands[2]) != -128)))
18874         {
18875           operands[2] = GEN_INT (-INTVAL (operands[2]));
18876           return "sub{q}\t{%2, %0|%0, %2}";
18877         }
18878       return "add{q}\t{%2, %0|%0, %2}";
18880     case TYPE_LEA:
18881       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18882       return "lea{q}\t{%a2, %0|%0, %a2}";
18884     default:
18885       gcc_unreachable ();
18886     }
18888   [(set (attr "type")
18889         (cond [(eq_attr "alternative" "0")
18890                  (const_string "alu")
18891                (match_operand:DI 2 "const0_operand" "")
18892                  (const_string "imov")
18893               ]
18894               (const_string "lea")))
18895    (set_attr "mode" "DI")])
18897 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18898   [(set (match_operand:DI 0 "register_operand" "=r,r")
18899         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18900                  (match_operand:DI 3 "immediate_operand" "i,i")))
18901    (use (match_operand:DI 2 "register_operand" "r,r"))
18902    (clobber (reg:CC FLAGS_REG))
18903    (clobber (mem:BLK (scratch)))]
18904   "TARGET_64BIT"
18906   switch (get_attr_type (insn))
18907     {
18908     case TYPE_ALU:
18909       return "add{q}\t{%2, %0|%0, %2}";
18911     case TYPE_LEA:
18912       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18913       return "lea{q}\t{%a2, %0|%0, %a2}";
18915     default:
18916       gcc_unreachable ();
18917     }
18919   [(set_attr "type" "alu,lea")
18920    (set_attr "mode" "DI")])
18922 (define_expand "allocate_stack_worker"
18923   [(match_operand:SI 0 "register_operand" "")]
18924   "TARGET_STACK_PROBE"
18926   if (reload_completed)
18927     {
18928       if (TARGET_64BIT)
18929         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18930       else
18931         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18932     }
18933   else
18934     {
18935       if (TARGET_64BIT)
18936         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18937       else
18938         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18939     }
18940   DONE;
18943 (define_insn "allocate_stack_worker_1"
18944   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18945     UNSPECV_STACK_PROBE)
18946    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18947    (clobber (match_scratch:SI 1 "=0"))
18948    (clobber (reg:CC FLAGS_REG))]
18949   "!TARGET_64BIT && TARGET_STACK_PROBE"
18950   "call\t__alloca"
18951   [(set_attr "type" "multi")
18952    (set_attr "length" "5")])
18954 (define_expand "allocate_stack_worker_postreload"
18955   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18956                                     UNSPECV_STACK_PROBE)
18957               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18958               (clobber (match_dup 0))
18959               (clobber (reg:CC FLAGS_REG))])]
18960   ""
18961   "")
18963 (define_insn "allocate_stack_worker_rex64"
18964   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18965     UNSPECV_STACK_PROBE)
18966    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18967    (clobber (match_scratch:DI 1 "=0"))
18968    (clobber (reg:CC FLAGS_REG))]
18969   "TARGET_64BIT && TARGET_STACK_PROBE"
18970   "call\t__alloca"
18971   [(set_attr "type" "multi")
18972    (set_attr "length" "5")])
18974 (define_expand "allocate_stack_worker_rex64_postreload"
18975   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18976                                     UNSPECV_STACK_PROBE)
18977               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18978               (clobber (match_dup 0))
18979               (clobber (reg:CC FLAGS_REG))])]
18980   ""
18981   "")
18983 (define_expand "allocate_stack"
18984   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18985                    (minus:SI (reg:SI SP_REG)
18986                              (match_operand:SI 1 "general_operand" "")))
18987               (clobber (reg:CC FLAGS_REG))])
18988    (parallel [(set (reg:SI SP_REG)
18989                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18990               (clobber (reg:CC FLAGS_REG))])]
18991   "TARGET_STACK_PROBE"
18993 #ifdef CHECK_STACK_LIMIT
18994   if (GET_CODE (operands[1]) == CONST_INT
18995       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18996     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18997                            operands[1]));
18998   else 
18999 #endif
19000     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19001                                                             operands[1])));
19003   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19004   DONE;
19007 (define_expand "builtin_setjmp_receiver"
19008   [(label_ref (match_operand 0 "" ""))]
19009   "!TARGET_64BIT && flag_pic"
19011   if (TARGET_MACHO)
19012     {
19013       rtx xops[3];
19014       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19015       rtx label_rtx = gen_label_rtx ();
19016       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19017       xops[0] = xops[1] = picreg;
19018       xops[2] = gen_rtx_CONST (SImode,
19019                   gen_rtx_MINUS (SImode,
19020                     gen_rtx_LABEL_REF (SImode, label_rtx),
19021                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19022       ix86_expand_binary_operator (MINUS, SImode, xops);
19023     }
19024   else
19025     emit_insn (gen_set_got (pic_offset_table_rtx));
19026   DONE;
19029 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19031 (define_split
19032   [(set (match_operand 0 "register_operand" "")
19033         (match_operator 3 "promotable_binary_operator"
19034            [(match_operand 1 "register_operand" "")
19035             (match_operand 2 "aligned_operand" "")]))
19036    (clobber (reg:CC FLAGS_REG))]
19037   "! TARGET_PARTIAL_REG_STALL && reload_completed
19038    && ((GET_MODE (operands[0]) == HImode 
19039         && ((!optimize_size && !TARGET_FAST_PREFIX)
19040             /* ??? next two lines just !satisfies_constraint_K (...) */
19041             || GET_CODE (operands[2]) != CONST_INT
19042             || satisfies_constraint_K (operands[2])))
19043        || (GET_MODE (operands[0]) == QImode 
19044            && (TARGET_PROMOTE_QImode || optimize_size)))"
19045   [(parallel [(set (match_dup 0)
19046                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19047               (clobber (reg:CC FLAGS_REG))])]
19048   "operands[0] = gen_lowpart (SImode, operands[0]);
19049    operands[1] = gen_lowpart (SImode, operands[1]);
19050    if (GET_CODE (operands[3]) != ASHIFT)
19051      operands[2] = gen_lowpart (SImode, operands[2]);
19052    PUT_MODE (operands[3], SImode);")
19054 ; Promote the QImode tests, as i386 has encoding of the AND
19055 ; instruction with 32-bit sign-extended immediate and thus the
19056 ; instruction size is unchanged, except in the %eax case for
19057 ; which it is increased by one byte, hence the ! optimize_size.
19058 (define_split
19059   [(set (match_operand 0 "flags_reg_operand" "")
19060         (match_operator 2 "compare_operator"
19061           [(and (match_operand 3 "aligned_operand" "")
19062                 (match_operand 4 "const_int_operand" ""))
19063            (const_int 0)]))
19064    (set (match_operand 1 "register_operand" "")
19065         (and (match_dup 3) (match_dup 4)))]
19066   "! TARGET_PARTIAL_REG_STALL && reload_completed
19067    /* Ensure that the operand will remain sign-extended immediate.  */
19068    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19069    && ! optimize_size
19070    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19071        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19072   [(parallel [(set (match_dup 0)
19073                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19074                                     (const_int 0)]))
19075               (set (match_dup 1)
19076                    (and:SI (match_dup 3) (match_dup 4)))])]
19078   operands[4]
19079     = gen_int_mode (INTVAL (operands[4])
19080                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19081   operands[1] = gen_lowpart (SImode, operands[1]);
19082   operands[3] = gen_lowpart (SImode, operands[3]);
19085 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19086 ; the TEST instruction with 32-bit sign-extended immediate and thus
19087 ; the instruction size would at least double, which is not what we
19088 ; want even with ! optimize_size.
19089 (define_split
19090   [(set (match_operand 0 "flags_reg_operand" "")
19091         (match_operator 1 "compare_operator"
19092           [(and (match_operand:HI 2 "aligned_operand" "")
19093                 (match_operand:HI 3 "const_int_operand" ""))
19094            (const_int 0)]))]
19095   "! TARGET_PARTIAL_REG_STALL && reload_completed
19096    /* Ensure that the operand will remain sign-extended immediate.  */
19097    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19098    && ! TARGET_FAST_PREFIX
19099    && ! optimize_size"
19100   [(set (match_dup 0)
19101         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19102                          (const_int 0)]))]
19104   operands[3]
19105     = gen_int_mode (INTVAL (operands[3])
19106                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19107   operands[2] = gen_lowpart (SImode, operands[2]);
19110 (define_split
19111   [(set (match_operand 0 "register_operand" "")
19112         (neg (match_operand 1 "register_operand" "")))
19113    (clobber (reg:CC FLAGS_REG))]
19114   "! TARGET_PARTIAL_REG_STALL && reload_completed
19115    && (GET_MODE (operands[0]) == HImode
19116        || (GET_MODE (operands[0]) == QImode 
19117            && (TARGET_PROMOTE_QImode || optimize_size)))"
19118   [(parallel [(set (match_dup 0)
19119                    (neg:SI (match_dup 1)))
19120               (clobber (reg:CC FLAGS_REG))])]
19121   "operands[0] = gen_lowpart (SImode, operands[0]);
19122    operands[1] = gen_lowpart (SImode, operands[1]);")
19124 (define_split
19125   [(set (match_operand 0 "register_operand" "")
19126         (not (match_operand 1 "register_operand" "")))]
19127   "! TARGET_PARTIAL_REG_STALL && reload_completed
19128    && (GET_MODE (operands[0]) == HImode
19129        || (GET_MODE (operands[0]) == QImode 
19130            && (TARGET_PROMOTE_QImode || optimize_size)))"
19131   [(set (match_dup 0)
19132         (not:SI (match_dup 1)))]
19133   "operands[0] = gen_lowpart (SImode, operands[0]);
19134    operands[1] = gen_lowpart (SImode, operands[1]);")
19136 (define_split 
19137   [(set (match_operand 0 "register_operand" "")
19138         (if_then_else (match_operator 1 "comparison_operator" 
19139                                 [(reg FLAGS_REG) (const_int 0)])
19140                       (match_operand 2 "register_operand" "")
19141                       (match_operand 3 "register_operand" "")))]
19142   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19143    && (GET_MODE (operands[0]) == HImode
19144        || (GET_MODE (operands[0]) == QImode 
19145            && (TARGET_PROMOTE_QImode || optimize_size)))"
19146   [(set (match_dup 0)
19147         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19148   "operands[0] = gen_lowpart (SImode, operands[0]);
19149    operands[2] = gen_lowpart (SImode, operands[2]);
19150    operands[3] = gen_lowpart (SImode, operands[3]);")
19151                         
19153 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19154 ;; transform a complex memory operation into two memory to register operations.
19156 ;; Don't push memory operands
19157 (define_peephole2
19158   [(set (match_operand:SI 0 "push_operand" "")
19159         (match_operand:SI 1 "memory_operand" ""))
19160    (match_scratch:SI 2 "r")]
19161   "! optimize_size && ! TARGET_PUSH_MEMORY"
19162   [(set (match_dup 2) (match_dup 1))
19163    (set (match_dup 0) (match_dup 2))]
19164   "")
19166 (define_peephole2
19167   [(set (match_operand:DI 0 "push_operand" "")
19168         (match_operand:DI 1 "memory_operand" ""))
19169    (match_scratch:DI 2 "r")]
19170   "! optimize_size && ! TARGET_PUSH_MEMORY"
19171   [(set (match_dup 2) (match_dup 1))
19172    (set (match_dup 0) (match_dup 2))]
19173   "")
19175 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19176 ;; SImode pushes.
19177 (define_peephole2
19178   [(set (match_operand:SF 0 "push_operand" "")
19179         (match_operand:SF 1 "memory_operand" ""))
19180    (match_scratch:SF 2 "r")]
19181   "! optimize_size && ! TARGET_PUSH_MEMORY"
19182   [(set (match_dup 2) (match_dup 1))
19183    (set (match_dup 0) (match_dup 2))]
19184   "")
19186 (define_peephole2
19187   [(set (match_operand:HI 0 "push_operand" "")
19188         (match_operand:HI 1 "memory_operand" ""))
19189    (match_scratch:HI 2 "r")]
19190   "! optimize_size && ! TARGET_PUSH_MEMORY"
19191   [(set (match_dup 2) (match_dup 1))
19192    (set (match_dup 0) (match_dup 2))]
19193   "")
19195 (define_peephole2
19196   [(set (match_operand:QI 0 "push_operand" "")
19197         (match_operand:QI 1 "memory_operand" ""))
19198    (match_scratch:QI 2 "q")]
19199   "! optimize_size && ! TARGET_PUSH_MEMORY"
19200   [(set (match_dup 2) (match_dup 1))
19201    (set (match_dup 0) (match_dup 2))]
19202   "")
19204 ;; Don't move an immediate directly to memory when the instruction
19205 ;; gets too big.
19206 (define_peephole2
19207   [(match_scratch:SI 1 "r")
19208    (set (match_operand:SI 0 "memory_operand" "")
19209         (const_int 0))]
19210   "! optimize_size
19211    && ! TARGET_USE_MOV0
19212    && TARGET_SPLIT_LONG_MOVES
19213    && get_attr_length (insn) >= ix86_cost->large_insn
19214    && peep2_regno_dead_p (0, FLAGS_REG)"
19215   [(parallel [(set (match_dup 1) (const_int 0))
19216               (clobber (reg:CC FLAGS_REG))])
19217    (set (match_dup 0) (match_dup 1))]
19218   "")
19220 (define_peephole2
19221   [(match_scratch:HI 1 "r")
19222    (set (match_operand:HI 0 "memory_operand" "")
19223         (const_int 0))]
19224   "! optimize_size
19225    && ! TARGET_USE_MOV0
19226    && TARGET_SPLIT_LONG_MOVES
19227    && get_attr_length (insn) >= ix86_cost->large_insn
19228    && peep2_regno_dead_p (0, FLAGS_REG)"
19229   [(parallel [(set (match_dup 2) (const_int 0))
19230               (clobber (reg:CC FLAGS_REG))])
19231    (set (match_dup 0) (match_dup 1))]
19232   "operands[2] = gen_lowpart (SImode, operands[1]);")
19234 (define_peephole2
19235   [(match_scratch:QI 1 "q")
19236    (set (match_operand:QI 0 "memory_operand" "")
19237         (const_int 0))]
19238   "! optimize_size
19239    && ! TARGET_USE_MOV0
19240    && TARGET_SPLIT_LONG_MOVES
19241    && get_attr_length (insn) >= ix86_cost->large_insn
19242    && peep2_regno_dead_p (0, FLAGS_REG)"
19243   [(parallel [(set (match_dup 2) (const_int 0))
19244               (clobber (reg:CC FLAGS_REG))])
19245    (set (match_dup 0) (match_dup 1))]
19246   "operands[2] = gen_lowpart (SImode, operands[1]);")
19248 (define_peephole2
19249   [(match_scratch:SI 2 "r")
19250    (set (match_operand:SI 0 "memory_operand" "")
19251         (match_operand:SI 1 "immediate_operand" ""))]
19252   "! optimize_size
19253    && get_attr_length (insn) >= ix86_cost->large_insn
19254    && TARGET_SPLIT_LONG_MOVES"
19255   [(set (match_dup 2) (match_dup 1))
19256    (set (match_dup 0) (match_dup 2))]
19257   "")
19259 (define_peephole2
19260   [(match_scratch:HI 2 "r")
19261    (set (match_operand:HI 0 "memory_operand" "")
19262         (match_operand:HI 1 "immediate_operand" ""))]
19263   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19264   && TARGET_SPLIT_LONG_MOVES"
19265   [(set (match_dup 2) (match_dup 1))
19266    (set (match_dup 0) (match_dup 2))]
19267   "")
19269 (define_peephole2
19270   [(match_scratch:QI 2 "q")
19271    (set (match_operand:QI 0 "memory_operand" "")
19272         (match_operand:QI 1 "immediate_operand" ""))]
19273   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19274   && TARGET_SPLIT_LONG_MOVES"
19275   [(set (match_dup 2) (match_dup 1))
19276    (set (match_dup 0) (match_dup 2))]
19277   "")
19279 ;; Don't compare memory with zero, load and use a test instead.
19280 (define_peephole2
19281   [(set (match_operand 0 "flags_reg_operand" "")
19282         (match_operator 1 "compare_operator"
19283           [(match_operand:SI 2 "memory_operand" "")
19284            (const_int 0)]))
19285    (match_scratch:SI 3 "r")]
19286   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19287   [(set (match_dup 3) (match_dup 2))
19288    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19289   "")
19291 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19292 ;; Don't split NOTs with a displacement operand, because resulting XOR
19293 ;; will not be pairable anyway.
19295 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19296 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19297 ;; so this split helps here as well.
19299 ;; Note: Can't do this as a regular split because we can't get proper
19300 ;; lifetime information then.
19302 (define_peephole2
19303   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19304         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19305   "!optimize_size
19306    && peep2_regno_dead_p (0, FLAGS_REG)
19307    && ((TARGET_PENTIUM 
19308         && (GET_CODE (operands[0]) != MEM
19309             || !memory_displacement_operand (operands[0], SImode)))
19310        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19311   [(parallel [(set (match_dup 0)
19312                    (xor:SI (match_dup 1) (const_int -1)))
19313               (clobber (reg:CC FLAGS_REG))])]
19314   "")
19316 (define_peephole2
19317   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19318         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19319   "!optimize_size
19320    && peep2_regno_dead_p (0, FLAGS_REG)
19321    && ((TARGET_PENTIUM 
19322         && (GET_CODE (operands[0]) != MEM
19323             || !memory_displacement_operand (operands[0], HImode)))
19324        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19325   [(parallel [(set (match_dup 0)
19326                    (xor:HI (match_dup 1) (const_int -1)))
19327               (clobber (reg:CC FLAGS_REG))])]
19328   "")
19330 (define_peephole2
19331   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19332         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19333   "!optimize_size
19334    && peep2_regno_dead_p (0, FLAGS_REG)
19335    && ((TARGET_PENTIUM 
19336         && (GET_CODE (operands[0]) != MEM
19337             || !memory_displacement_operand (operands[0], QImode)))
19338        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19339   [(parallel [(set (match_dup 0)
19340                    (xor:QI (match_dup 1) (const_int -1)))
19341               (clobber (reg:CC FLAGS_REG))])]
19342   "")
19344 ;; Non pairable "test imm, reg" instructions can be translated to
19345 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19346 ;; byte opcode instead of two, have a short form for byte operands),
19347 ;; so do it for other CPUs as well.  Given that the value was dead,
19348 ;; this should not create any new dependencies.  Pass on the sub-word
19349 ;; versions if we're concerned about partial register stalls.
19351 (define_peephole2
19352   [(set (match_operand 0 "flags_reg_operand" "")
19353         (match_operator 1 "compare_operator"
19354           [(and:SI (match_operand:SI 2 "register_operand" "")
19355                    (match_operand:SI 3 "immediate_operand" ""))
19356            (const_int 0)]))]
19357   "ix86_match_ccmode (insn, CCNOmode)
19358    && (true_regnum (operands[2]) != 0
19359        || satisfies_constraint_K (operands[3]))
19360    && peep2_reg_dead_p (1, operands[2])"
19361   [(parallel
19362      [(set (match_dup 0)
19363            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19364                             (const_int 0)]))
19365       (set (match_dup 2)
19366            (and:SI (match_dup 2) (match_dup 3)))])]
19367   "")
19369 ;; We don't need to handle HImode case, because it will be promoted to SImode
19370 ;; on ! TARGET_PARTIAL_REG_STALL
19372 (define_peephole2
19373   [(set (match_operand 0 "flags_reg_operand" "")
19374         (match_operator 1 "compare_operator"
19375           [(and:QI (match_operand:QI 2 "register_operand" "")
19376                    (match_operand:QI 3 "immediate_operand" ""))
19377            (const_int 0)]))]
19378   "! TARGET_PARTIAL_REG_STALL
19379    && ix86_match_ccmode (insn, CCNOmode)
19380    && true_regnum (operands[2]) != 0
19381    && peep2_reg_dead_p (1, operands[2])"
19382   [(parallel
19383      [(set (match_dup 0)
19384            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19385                             (const_int 0)]))
19386       (set (match_dup 2)
19387            (and:QI (match_dup 2) (match_dup 3)))])]
19388   "")
19390 (define_peephole2
19391   [(set (match_operand 0 "flags_reg_operand" "")
19392         (match_operator 1 "compare_operator"
19393           [(and:SI
19394              (zero_extract:SI
19395                (match_operand 2 "ext_register_operand" "")
19396                (const_int 8)
19397                (const_int 8))
19398              (match_operand 3 "const_int_operand" ""))
19399            (const_int 0)]))]
19400   "! TARGET_PARTIAL_REG_STALL
19401    && ix86_match_ccmode (insn, CCNOmode)
19402    && true_regnum (operands[2]) != 0
19403    && peep2_reg_dead_p (1, operands[2])"
19404   [(parallel [(set (match_dup 0)
19405                    (match_op_dup 1
19406                      [(and:SI
19407                         (zero_extract:SI
19408                           (match_dup 2)
19409                           (const_int 8)
19410                           (const_int 8))
19411                         (match_dup 3))
19412                       (const_int 0)]))
19413               (set (zero_extract:SI (match_dup 2)
19414                                     (const_int 8)
19415                                     (const_int 8))
19416                    (and:SI 
19417                      (zero_extract:SI
19418                        (match_dup 2)
19419                        (const_int 8)
19420                        (const_int 8))
19421                      (match_dup 3)))])]
19422   "")
19424 ;; Don't do logical operations with memory inputs.
19425 (define_peephole2
19426   [(match_scratch:SI 2 "r")
19427    (parallel [(set (match_operand:SI 0 "register_operand" "")
19428                    (match_operator:SI 3 "arith_or_logical_operator"
19429                      [(match_dup 0)
19430                       (match_operand:SI 1 "memory_operand" "")]))
19431               (clobber (reg:CC FLAGS_REG))])]
19432   "! optimize_size && ! TARGET_READ_MODIFY"
19433   [(set (match_dup 2) (match_dup 1))
19434    (parallel [(set (match_dup 0)
19435                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19436               (clobber (reg:CC FLAGS_REG))])]
19437   "")
19439 (define_peephole2
19440   [(match_scratch:SI 2 "r")
19441    (parallel [(set (match_operand:SI 0 "register_operand" "")
19442                    (match_operator:SI 3 "arith_or_logical_operator"
19443                      [(match_operand:SI 1 "memory_operand" "")
19444                       (match_dup 0)]))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   "! optimize_size && ! TARGET_READ_MODIFY"
19447   [(set (match_dup 2) (match_dup 1))
19448    (parallel [(set (match_dup 0)
19449                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19450               (clobber (reg:CC FLAGS_REG))])]
19451   "")
19453 ; Don't do logical operations with memory outputs
19455 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19456 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19457 ; the same decoder scheduling characteristics as the original.
19459 (define_peephole2
19460   [(match_scratch:SI 2 "r")
19461    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19462                    (match_operator:SI 3 "arith_or_logical_operator"
19463                      [(match_dup 0)
19464                       (match_operand:SI 1 "nonmemory_operand" "")]))
19465               (clobber (reg:CC FLAGS_REG))])]
19466   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19467   [(set (match_dup 2) (match_dup 0))
19468    (parallel [(set (match_dup 2)
19469                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19470               (clobber (reg:CC FLAGS_REG))])
19471    (set (match_dup 0) (match_dup 2))]
19472   "")
19474 (define_peephole2
19475   [(match_scratch:SI 2 "r")
19476    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19477                    (match_operator:SI 3 "arith_or_logical_operator"
19478                      [(match_operand:SI 1 "nonmemory_operand" "")
19479                       (match_dup 0)]))
19480               (clobber (reg:CC FLAGS_REG))])]
19481   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19482   [(set (match_dup 2) (match_dup 0))
19483    (parallel [(set (match_dup 2)
19484                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19485               (clobber (reg:CC FLAGS_REG))])
19486    (set (match_dup 0) (match_dup 2))]
19487   "")
19489 ;; Attempt to always use XOR for zeroing registers.
19490 (define_peephole2
19491   [(set (match_operand 0 "register_operand" "")
19492         (match_operand 1 "const0_operand" ""))]
19493   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19494    && (! TARGET_USE_MOV0 || optimize_size)
19495    && GENERAL_REG_P (operands[0])
19496    && peep2_regno_dead_p (0, FLAGS_REG)"
19497   [(parallel [(set (match_dup 0) (const_int 0))
19498               (clobber (reg:CC FLAGS_REG))])]
19500   operands[0] = gen_lowpart (word_mode, operands[0]);
19503 (define_peephole2
19504   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19505         (const_int 0))]
19506   "(GET_MODE (operands[0]) == QImode
19507     || GET_MODE (operands[0]) == HImode)
19508    && (! TARGET_USE_MOV0 || optimize_size)
19509    && peep2_regno_dead_p (0, FLAGS_REG)"
19510   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19511               (clobber (reg:CC FLAGS_REG))])])
19513 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19514 (define_peephole2
19515   [(set (match_operand 0 "register_operand" "")
19516         (const_int -1))]
19517   "(GET_MODE (operands[0]) == HImode
19518     || GET_MODE (operands[0]) == SImode 
19519     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19520    && (optimize_size || TARGET_PENTIUM)
19521    && peep2_regno_dead_p (0, FLAGS_REG)"
19522   [(parallel [(set (match_dup 0) (const_int -1))
19523               (clobber (reg:CC FLAGS_REG))])]
19524   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19525                               operands[0]);")
19527 ;; Attempt to convert simple leas to adds. These can be created by
19528 ;; move expanders.
19529 (define_peephole2
19530   [(set (match_operand:SI 0 "register_operand" "")
19531         (plus:SI (match_dup 0)
19532                  (match_operand:SI 1 "nonmemory_operand" "")))]
19533   "peep2_regno_dead_p (0, FLAGS_REG)"
19534   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19535               (clobber (reg:CC FLAGS_REG))])]
19536   "")
19538 (define_peephole2
19539   [(set (match_operand:SI 0 "register_operand" "")
19540         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19541                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19542   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19543   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19544               (clobber (reg:CC FLAGS_REG))])]
19545   "operands[2] = gen_lowpart (SImode, operands[2]);")
19547 (define_peephole2
19548   [(set (match_operand:DI 0 "register_operand" "")
19549         (plus:DI (match_dup 0)
19550                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19551   "peep2_regno_dead_p (0, FLAGS_REG)"
19552   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19553               (clobber (reg:CC FLAGS_REG))])]
19554   "")
19556 (define_peephole2
19557   [(set (match_operand:SI 0 "register_operand" "")
19558         (mult:SI (match_dup 0)
19559                  (match_operand:SI 1 "const_int_operand" "")))]
19560   "exact_log2 (INTVAL (operands[1])) >= 0
19561    && peep2_regno_dead_p (0, FLAGS_REG)"
19562   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19563               (clobber (reg:CC FLAGS_REG))])]
19564   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19566 (define_peephole2
19567   [(set (match_operand:DI 0 "register_operand" "")
19568         (mult:DI (match_dup 0)
19569                  (match_operand:DI 1 "const_int_operand" "")))]
19570   "exact_log2 (INTVAL (operands[1])) >= 0
19571    && peep2_regno_dead_p (0, FLAGS_REG)"
19572   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19573               (clobber (reg:CC FLAGS_REG))])]
19574   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19576 (define_peephole2
19577   [(set (match_operand:SI 0 "register_operand" "")
19578         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19579                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19580   "exact_log2 (INTVAL (operands[2])) >= 0
19581    && REGNO (operands[0]) == REGNO (operands[1])
19582    && peep2_regno_dead_p (0, FLAGS_REG)"
19583   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19584               (clobber (reg:CC FLAGS_REG))])]
19585   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19587 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19588 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19589 ;; many CPUs it is also faster, since special hardware to avoid esp
19590 ;; dependencies is present.
19592 ;; While some of these conversions may be done using splitters, we use peepholes
19593 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19595 ;; Convert prologue esp subtractions to push.
19596 ;; We need register to push.  In order to keep verify_flow_info happy we have
19597 ;; two choices
19598 ;; - use scratch and clobber it in order to avoid dependencies
19599 ;; - use already live register
19600 ;; We can't use the second way right now, since there is no reliable way how to
19601 ;; verify that given register is live.  First choice will also most likely in
19602 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19603 ;; call clobbered registers are dead.  We may want to use base pointer as an
19604 ;; alternative when no register is available later.
19606 (define_peephole2
19607   [(match_scratch:SI 0 "r")
19608    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19609               (clobber (reg:CC FLAGS_REG))
19610               (clobber (mem:BLK (scratch)))])]
19611   "optimize_size || !TARGET_SUB_ESP_4"
19612   [(clobber (match_dup 0))
19613    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19614               (clobber (mem:BLK (scratch)))])])
19616 (define_peephole2
19617   [(match_scratch:SI 0 "r")
19618    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19619               (clobber (reg:CC FLAGS_REG))
19620               (clobber (mem:BLK (scratch)))])]
19621   "optimize_size || !TARGET_SUB_ESP_8"
19622   [(clobber (match_dup 0))
19623    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19624    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19625               (clobber (mem:BLK (scratch)))])])
19627 ;; Convert esp subtractions to push.
19628 (define_peephole2
19629   [(match_scratch:SI 0 "r")
19630    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19631               (clobber (reg:CC FLAGS_REG))])]
19632   "optimize_size || !TARGET_SUB_ESP_4"
19633   [(clobber (match_dup 0))
19634    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19636 (define_peephole2
19637   [(match_scratch:SI 0 "r")
19638    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19639               (clobber (reg:CC FLAGS_REG))])]
19640   "optimize_size || !TARGET_SUB_ESP_8"
19641   [(clobber (match_dup 0))
19642    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19643    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19645 ;; Convert epilogue deallocator to pop.
19646 (define_peephole2
19647   [(match_scratch:SI 0 "r")
19648    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19649               (clobber (reg:CC FLAGS_REG))
19650               (clobber (mem:BLK (scratch)))])]
19651   "optimize_size || !TARGET_ADD_ESP_4"
19652   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19653               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19654               (clobber (mem:BLK (scratch)))])]
19655   "")
19657 ;; Two pops case is tricky, since pop causes dependency on destination register.
19658 ;; We use two registers if available.
19659 (define_peephole2
19660   [(match_scratch:SI 0 "r")
19661    (match_scratch:SI 1 "r")
19662    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19663               (clobber (reg:CC FLAGS_REG))
19664               (clobber (mem:BLK (scratch)))])]
19665   "optimize_size || !TARGET_ADD_ESP_8"
19666   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19667               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19668               (clobber (mem:BLK (scratch)))])
19669    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19670               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19671   "")
19673 (define_peephole2
19674   [(match_scratch:SI 0 "r")
19675    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19676               (clobber (reg:CC FLAGS_REG))
19677               (clobber (mem:BLK (scratch)))])]
19678   "optimize_size"
19679   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19680               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19681               (clobber (mem:BLK (scratch)))])
19682    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19683               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19684   "")
19686 ;; Convert esp additions to pop.
19687 (define_peephole2
19688   [(match_scratch:SI 0 "r")
19689    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19690               (clobber (reg:CC FLAGS_REG))])]
19691   ""
19692   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19693               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19694   "")
19696 ;; Two pops case is tricky, since pop causes dependency on destination register.
19697 ;; We use two registers if available.
19698 (define_peephole2
19699   [(match_scratch:SI 0 "r")
19700    (match_scratch:SI 1 "r")
19701    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19702               (clobber (reg:CC FLAGS_REG))])]
19703   ""
19704   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19705               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19706    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19707               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19708   "")
19710 (define_peephole2
19711   [(match_scratch:SI 0 "r")
19712    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19713               (clobber (reg:CC FLAGS_REG))])]
19714   "optimize_size"
19715   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19716               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19717    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19718               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19719   "")
19721 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19722 ;; required and register dies.  Similarly for 128 to plus -128.
19723 (define_peephole2
19724   [(set (match_operand 0 "flags_reg_operand" "")
19725         (match_operator 1 "compare_operator"
19726           [(match_operand 2 "register_operand" "")
19727            (match_operand 3 "const_int_operand" "")]))]
19728   "(INTVAL (operands[3]) == -1
19729     || INTVAL (operands[3]) == 1
19730     || INTVAL (operands[3]) == 128)
19731    && ix86_match_ccmode (insn, CCGCmode)
19732    && peep2_reg_dead_p (1, operands[2])"
19733   [(parallel [(set (match_dup 0)
19734                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19735               (clobber (match_dup 2))])]
19736   "")
19738 (define_peephole2
19739   [(match_scratch:DI 0 "r")
19740    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19741               (clobber (reg:CC FLAGS_REG))
19742               (clobber (mem:BLK (scratch)))])]
19743   "optimize_size || !TARGET_SUB_ESP_4"
19744   [(clobber (match_dup 0))
19745    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19746               (clobber (mem:BLK (scratch)))])])
19748 (define_peephole2
19749   [(match_scratch:DI 0 "r")
19750    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19751               (clobber (reg:CC FLAGS_REG))
19752               (clobber (mem:BLK (scratch)))])]
19753   "optimize_size || !TARGET_SUB_ESP_8"
19754   [(clobber (match_dup 0))
19755    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19756    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19757               (clobber (mem:BLK (scratch)))])])
19759 ;; Convert esp subtractions to push.
19760 (define_peephole2
19761   [(match_scratch:DI 0 "r")
19762    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19763               (clobber (reg:CC FLAGS_REG))])]
19764   "optimize_size || !TARGET_SUB_ESP_4"
19765   [(clobber (match_dup 0))
19766    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19768 (define_peephole2
19769   [(match_scratch:DI 0 "r")
19770    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19771               (clobber (reg:CC FLAGS_REG))])]
19772   "optimize_size || !TARGET_SUB_ESP_8"
19773   [(clobber (match_dup 0))
19774    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19775    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19777 ;; Convert epilogue deallocator to pop.
19778 (define_peephole2
19779   [(match_scratch:DI 0 "r")
19780    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19781               (clobber (reg:CC FLAGS_REG))
19782               (clobber (mem:BLK (scratch)))])]
19783   "optimize_size || !TARGET_ADD_ESP_4"
19784   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19785               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19786               (clobber (mem:BLK (scratch)))])]
19787   "")
19789 ;; Two pops case is tricky, since pop causes dependency on destination register.
19790 ;; We use two registers if available.
19791 (define_peephole2
19792   [(match_scratch:DI 0 "r")
19793    (match_scratch:DI 1 "r")
19794    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19795               (clobber (reg:CC FLAGS_REG))
19796               (clobber (mem:BLK (scratch)))])]
19797   "optimize_size || !TARGET_ADD_ESP_8"
19798   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19799               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19800               (clobber (mem:BLK (scratch)))])
19801    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19802               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19803   "")
19805 (define_peephole2
19806   [(match_scratch:DI 0 "r")
19807    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19808               (clobber (reg:CC FLAGS_REG))
19809               (clobber (mem:BLK (scratch)))])]
19810   "optimize_size"
19811   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19812               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19813               (clobber (mem:BLK (scratch)))])
19814    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19815               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19816   "")
19818 ;; Convert esp additions to pop.
19819 (define_peephole2
19820   [(match_scratch:DI 0 "r")
19821    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19822               (clobber (reg:CC FLAGS_REG))])]
19823   ""
19824   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826   "")
19828 ;; Two pops case is tricky, since pop causes dependency on destination register.
19829 ;; We use two registers if available.
19830 (define_peephole2
19831   [(match_scratch:DI 0 "r")
19832    (match_scratch:DI 1 "r")
19833    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19834               (clobber (reg:CC FLAGS_REG))])]
19835   ""
19836   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19837               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19838    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19839               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19840   "")
19842 (define_peephole2
19843   [(match_scratch:DI 0 "r")
19844    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19845               (clobber (reg:CC FLAGS_REG))])]
19846   "optimize_size"
19847   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19848               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19849    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19850               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19851   "")
19853 ;; Convert imul by three, five and nine into lea
19854 (define_peephole2
19855   [(parallel
19856     [(set (match_operand:SI 0 "register_operand" "")
19857           (mult:SI (match_operand:SI 1 "register_operand" "")
19858                    (match_operand:SI 2 "const_int_operand" "")))
19859      (clobber (reg:CC FLAGS_REG))])]
19860   "INTVAL (operands[2]) == 3
19861    || INTVAL (operands[2]) == 5
19862    || INTVAL (operands[2]) == 9"
19863   [(set (match_dup 0)
19864         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19865                  (match_dup 1)))]
19866   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19868 (define_peephole2
19869   [(parallel
19870     [(set (match_operand:SI 0 "register_operand" "")
19871           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19872                    (match_operand:SI 2 "const_int_operand" "")))
19873      (clobber (reg:CC FLAGS_REG))])]
19874   "!optimize_size 
19875    && (INTVAL (operands[2]) == 3
19876        || INTVAL (operands[2]) == 5
19877        || INTVAL (operands[2]) == 9)"
19878   [(set (match_dup 0) (match_dup 1))
19879    (set (match_dup 0)
19880         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19881                  (match_dup 0)))]
19882   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19884 (define_peephole2
19885   [(parallel
19886     [(set (match_operand:DI 0 "register_operand" "")
19887           (mult:DI (match_operand:DI 1 "register_operand" "")
19888                    (match_operand:DI 2 "const_int_operand" "")))
19889      (clobber (reg:CC FLAGS_REG))])]
19890   "TARGET_64BIT
19891    && (INTVAL (operands[2]) == 3
19892        || INTVAL (operands[2]) == 5
19893        || INTVAL (operands[2]) == 9)"
19894   [(set (match_dup 0)
19895         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19896                  (match_dup 1)))]
19897   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19899 (define_peephole2
19900   [(parallel
19901     [(set (match_operand:DI 0 "register_operand" "")
19902           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19903                    (match_operand:DI 2 "const_int_operand" "")))
19904      (clobber (reg:CC FLAGS_REG))])]
19905   "TARGET_64BIT
19906    && !optimize_size 
19907    && (INTVAL (operands[2]) == 3
19908        || INTVAL (operands[2]) == 5
19909        || INTVAL (operands[2]) == 9)"
19910   [(set (match_dup 0) (match_dup 1))
19911    (set (match_dup 0)
19912         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19913                  (match_dup 0)))]
19914   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19916 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19917 ;; imul $32bit_imm, reg, reg is direct decoded.
19918 (define_peephole2
19919   [(match_scratch:DI 3 "r")
19920    (parallel [(set (match_operand:DI 0 "register_operand" "")
19921                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19922                             (match_operand:DI 2 "immediate_operand" "")))
19923               (clobber (reg:CC FLAGS_REG))])]
19924   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19925    && !satisfies_constraint_K (operands[2])"
19926   [(set (match_dup 3) (match_dup 1))
19927    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19928               (clobber (reg:CC FLAGS_REG))])]
19931 (define_peephole2
19932   [(match_scratch:SI 3 "r")
19933    (parallel [(set (match_operand:SI 0 "register_operand" "")
19934                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19935                             (match_operand:SI 2 "immediate_operand" "")))
19936               (clobber (reg:CC FLAGS_REG))])]
19937   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19938    && !satisfies_constraint_K (operands[2])"
19939   [(set (match_dup 3) (match_dup 1))
19940    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19941               (clobber (reg:CC FLAGS_REG))])]
19944 (define_peephole2
19945   [(match_scratch:SI 3 "r")
19946    (parallel [(set (match_operand:DI 0 "register_operand" "")
19947                    (zero_extend:DI
19948                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19949                               (match_operand:SI 2 "immediate_operand" ""))))
19950               (clobber (reg:CC FLAGS_REG))])]
19951   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19952    && !satisfies_constraint_K (operands[2])"
19953   [(set (match_dup 3) (match_dup 1))
19954    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19955               (clobber (reg:CC FLAGS_REG))])]
19958 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19959 ;; Convert it into imul reg, reg
19960 ;; It would be better to force assembler to encode instruction using long
19961 ;; immediate, but there is apparently no way to do so.
19962 (define_peephole2
19963   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19964                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19965                             (match_operand:DI 2 "const_int_operand" "")))
19966               (clobber (reg:CC FLAGS_REG))])
19967    (match_scratch:DI 3 "r")]
19968   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19969    && satisfies_constraint_K (operands[2])"
19970   [(set (match_dup 3) (match_dup 2))
19971    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19972               (clobber (reg:CC FLAGS_REG))])]
19974   if (!rtx_equal_p (operands[0], operands[1]))
19975     emit_move_insn (operands[0], operands[1]);
19978 (define_peephole2
19979   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19980                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19981                             (match_operand:SI 2 "const_int_operand" "")))
19982               (clobber (reg:CC FLAGS_REG))])
19983    (match_scratch:SI 3 "r")]
19984   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19985    && satisfies_constraint_K (operands[2])"
19986   [(set (match_dup 3) (match_dup 2))
19987    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19988               (clobber (reg:CC FLAGS_REG))])]
19990   if (!rtx_equal_p (operands[0], operands[1]))
19991     emit_move_insn (operands[0], operands[1]);
19994 (define_peephole2
19995   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19996                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19997                             (match_operand:HI 2 "immediate_operand" "")))
19998               (clobber (reg:CC FLAGS_REG))])
19999    (match_scratch:HI 3 "r")]
20000   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20001   [(set (match_dup 3) (match_dup 2))
20002    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20003               (clobber (reg:CC FLAGS_REG))])]
20005   if (!rtx_equal_p (operands[0], operands[1]))
20006     emit_move_insn (operands[0], operands[1]);
20009 ;; Call-value patterns last so that the wildcard operand does not
20010 ;; disrupt insn-recog's switch tables.
20012 (define_insn "*call_value_pop_0"
20013   [(set (match_operand 0 "" "")
20014         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20015               (match_operand:SI 2 "" "")))
20016    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20017                             (match_operand:SI 3 "immediate_operand" "")))]
20018   "!TARGET_64BIT"
20020   if (SIBLING_CALL_P (insn))
20021     return "jmp\t%P1";
20022   else
20023     return "call\t%P1";
20025   [(set_attr "type" "callv")])
20027 (define_insn "*call_value_pop_1"
20028   [(set (match_operand 0 "" "")
20029         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20030               (match_operand:SI 2 "" "")))
20031    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20032                             (match_operand:SI 3 "immediate_operand" "i")))]
20033   "!TARGET_64BIT"
20035   if (constant_call_address_operand (operands[1], Pmode))
20036     {
20037       if (SIBLING_CALL_P (insn))
20038         return "jmp\t%P1";
20039       else
20040         return "call\t%P1";
20041     }
20042   if (SIBLING_CALL_P (insn))
20043     return "jmp\t%A1";
20044   else
20045     return "call\t%A1";
20047   [(set_attr "type" "callv")])
20049 (define_insn "*call_value_0"
20050   [(set (match_operand 0 "" "")
20051         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20052               (match_operand:SI 2 "" "")))]
20053   "!TARGET_64BIT"
20055   if (SIBLING_CALL_P (insn))
20056     return "jmp\t%P1";
20057   else
20058     return "call\t%P1";
20060   [(set_attr "type" "callv")])
20062 (define_insn "*call_value_0_rex64"
20063   [(set (match_operand 0 "" "")
20064         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20065               (match_operand:DI 2 "const_int_operand" "")))]
20066   "TARGET_64BIT"
20068   if (SIBLING_CALL_P (insn))
20069     return "jmp\t%P1";
20070   else
20071     return "call\t%P1";
20073   [(set_attr "type" "callv")])
20075 (define_insn "*call_value_1"
20076   [(set (match_operand 0 "" "")
20077         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20078               (match_operand:SI 2 "" "")))]
20079   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20081   if (constant_call_address_operand (operands[1], Pmode))
20082     return "call\t%P1";
20083   return "call\t%A1";
20085   [(set_attr "type" "callv")])
20087 (define_insn "*sibcall_value_1"
20088   [(set (match_operand 0 "" "")
20089         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20090               (match_operand:SI 2 "" "")))]
20091   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20093   if (constant_call_address_operand (operands[1], Pmode))
20094     return "jmp\t%P1";
20095   return "jmp\t%A1";
20097   [(set_attr "type" "callv")])
20099 (define_insn "*call_value_1_rex64"
20100   [(set (match_operand 0 "" "")
20101         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20102               (match_operand:DI 2 "" "")))]
20103   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20105   if (constant_call_address_operand (operands[1], Pmode))
20106     return "call\t%P1";
20107   return "call\t%A1";
20109   [(set_attr "type" "callv")])
20111 (define_insn "*sibcall_value_1_rex64"
20112   [(set (match_operand 0 "" "")
20113         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20114               (match_operand:DI 2 "" "")))]
20115   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20116   "jmp\t%P1"
20117   [(set_attr "type" "callv")])
20119 (define_insn "*sibcall_value_1_rex64_v"
20120   [(set (match_operand 0 "" "")
20121         (call (mem:QI (reg:DI 40))
20122               (match_operand:DI 1 "" "")))]
20123   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20124   "jmp\t*%%r11"
20125   [(set_attr "type" "callv")])
20127 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20128 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20129 ;; caught for use by garbage collectors and the like.  Using an insn that
20130 ;; maps to SIGILL makes it more likely the program will rightfully die.
20131 ;; Keeping with tradition, "6" is in honor of #UD.
20132 (define_insn "trap"
20133   [(trap_if (const_int 1) (const_int 6))]
20134   ""
20135   { return ASM_SHORT "0x0b0f"; }
20136   [(set_attr "length" "2")])
20138 (define_expand "sse_prologue_save"
20139   [(parallel [(set (match_operand:BLK 0 "" "")
20140                    (unspec:BLK [(reg:DI 21)
20141                                 (reg:DI 22)
20142                                 (reg:DI 23)
20143                                 (reg:DI 24)
20144                                 (reg:DI 25)
20145                                 (reg:DI 26)
20146                                 (reg:DI 27)
20147                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20148               (use (match_operand:DI 1 "register_operand" ""))
20149               (use (match_operand:DI 2 "immediate_operand" ""))
20150               (use (label_ref:DI (match_operand 3 "" "")))])]
20151   "TARGET_64BIT"
20152   "")
20154 (define_insn "*sse_prologue_save_insn"
20155   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20156                           (match_operand:DI 4 "const_int_operand" "n")))
20157         (unspec:BLK [(reg:DI 21)
20158                      (reg:DI 22)
20159                      (reg:DI 23)
20160                      (reg:DI 24)
20161                      (reg:DI 25)
20162                      (reg:DI 26)
20163                      (reg:DI 27)
20164                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20165    (use (match_operand:DI 1 "register_operand" "r"))
20166    (use (match_operand:DI 2 "const_int_operand" "i"))
20167    (use (label_ref:DI (match_operand 3 "" "X")))]
20168   "TARGET_64BIT
20169    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20170    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20171   "*
20173   int i;
20174   operands[0] = gen_rtx_MEM (Pmode,
20175                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20176   output_asm_insn (\"jmp\\t%A1\", operands);
20177   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20178     {
20179       operands[4] = adjust_address (operands[0], DImode, i*16);
20180       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20181       PUT_MODE (operands[4], TImode);
20182       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20183         output_asm_insn (\"rex\", operands);
20184       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20185     }
20186   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20187                              CODE_LABEL_NUMBER (operands[3]));
20188   RET;
20190   "
20191   [(set_attr "type" "other")
20192    (set_attr "length_immediate" "0")
20193    (set_attr "length_address" "0")
20194    (set_attr "length" "135")
20195    (set_attr "memory" "store")
20196    (set_attr "modrm" "0")
20197    (set_attr "mode" "DI")])
20199 (define_expand "prefetch"
20200   [(prefetch (match_operand 0 "address_operand" "")
20201              (match_operand:SI 1 "const_int_operand" "")
20202              (match_operand:SI 2 "const_int_operand" ""))]
20203   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20205   int rw = INTVAL (operands[1]);
20206   int locality = INTVAL (operands[2]);
20208   gcc_assert (rw == 0 || rw == 1);
20209   gcc_assert (locality >= 0 && locality <= 3);
20210   gcc_assert (GET_MODE (operands[0]) == Pmode
20211               || GET_MODE (operands[0]) == VOIDmode);
20213   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20214      supported by SSE counterpart or the SSE prefetch is not available
20215      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20216      of locality.  */
20217   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20218     operands[2] = GEN_INT (3);
20219   else
20220     operands[1] = const0_rtx;
20223 (define_insn "*prefetch_sse"
20224   [(prefetch (match_operand:SI 0 "address_operand" "p")
20225              (const_int 0)
20226              (match_operand:SI 1 "const_int_operand" ""))]
20227   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20229   static const char * const patterns[4] = {
20230    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20231   };
20233   int locality = INTVAL (operands[1]);
20234   gcc_assert (locality >= 0 && locality <= 3);
20236   return patterns[locality];  
20238   [(set_attr "type" "sse")
20239    (set_attr "memory" "none")])
20241 (define_insn "*prefetch_sse_rex"
20242   [(prefetch (match_operand:DI 0 "address_operand" "p")
20243              (const_int 0)
20244              (match_operand:SI 1 "const_int_operand" ""))]
20245   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20247   static const char * const patterns[4] = {
20248    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20249   };
20251   int locality = INTVAL (operands[1]);
20252   gcc_assert (locality >= 0 && locality <= 3);
20254   return patterns[locality];  
20256   [(set_attr "type" "sse")
20257    (set_attr "memory" "none")])
20259 (define_insn "*prefetch_3dnow"
20260   [(prefetch (match_operand:SI 0 "address_operand" "p")
20261              (match_operand:SI 1 "const_int_operand" "n")
20262              (const_int 3))]
20263   "TARGET_3DNOW && !TARGET_64BIT"
20265   if (INTVAL (operands[1]) == 0)
20266     return "prefetch\t%a0";
20267   else
20268     return "prefetchw\t%a0";
20270   [(set_attr "type" "mmx")
20271    (set_attr "memory" "none")])
20273 (define_insn "*prefetch_3dnow_rex"
20274   [(prefetch (match_operand:DI 0 "address_operand" "p")
20275              (match_operand:SI 1 "const_int_operand" "n")
20276              (const_int 3))]
20277   "TARGET_3DNOW && TARGET_64BIT"
20279   if (INTVAL (operands[1]) == 0)
20280     return "prefetch\t%a0";
20281   else
20282     return "prefetchw\t%a0";
20284   [(set_attr "type" "mmx")
20285    (set_attr "memory" "none")])
20287 (define_expand "stack_protect_set"
20288   [(match_operand 0 "memory_operand" "")
20289    (match_operand 1 "memory_operand" "")]
20290   ""
20292 #ifdef TARGET_THREAD_SSP_OFFSET
20293   if (TARGET_64BIT)
20294     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20295                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20296   else
20297     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20298                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20299 #else
20300   if (TARGET_64BIT)
20301     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20302   else
20303     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20304 #endif
20305   DONE;
20308 (define_insn "stack_protect_set_si"
20309   [(set (match_operand:SI 0 "memory_operand" "=m")
20310         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20311    (set (match_scratch:SI 2 "=&r") (const_int 0))
20312    (clobber (reg:CC FLAGS_REG))]
20313   ""
20314   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20315   [(set_attr "type" "multi")])
20317 (define_insn "stack_protect_set_di"
20318   [(set (match_operand:DI 0 "memory_operand" "=m")
20319         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20320    (set (match_scratch:DI 2 "=&r") (const_int 0))
20321    (clobber (reg:CC FLAGS_REG))]
20322   "TARGET_64BIT"
20323   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20324   [(set_attr "type" "multi")])
20326 (define_insn "stack_tls_protect_set_si"
20327   [(set (match_operand:SI 0 "memory_operand" "=m")
20328         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20329    (set (match_scratch:SI 2 "=&r") (const_int 0))
20330    (clobber (reg:CC FLAGS_REG))]
20331   ""
20332   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20333   [(set_attr "type" "multi")])
20335 (define_insn "stack_tls_protect_set_di"
20336   [(set (match_operand:DI 0 "memory_operand" "=m")
20337         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20338    (set (match_scratch:DI 2 "=&r") (const_int 0))
20339    (clobber (reg:CC FLAGS_REG))]
20340   "TARGET_64BIT"
20341   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20342   [(set_attr "type" "multi")])
20344 (define_expand "stack_protect_test"
20345   [(match_operand 0 "memory_operand" "")
20346    (match_operand 1 "memory_operand" "")
20347    (match_operand 2 "" "")]
20348   ""
20350   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20351   ix86_compare_op0 = operands[0];
20352   ix86_compare_op1 = operands[1];
20353   ix86_compare_emitted = flags;
20355 #ifdef TARGET_THREAD_SSP_OFFSET
20356   if (TARGET_64BIT)
20357     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20358                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20359   else
20360     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20361                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20362 #else
20363   if (TARGET_64BIT)
20364     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20365   else
20366     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20367 #endif
20368   emit_jump_insn (gen_beq (operands[2]));
20369   DONE;
20372 (define_insn "stack_protect_test_si"
20373   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20374         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20375                      (match_operand:SI 2 "memory_operand" "m")]
20376                     UNSPEC_SP_TEST))
20377    (clobber (match_scratch:SI 3 "=&r"))]
20378   ""
20379   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20380   [(set_attr "type" "multi")])
20382 (define_insn "stack_protect_test_di"
20383   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20384         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20385                      (match_operand:DI 2 "memory_operand" "m")]
20386                     UNSPEC_SP_TEST))
20387    (clobber (match_scratch:DI 3 "=&r"))]
20388   "TARGET_64BIT"
20389   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20390   [(set_attr "type" "multi")])
20392 (define_insn "stack_tls_protect_test_si"
20393   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20394         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20395                      (match_operand:SI 2 "const_int_operand" "i")]
20396                     UNSPEC_SP_TLS_TEST))
20397    (clobber (match_scratch:SI 3 "=r"))]
20398   ""
20399   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20400   [(set_attr "type" "multi")])
20402 (define_insn "stack_tls_protect_test_di"
20403   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20404         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20405                      (match_operand:DI 2 "const_int_operand" "i")]
20406                     UNSPEC_SP_TLS_TEST))
20407    (clobber (match_scratch:DI 3 "=r"))]
20408   "TARGET_64BIT"
20409   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20410   [(set_attr "type" "multi")])
20412 (include "sse.md")
20413 (include "mmx.md")
20414 (include "sync.md")