PR target/24055
[official-gcc.git] / gcc / config / i386 / i386.md
blob8bfa037a8cc07e21c165c9718a3f263bc989e3a6
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
70    ; TLS support
71    (UNSPEC_TP                   15)
72    (UNSPEC_TLS_GD               16)
73    (UNSPEC_TLS_LD_BASE          17)
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
85    ; For SSE/MMX support:
86    (UNSPEC_FIX_NOTRUNC          30)
87    (UNSPEC_MASKMOV              31)
88    (UNSPEC_MOVMSK               32)
89    (UNSPEC_MOVNT                33)
90    (UNSPEC_MOVU                 34)
91    (UNSPEC_RCP                  35)
92    (UNSPEC_RSQRT                36)
93    (UNSPEC_SFENCE               37)
94    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
95    (UNSPEC_PFRCP                39)
96    (UNSPEC_PFRCPIT1             40)
97    (UNSPEC_PFRCPIT2             41)
98    (UNSPEC_PFRSQRT              42)
99    (UNSPEC_PFRSQIT1             43)
100    (UNSPEC_MFENCE               44)
101    (UNSPEC_LFENCE               45)
102    (UNSPEC_PSADBW               46)
103    (UNSPEC_LDQQU                47)
105    ; Generic math support
106    (UNSPEC_COPYSIGN             50)
107    (UNSPEC_IEEE_MIN             51)     ; not commutative
108    (UNSPEC_IEEE_MAX             52)     ; not commutative
110    ; x87 Floating point
111    (UNSPEC_SIN                  60)
112    (UNSPEC_COS                  61)
113    (UNSPEC_FPATAN               62)
114    (UNSPEC_FYL2X                63)
115    (UNSPEC_FYL2XP1              64)
116    (UNSPEC_FRNDINT              65)
117    (UNSPEC_FIST                 66)
118    (UNSPEC_F2XM1                67)
120    ; x87 Rounding
121    (UNSPEC_FRNDINT_FLOOR        70)
122    (UNSPEC_FRNDINT_CEIL         71)
123    (UNSPEC_FRNDINT_TRUNC        72)
124    (UNSPEC_FRNDINT_MASK_PM      73)
125    (UNSPEC_FIST_FLOOR           74)
126    (UNSPEC_FIST_CEIL            75)
128    ; x87 Double output FP
129    (UNSPEC_SINCOS_COS           80)
130    (UNSPEC_SINCOS_SIN           81)
131    (UNSPEC_TAN_ONE              82)
132    (UNSPEC_TAN_TAN              83)
133    (UNSPEC_XTRACT_FRACT         84)
134    (UNSPEC_XTRACT_EXP           85)
135    (UNSPEC_FSCALE_FRACT         86)
136    (UNSPEC_FSCALE_EXP           87)
137    (UNSPEC_FPREM_F              88)
138    (UNSPEC_FPREM_U              89)
139    (UNSPEC_FPREM1_F             90)
140    (UNSPEC_FPREM1_U             91)
142    ; SSP patterns
143    (UNSPEC_SP_SET               100)
144    (UNSPEC_SP_TEST              101)
145    (UNSPEC_SP_TLS_SET           102)
146    (UNSPEC_SP_TLS_TEST          103)
147   ])
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         1)
152    (UNSPECV_EMMS                2)
153    (UNSPECV_LDMXCSR             3)
154    (UNSPECV_STMXCSR             4)
155    (UNSPECV_FEMMS               5)
156    (UNSPECV_CLFLUSH             6)
157    (UNSPECV_ALIGN               7)
158    (UNSPECV_MONITOR             8)
159    (UNSPECV_MWAIT               9)
160    (UNSPECV_CMPXCHG_1           10)
161    (UNSPECV_CMPXCHG_2           11)
162    (UNSPECV_XCHG                12)
163    (UNSPECV_LOCK                13)
164   ])
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       gcc_unreachable (),1")))
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
415 ;; Indicates if an instruction has both an immediate and a displacement.
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
431 ;; Indicates if an FP operation has an integer source.
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
436 ;; Defines rounding mode of an FP operation.
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439   (const_string "any"))
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
462 ;; Scheduling descriptions
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
470 ;; Operand and operator predicates
472 (include "predicates.md")
475 ;; Compare instructions.
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
481 (define_expand "cmpti"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
484                     (match_operand:TI 1 "x86_64_general_operand" "")))]
485   "TARGET_64BIT"
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (TImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
494 (define_expand "cmpdi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
497                     (match_operand:DI 1 "x86_64_general_operand" "")))]
498   ""
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (DImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
507 (define_expand "cmpsi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
510                     (match_operand:SI 1 "general_operand" "")))]
511   ""
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (SImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
520 (define_expand "cmphi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
523                     (match_operand:HI 1 "general_operand" "")))]
524   ""
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (HImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
533 (define_expand "cmpqi"
534   [(set (reg:CC FLAGS_REG)
535         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
536                     (match_operand:QI 1 "general_operand" "")))]
537   "TARGET_QIMODE_MATH"
539   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
540     operands[0] = force_reg (QImode, operands[0]);
541   ix86_compare_op0 = operands[0];
542   ix86_compare_op1 = operands[1];
543   DONE;
546 (define_insn "cmpdi_ccno_1_rex64"
547   [(set (reg FLAGS_REG)
548         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
549                  (match_operand:DI 1 "const0_operand" "n,n")))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
551   "@
552    test{q}\t{%0, %0|%0, %0}
553    cmp{q}\t{%1, %0|%0, %1}"
554   [(set_attr "type" "test,icmp")
555    (set_attr "length_immediate" "0,1")
556    (set_attr "mode" "DI")])
558 (define_insn "*cmpdi_minus_1_rex64"
559   [(set (reg FLAGS_REG)
560         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
561                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
562                  (const_int 0)))]
563   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
564   "cmp{q}\t{%1, %0|%0, %1}"
565   [(set_attr "type" "icmp")
566    (set_attr "mode" "DI")])
568 (define_expand "cmpdi_1_rex64"
569   [(set (reg:CC FLAGS_REG)
570         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
571                     (match_operand:DI 1 "general_operand" "")))]
572   "TARGET_64BIT"
573   "")
575 (define_insn "cmpdi_1_insn_rex64"
576   [(set (reg FLAGS_REG)
577         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
578                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
579   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
580   "cmp{q}\t{%1, %0|%0, %1}"
581   [(set_attr "type" "icmp")
582    (set_attr "mode" "DI")])
585 (define_insn "*cmpsi_ccno_1"
586   [(set (reg FLAGS_REG)
587         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
588                  (match_operand:SI 1 "const0_operand" "n,n")))]
589   "ix86_match_ccmode (insn, CCNOmode)"
590   "@
591    test{l}\t{%0, %0|%0, %0}
592    cmp{l}\t{%1, %0|%0, %1}"
593   [(set_attr "type" "test,icmp")
594    (set_attr "length_immediate" "0,1")
595    (set_attr "mode" "SI")])
597 (define_insn "*cmpsi_minus_1"
598   [(set (reg FLAGS_REG)
599         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
600                            (match_operand:SI 1 "general_operand" "ri,mr"))
601                  (const_int 0)))]
602   "ix86_match_ccmode (insn, CCGOCmode)"
603   "cmp{l}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "SI")])
607 (define_expand "cmpsi_1"
608   [(set (reg:CC FLAGS_REG)
609         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610                     (match_operand:SI 1 "general_operand" "ri,mr")))]
611   ""
612   "")
614 (define_insn "*cmpsi_1_insn"
615   [(set (reg FLAGS_REG)
616         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                  (match_operand:SI 1 "general_operand" "ri,mr")))]
618   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619     && ix86_match_ccmode (insn, CCmode)"
620   "cmp{l}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "SI")])
624 (define_insn "*cmphi_ccno_1"
625   [(set (reg FLAGS_REG)
626         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
627                  (match_operand:HI 1 "const0_operand" "n,n")))]
628   "ix86_match_ccmode (insn, CCNOmode)"
629   "@
630    test{w}\t{%0, %0|%0, %0}
631    cmp{w}\t{%1, %0|%0, %1}"
632   [(set_attr "type" "test,icmp")
633    (set_attr "length_immediate" "0,1")
634    (set_attr "mode" "HI")])
636 (define_insn "*cmphi_minus_1"
637   [(set (reg FLAGS_REG)
638         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
639                            (match_operand:HI 1 "general_operand" "ri,mr"))
640                  (const_int 0)))]
641   "ix86_match_ccmode (insn, CCGOCmode)"
642   "cmp{w}\t{%1, %0|%0, %1}"
643   [(set_attr "type" "icmp")
644    (set_attr "mode" "HI")])
646 (define_insn "*cmphi_1"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:HI 1 "general_operand" "ri,mr")))]
650   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
651    && ix86_match_ccmode (insn, CCmode)"
652   "cmp{w}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "HI")])
656 (define_insn "*cmpqi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
659                  (match_operand:QI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{b}\t{%0, %0|%0, %0}
663    cmp{b}\t{$0, %0|%0, 0}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "QI")])
668 (define_insn "*cmpqi_1"
669   [(set (reg FLAGS_REG)
670         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
671                  (match_operand:QI 1 "general_operand" "qi,mq")))]
672   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
673     && ix86_match_ccmode (insn, CCmode)"
674   "cmp{b}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "QI")])
678 (define_insn "*cmpqi_minus_1"
679   [(set (reg FLAGS_REG)
680         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681                            (match_operand:QI 1 "general_operand" "qi,mq"))
682                  (const_int 0)))]
683   "ix86_match_ccmode (insn, CCGOCmode)"
684   "cmp{b}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "QI")])
688 (define_insn "*cmpqi_ext_1"
689   [(set (reg FLAGS_REG)
690         (compare
691           (match_operand:QI 0 "general_operand" "Qm")
692           (subreg:QI
693             (zero_extract:SI
694               (match_operand 1 "ext_register_operand" "Q")
695               (const_int 8)
696               (const_int 8)) 0)))]
697   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%h1, %0|%0, %h1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_ext_1_rex64"
703   [(set (reg FLAGS_REG)
704         (compare
705           (match_operand:QI 0 "register_operand" "Q")
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 1 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)))]
711   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712   "cmp{b}\t{%h1, %0|%0, %h1}"
713   [(set_attr "type" "icmp")
714    (set_attr "mode" "QI")])
716 (define_insn "*cmpqi_ext_2"
717   [(set (reg FLAGS_REG)
718         (compare
719           (subreg:QI
720             (zero_extract:SI
721               (match_operand 0 "ext_register_operand" "Q")
722               (const_int 8)
723               (const_int 8)) 0)
724           (match_operand:QI 1 "const0_operand" "n")))]
725   "ix86_match_ccmode (insn, CCNOmode)"
726   "test{b}\t%h0, %h0"
727   [(set_attr "type" "test")
728    (set_attr "length_immediate" "0")
729    (set_attr "mode" "QI")])
731 (define_expand "cmpqi_ext_3"
732   [(set (reg:CC FLAGS_REG)
733         (compare:CC
734           (subreg:QI
735             (zero_extract:SI
736               (match_operand 0 "ext_register_operand" "")
737               (const_int 8)
738               (const_int 8)) 0)
739           (match_operand:QI 1 "general_operand" "")))]
740   ""
741   "")
743 (define_insn "cmpqi_ext_3_insn"
744   [(set (reg FLAGS_REG)
745         (compare
746           (subreg:QI
747             (zero_extract:SI
748               (match_operand 0 "ext_register_operand" "Q")
749               (const_int 8)
750               (const_int 8)) 0)
751           (match_operand:QI 1 "general_operand" "Qmn")))]
752   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753   "cmp{b}\t{%1, %h0|%h0, %1}"
754   [(set_attr "type" "icmp")
755    (set_attr "mode" "QI")])
757 (define_insn "cmpqi_ext_3_insn_rex64"
758   [(set (reg FLAGS_REG)
759         (compare
760           (subreg:QI
761             (zero_extract:SI
762               (match_operand 0 "ext_register_operand" "Q")
763               (const_int 8)
764               (const_int 8)) 0)
765           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
766   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767   "cmp{b}\t{%1, %h0|%h0, %1}"
768   [(set_attr "type" "icmp")
769    (set_attr "mode" "QI")])
771 (define_insn "*cmpqi_ext_4"
772   [(set (reg FLAGS_REG)
773         (compare
774           (subreg:QI
775             (zero_extract:SI
776               (match_operand 0 "ext_register_operand" "Q")
777               (const_int 8)
778               (const_int 8)) 0)
779           (subreg:QI
780             (zero_extract:SI
781               (match_operand 1 "ext_register_operand" "Q")
782               (const_int 8)
783               (const_int 8)) 0)))]
784   "ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%h1, %h0|%h0, %h1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
789 ;; These implement float point compares.
790 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
791 ;; which would allow mix and match FP modes on the compares.  Which is what
792 ;; the old patterns did, but with many more of them.
794 (define_expand "cmpxf"
795   [(set (reg:CC FLAGS_REG)
796         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
797                     (match_operand:XF 1 "nonmemory_operand" "")))]
798   "TARGET_80387"
800   ix86_compare_op0 = operands[0];
801   ix86_compare_op1 = operands[1];
802   DONE;
805 (define_expand "cmpdf"
806   [(set (reg:CC FLAGS_REG)
807         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
808                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
809   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
811   ix86_compare_op0 = operands[0];
812   ix86_compare_op1 = operands[1];
813   DONE;
816 (define_expand "cmpsf"
817   [(set (reg:CC FLAGS_REG)
818         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
819                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
820   "TARGET_80387 || TARGET_SSE_MATH"
822   ix86_compare_op0 = operands[0];
823   ix86_compare_op1 = operands[1];
824   DONE;
827 ;; FP compares, step 1:
828 ;; Set the FP condition codes.
830 ;; CCFPmode     compare with exceptions
831 ;; CCFPUmode    compare with no exceptions
833 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
834 ;; used to manage the reg stack popping would not be preserved.
836 (define_insn "*cmpfp_0"
837   [(set (match_operand:HI 0 "register_operand" "=a")
838         (unspec:HI
839           [(compare:CCFP
840              (match_operand 1 "register_operand" "f")
841              (match_operand 2 "const0_operand" "X"))]
842         UNSPEC_FNSTSW))]
843   "TARGET_80387
844    && FLOAT_MODE_P (GET_MODE (operands[1]))
845    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
846   "* return output_fp_compare (insn, operands, 0, 0);"
847   [(set_attr "type" "multi")
848    (set_attr "unit" "i387")
849    (set (attr "mode")
850      (cond [(match_operand:SF 1 "" "")
851               (const_string "SF")
852             (match_operand:DF 1 "" "")
853               (const_string "DF")
854            ]
855            (const_string "XF")))])
857 (define_insn "*cmpfp_sf"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:SF 1 "register_operand" "f")
862              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 0, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "unit" "i387")
868    (set_attr "mode" "SF")])
870 (define_insn "*cmpfp_df"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:DF 1 "register_operand" "f")
875              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set_attr "mode" "DF")])
883 (define_insn "*cmpfp_xf"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFP
887              (match_operand:XF 1 "register_operand" "f")
888              (match_operand:XF 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387"
891   "* return output_fp_compare (insn, operands, 0, 0);"
892   [(set_attr "type" "multi")
893    (set_attr "unit" "i387")
894    (set_attr "mode" "XF")])
896 (define_insn "*cmpfp_u"
897   [(set (match_operand:HI 0 "register_operand" "=a")
898         (unspec:HI
899           [(compare:CCFPU
900              (match_operand 1 "register_operand" "f")
901              (match_operand 2 "register_operand" "f"))]
902           UNSPEC_FNSTSW))]
903   "TARGET_80387
904    && FLOAT_MODE_P (GET_MODE (operands[1]))
905    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
906   "* return output_fp_compare (insn, operands, 0, 1);"
907   [(set_attr "type" "multi")
908    (set_attr "unit" "i387")
909    (set (attr "mode")
910      (cond [(match_operand:SF 1 "" "")
911               (const_string "SF")
912             (match_operand:DF 1 "" "")
913               (const_string "DF")
914            ]
915            (const_string "XF")))])
917 (define_insn "*cmpfp_<mode>"
918   [(set (match_operand:HI 0 "register_operand" "=a")
919         (unspec:HI
920           [(compare:CCFP
921              (match_operand 1 "register_operand" "f")
922              (match_operator 3 "float_operator"
923                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
924           UNSPEC_FNSTSW))]
925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
926    && FLOAT_MODE_P (GET_MODE (operands[1]))
927    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
928   "* return output_fp_compare (insn, operands, 0, 0);"
929   [(set_attr "type" "multi")
930    (set_attr "unit" "i387")
931    (set_attr "fp_int_src" "true")
932    (set_attr "mode" "<MODE>")])
934 ;; FP compares, step 2
935 ;; Move the fpsw to ax.
937 (define_insn "x86_fnstsw_1"
938   [(set (match_operand:HI 0 "register_operand" "=a")
939         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
940   "TARGET_80387"
941   "fnstsw\t%0"
942   [(set_attr "length" "2")
943    (set_attr "mode" "SI")
944    (set_attr "unit" "i387")])
946 ;; FP compares, step 3
947 ;; Get ax into flags, general case.
949 (define_insn "x86_sahf_1"
950   [(set (reg:CC FLAGS_REG)
951         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
952   "!TARGET_64BIT"
953   "sahf"
954   [(set_attr "length" "1")
955    (set_attr "athlon_decode" "vector")
956    (set_attr "mode" "SI")])
958 ;; Pentium Pro can do steps 1 through 3 in one go.
960 (define_insn "*cmpfp_i_mixed"
961   [(set (reg:CCFP FLAGS_REG)
962         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
963                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
964   "TARGET_MIX_SSE_I387
965    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
967   "* return output_fp_compare (insn, operands, 1, 0);"
968   [(set_attr "type" "fcmp,ssecomi")
969    (set (attr "mode")
970      (if_then_else (match_operand:SF 1 "" "")
971         (const_string "SF")
972         (const_string "DF")))
973    (set_attr "athlon_decode" "vector")])
975 (define_insn "*cmpfp_i_sse"
976   [(set (reg:CCFP FLAGS_REG)
977         (compare:CCFP (match_operand 0 "register_operand" "x")
978                       (match_operand 1 "nonimmediate_operand" "xm")))]
979   "TARGET_SSE_MATH
980    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982   "* return output_fp_compare (insn, operands, 1, 0);"
983   [(set_attr "type" "ssecomi")
984    (set (attr "mode")
985      (if_then_else (match_operand:SF 1 "" "")
986         (const_string "SF")
987         (const_string "DF")))
988    (set_attr "athlon_decode" "vector")])
990 (define_insn "*cmpfp_i_i387"
991   [(set (reg:CCFP FLAGS_REG)
992         (compare:CCFP (match_operand 0 "register_operand" "f")
993                       (match_operand 1 "register_operand" "f")))]
994   "TARGET_80387 && TARGET_CMOVE
995    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
996    && FLOAT_MODE_P (GET_MODE (operands[0]))
997    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
998   "* return output_fp_compare (insn, operands, 1, 0);"
999   [(set_attr "type" "fcmp")
1000    (set (attr "mode")
1001      (cond [(match_operand:SF 1 "" "")
1002               (const_string "SF")
1003             (match_operand:DF 1 "" "")
1004               (const_string "DF")
1005            ]
1006            (const_string "XF")))
1007    (set_attr "athlon_decode" "vector")])
1009 (define_insn "*cmpfp_iu_mixed"
1010   [(set (reg:CCFPU FLAGS_REG)
1011         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1012                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013   "TARGET_MIX_SSE_I387
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 1);"
1017   [(set_attr "type" "fcmp,ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")])
1024 (define_insn "*cmpfp_iu_sse"
1025   [(set (reg:CCFPU FLAGS_REG)
1026         (compare:CCFPU (match_operand 0 "register_operand" "x")
1027                        (match_operand 1 "nonimmediate_operand" "xm")))]
1028   "TARGET_SSE_MATH
1029    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031   "* return output_fp_compare (insn, operands, 1, 1);"
1032   [(set_attr "type" "ssecomi")
1033    (set (attr "mode")
1034      (if_then_else (match_operand:SF 1 "" "")
1035         (const_string "SF")
1036         (const_string "DF")))
1037    (set_attr "athlon_decode" "vector")])
1039 (define_insn "*cmpfp_iu_387"
1040   [(set (reg:CCFPU FLAGS_REG)
1041         (compare:CCFPU (match_operand 0 "register_operand" "f")
1042                        (match_operand 1 "register_operand" "f")))]
1043   "TARGET_80387 && TARGET_CMOVE
1044    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1045    && FLOAT_MODE_P (GET_MODE (operands[0]))
1046    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047   "* return output_fp_compare (insn, operands, 1, 1);"
1048   [(set_attr "type" "fcmp")
1049    (set (attr "mode")
1050      (cond [(match_operand:SF 1 "" "")
1051               (const_string "SF")
1052             (match_operand:DF 1 "" "")
1053               (const_string "DF")
1054            ]
1055            (const_string "XF")))
1056    (set_attr "athlon_decode" "vector")])
1058 ;; Move instructions.
1060 ;; General case of fullword move.
1062 (define_expand "movsi"
1063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1064         (match_operand:SI 1 "general_operand" ""))]
1065   ""
1066   "ix86_expand_move (SImode, operands); DONE;")
1068 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1069 ;; general_operand.
1071 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1072 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1073 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1074 ;; targets without our curiosities, and it is just as easy to represent
1075 ;; this differently.
1077 (define_insn "*pushsi2"
1078   [(set (match_operand:SI 0 "push_operand" "=<")
1079         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1080   "!TARGET_64BIT"
1081   "push{l}\t%1"
1082   [(set_attr "type" "push")
1083    (set_attr "mode" "SI")])
1085 ;; For 64BIT abi we always round up to 8 bytes.
1086 (define_insn "*pushsi2_rex64"
1087   [(set (match_operand:SI 0 "push_operand" "=X")
1088         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1089   "TARGET_64BIT"
1090   "push{q}\t%q1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1094 (define_insn "*pushsi2_prologue"
1095   [(set (match_operand:SI 0 "push_operand" "=<")
1096         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1097    (clobber (mem:BLK (scratch)))]
1098   "!TARGET_64BIT"
1099   "push{l}\t%1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1103 (define_insn "*popsi1_epilogue"
1104   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1105         (mem:SI (reg:SI SP_REG)))
1106    (set (reg:SI SP_REG)
1107         (plus:SI (reg:SI SP_REG) (const_int 4)))
1108    (clobber (mem:BLK (scratch)))]
1109   "!TARGET_64BIT"
1110   "pop{l}\t%0"
1111   [(set_attr "type" "pop")
1112    (set_attr "mode" "SI")])
1114 (define_insn "popsi1"
1115   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116         (mem:SI (reg:SI SP_REG)))
1117    (set (reg:SI SP_REG)
1118         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1119   "!TARGET_64BIT"
1120   "pop{l}\t%0"
1121   [(set_attr "type" "pop")
1122    (set_attr "mode" "SI")])
1124 (define_insn "*movsi_xor"
1125   [(set (match_operand:SI 0 "register_operand" "=r")
1126         (match_operand:SI 1 "const0_operand" "i"))
1127    (clobber (reg:CC FLAGS_REG))]
1128   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1129   "xor{l}\t{%0, %0|%0, %0}"
1130   [(set_attr "type" "alu1")
1131    (set_attr "mode" "SI")
1132    (set_attr "length_immediate" "0")])
1134 (define_insn "*movsi_or"
1135   [(set (match_operand:SI 0 "register_operand" "=r")
1136         (match_operand:SI 1 "immediate_operand" "i"))
1137    (clobber (reg:CC FLAGS_REG))]
1138   "reload_completed
1139    && operands[1] == constm1_rtx
1140    && (TARGET_PENTIUM || optimize_size)"
1142   operands[1] = constm1_rtx;
1143   return "or{l}\t{%1, %0|%0, %1}";
1145   [(set_attr "type" "alu1")
1146    (set_attr "mode" "SI")
1147    (set_attr "length_immediate" "1")])
1149 (define_insn "*movsi_1"
1150   [(set (match_operand:SI 0 "nonimmediate_operand"
1151                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1152         (match_operand:SI 1 "general_operand"
1153                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1154   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1156   switch (get_attr_type (insn))
1157     {
1158     case TYPE_SSELOG1:
1159       if (get_attr_mode (insn) == MODE_TI)
1160         return "pxor\t%0, %0";
1161       return "xorps\t%0, %0";
1163     case TYPE_SSEMOV:
1164       switch (get_attr_mode (insn))
1165         {
1166         case MODE_TI:
1167           return "movdqa\t{%1, %0|%0, %1}";
1168         case MODE_V4SF:
1169           return "movaps\t{%1, %0|%0, %1}";
1170         case MODE_SI:
1171           return "movd\t{%1, %0|%0, %1}";
1172         case MODE_SF:
1173           return "movss\t{%1, %0|%0, %1}";
1174         default:
1175           gcc_unreachable ();
1176         }
1178     case TYPE_MMXADD:
1179       return "pxor\t%0, %0";
1181     case TYPE_MMXMOV:
1182       if (get_attr_mode (insn) == MODE_DI)
1183         return "movq\t{%1, %0|%0, %1}";
1184       return "movd\t{%1, %0|%0, %1}";
1186     case TYPE_LEA:
1187       return "lea{l}\t{%1, %0|%0, %1}";
1189     default:
1190       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1191       return "mov{l}\t{%1, %0|%0, %1}";
1192     }
1194   [(set (attr "type")
1195      (cond [(eq_attr "alternative" "2")
1196               (const_string "mmx")
1197             (eq_attr "alternative" "3,4,5")
1198               (const_string "mmxmov")
1199             (eq_attr "alternative" "6")
1200               (const_string "sselog1")
1201             (eq_attr "alternative" "7,8,9,10,11")
1202               (const_string "ssemov")
1203             (match_operand:DI 1 "pic_32bit_operand" "")
1204               (const_string "lea")
1205            ]
1206            (const_string "imov")))
1207    (set (attr "mode")
1208      (cond [(eq_attr "alternative" "2,3")
1209               (const_string "DI")
1210             (eq_attr "alternative" "6,7")
1211               (if_then_else
1212                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1213                 (const_string "V4SF")
1214                 (const_string "TI"))
1215             (and (eq_attr "alternative" "8,9,10,11")
1216                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1217               (const_string "SF")
1218            ]
1219            (const_string "SI")))])
1221 ;; Stores and loads of ax to arbitrary constant address.
1222 ;; We fake an second form of instruction to force reload to load address
1223 ;; into register when rax is not available
1224 (define_insn "*movabssi_1_rex64"
1225   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1226         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1227   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1228   "@
1229    movabs{l}\t{%1, %P0|%P0, %1}
1230    mov{l}\t{%1, %a0|%a0, %1}"
1231   [(set_attr "type" "imov")
1232    (set_attr "modrm" "0,*")
1233    (set_attr "length_address" "8,0")
1234    (set_attr "length_immediate" "0,*")
1235    (set_attr "memory" "store")
1236    (set_attr "mode" "SI")])
1238 (define_insn "*movabssi_2_rex64"
1239   [(set (match_operand:SI 0 "register_operand" "=a,r")
1240         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1241   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1242   "@
1243    movabs{l}\t{%P1, %0|%0, %P1}
1244    mov{l}\t{%a1, %0|%0, %a1}"
1245   [(set_attr "type" "imov")
1246    (set_attr "modrm" "0,*")
1247    (set_attr "length_address" "8,0")
1248    (set_attr "length_immediate" "0")
1249    (set_attr "memory" "load")
1250    (set_attr "mode" "SI")])
1252 (define_insn "*swapsi"
1253   [(set (match_operand:SI 0 "register_operand" "+r")
1254         (match_operand:SI 1 "register_operand" "+r"))
1255    (set (match_dup 1)
1256         (match_dup 0))]
1257   ""
1258   "xchg{l}\t%1, %0"
1259   [(set_attr "type" "imov")
1260    (set_attr "mode" "SI")
1261    (set_attr "pent_pair" "np")
1262    (set_attr "athlon_decode" "vector")])
1264 (define_expand "movhi"
1265   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1266         (match_operand:HI 1 "general_operand" ""))]
1267   ""
1268   "ix86_expand_move (HImode, operands); DONE;")
1270 (define_insn "*pushhi2"
1271   [(set (match_operand:HI 0 "push_operand" "=<,<")
1272         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1273   "!TARGET_64BIT"
1274   "@
1275    push{w}\t{|WORD PTR }%1
1276    push{w}\t%1"
1277   [(set_attr "type" "push")
1278    (set_attr "mode" "HI")])
1280 ;; For 64BIT abi we always round up to 8 bytes.
1281 (define_insn "*pushhi2_rex64"
1282   [(set (match_operand:HI 0 "push_operand" "=X")
1283         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1284   "TARGET_64BIT"
1285   "push{q}\t%q1"
1286   [(set_attr "type" "push")
1287    (set_attr "mode" "QI")])
1289 (define_insn "*movhi_1"
1290   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1291         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1292   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1294   switch (get_attr_type (insn))
1295     {
1296     case TYPE_IMOVX:
1297       /* movzwl is faster than movw on p2 due to partial word stalls,
1298          though not as fast as an aligned movl.  */
1299       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1300     default:
1301       if (get_attr_mode (insn) == MODE_SI)
1302         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1303       else
1304         return "mov{w}\t{%1, %0|%0, %1}";
1305     }
1307   [(set (attr "type")
1308      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1309               (const_string "imov")
1310             (and (eq_attr "alternative" "0")
1311                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1312                           (const_int 0))
1313                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1314                           (const_int 0))))
1315               (const_string "imov")
1316             (and (eq_attr "alternative" "1,2")
1317                  (match_operand:HI 1 "aligned_operand" ""))
1318               (const_string "imov")
1319             (and (ne (symbol_ref "TARGET_MOVX")
1320                      (const_int 0))
1321                  (eq_attr "alternative" "0,2"))
1322               (const_string "imovx")
1323            ]
1324            (const_string "imov")))
1325     (set (attr "mode")
1326       (cond [(eq_attr "type" "imovx")
1327                (const_string "SI")
1328              (and (eq_attr "alternative" "1,2")
1329                   (match_operand:HI 1 "aligned_operand" ""))
1330                (const_string "SI")
1331              (and (eq_attr "alternative" "0")
1332                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                            (const_int 0))
1334                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                            (const_int 0))))
1336                (const_string "SI")
1337             ]
1338             (const_string "HI")))])
1340 ;; Stores and loads of ax to arbitrary constant address.
1341 ;; We fake an second form of instruction to force reload to load address
1342 ;; into register when rax is not available
1343 (define_insn "*movabshi_1_rex64"
1344   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1345         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1346   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1347   "@
1348    movabs{w}\t{%1, %P0|%P0, %1}
1349    mov{w}\t{%1, %a0|%a0, %1}"
1350   [(set_attr "type" "imov")
1351    (set_attr "modrm" "0,*")
1352    (set_attr "length_address" "8,0")
1353    (set_attr "length_immediate" "0,*")
1354    (set_attr "memory" "store")
1355    (set_attr "mode" "HI")])
1357 (define_insn "*movabshi_2_rex64"
1358   [(set (match_operand:HI 0 "register_operand" "=a,r")
1359         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1360   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1361   "@
1362    movabs{w}\t{%P1, %0|%0, %P1}
1363    mov{w}\t{%a1, %0|%0, %a1}"
1364   [(set_attr "type" "imov")
1365    (set_attr "modrm" "0,*")
1366    (set_attr "length_address" "8,0")
1367    (set_attr "length_immediate" "0")
1368    (set_attr "memory" "load")
1369    (set_attr "mode" "HI")])
1371 (define_insn "*swaphi_1"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1377   "xchg{l}\t%k1, %k0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "SI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1383 (define_insn "*swaphi_2"
1384   [(set (match_operand:HI 0 "register_operand" "+r")
1385         (match_operand:HI 1 "register_operand" "+r"))
1386    (set (match_dup 1)
1387         (match_dup 0))]
1388   "TARGET_PARTIAL_REG_STALL"
1389   "xchg{w}\t%1, %0"
1390   [(set_attr "type" "imov")
1391    (set_attr "mode" "HI")
1392    (set_attr "pent_pair" "np")
1393    (set_attr "athlon_decode" "vector")])
1395 (define_expand "movstricthi"
1396   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1397         (match_operand:HI 1 "general_operand" ""))]
1398   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1400   /* Don't generate memory->memory moves, go through a register */
1401   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1402     operands[1] = force_reg (HImode, operands[1]);
1405 (define_insn "*movstricthi_1"
1406   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1407         (match_operand:HI 1 "general_operand" "rn,m"))]
1408   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1409    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1410   "mov{w}\t{%1, %0|%0, %1}"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")])
1414 (define_insn "*movstricthi_xor"
1415   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1416         (match_operand:HI 1 "const0_operand" "i"))
1417    (clobber (reg:CC FLAGS_REG))]
1418   "reload_completed
1419    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1420   "xor{w}\t{%0, %0|%0, %0}"
1421   [(set_attr "type" "alu1")
1422    (set_attr "mode" "HI")
1423    (set_attr "length_immediate" "0")])
1425 (define_expand "movqi"
1426   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1427         (match_operand:QI 1 "general_operand" ""))]
1428   ""
1429   "ix86_expand_move (QImode, operands); DONE;")
1431 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1432 ;; "push a byte".  But actually we use pushw, which has the effect
1433 ;; of rounding the amount pushed up to a halfword.
1435 (define_insn "*pushqi2"
1436   [(set (match_operand:QI 0 "push_operand" "=X,X")
1437         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1438   "!TARGET_64BIT"
1439   "@
1440    push{w}\t{|word ptr }%1
1441    push{w}\t%w1"
1442   [(set_attr "type" "push")
1443    (set_attr "mode" "HI")])
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushqi2_rex64"
1447   [(set (match_operand:QI 0 "push_operand" "=X")
1448         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1449   "TARGET_64BIT"
1450   "push{q}\t%q1"
1451   [(set_attr "type" "push")
1452    (set_attr "mode" "QI")])
1454 ;; Situation is quite tricky about when to choose full sized (SImode) move
1455 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1456 ;; partial register dependency machines (such as AMD Athlon), where QImode
1457 ;; moves issue extra dependency and for partial register stalls machines
1458 ;; that don't use QImode patterns (and QImode move cause stall on the next
1459 ;; instruction).
1461 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1462 ;; register stall machines with, where we use QImode instructions, since
1463 ;; partial register stall can be caused there.  Then we use movzx.
1464 (define_insn "*movqi_1"
1465   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1466         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1467   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1469   switch (get_attr_type (insn))
1470     {
1471     case TYPE_IMOVX:
1472       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1473       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1474     default:
1475       if (get_attr_mode (insn) == MODE_SI)
1476         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1477       else
1478         return "mov{b}\t{%1, %0|%0, %1}";
1479     }
1481   [(set (attr "type")
1482      (cond [(eq_attr "alternative" "5")
1483               (const_string "imovx")
1484             (ne (symbol_ref "optimize_size") (const_int 0))
1485               (const_string "imov")
1486             (and (eq_attr "alternative" "3")
1487                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1488                           (const_int 0))
1489                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1490                           (const_int 0))))
1491               (const_string "imov")
1492             (eq_attr "alternative" "3")
1493               (const_string "imovx")
1494             (and (ne (symbol_ref "TARGET_MOVX")
1495                      (const_int 0))
1496                  (eq_attr "alternative" "2"))
1497               (const_string "imovx")
1498            ]
1499            (const_string "imov")))
1500    (set (attr "mode")
1501       (cond [(eq_attr "alternative" "3,4,5")
1502                (const_string "SI")
1503              (eq_attr "alternative" "6")
1504                (const_string "QI")
1505              (eq_attr "type" "imovx")
1506                (const_string "SI")
1507              (and (eq_attr "type" "imov")
1508                   (and (eq_attr "alternative" "0,1")
1509                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1510                            (const_int 0))))
1511                (const_string "SI")
1512              ;; Avoid partial register stalls when not using QImode arithmetic
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1516                                 (const_int 0))
1517                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1518                                 (const_int 0)))))
1519                (const_string "SI")
1520            ]
1521            (const_string "QI")))])
1523 (define_expand "reload_outqi"
1524   [(parallel [(match_operand:QI 0 "" "=m")
1525               (match_operand:QI 1 "register_operand" "r")
1526               (match_operand:QI 2 "register_operand" "=&q")])]
1527   ""
1529   rtx op0, op1, op2;
1530   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1532   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1533   if (! q_regs_operand (op1, QImode))
1534     {
1535       emit_insn (gen_movqi (op2, op1));
1536       op1 = op2;
1537     }
1538   emit_insn (gen_movqi (op0, op1));
1539   DONE;
1542 (define_insn "*swapqi_1"
1543   [(set (match_operand:QI 0 "register_operand" "+r")
1544         (match_operand:QI 1 "register_operand" "+r"))
1545    (set (match_dup 1)
1546         (match_dup 0))]
1547   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1548   "xchg{l}\t%k1, %k0"
1549   [(set_attr "type" "imov")
1550    (set_attr "mode" "SI")
1551    (set_attr "pent_pair" "np")
1552    (set_attr "athlon_decode" "vector")])
1554 (define_insn "*swapqi_2"
1555   [(set (match_operand:QI 0 "register_operand" "+q")
1556         (match_operand:QI 1 "register_operand" "+q"))
1557    (set (match_dup 1)
1558         (match_dup 0))]
1559   "TARGET_PARTIAL_REG_STALL"
1560   "xchg{b}\t%1, %0"
1561   [(set_attr "type" "imov")
1562    (set_attr "mode" "QI")
1563    (set_attr "pent_pair" "np")
1564    (set_attr "athlon_decode" "vector")])
1566 (define_expand "movstrictqi"
1567   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1568         (match_operand:QI 1 "general_operand" ""))]
1569   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1571   /* Don't generate memory->memory moves, go through a register.  */
1572   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1573     operands[1] = force_reg (QImode, operands[1]);
1576 (define_insn "*movstrictqi_1"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1578         (match_operand:QI 1 "general_operand" "*qn,m"))]
1579   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1581   "mov{b}\t{%1, %0|%0, %1}"
1582   [(set_attr "type" "imov")
1583    (set_attr "mode" "QI")])
1585 (define_insn "*movstrictqi_xor"
1586   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1587         (match_operand:QI 1 "const0_operand" "i"))
1588    (clobber (reg:CC FLAGS_REG))]
1589   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1590   "xor{b}\t{%0, %0|%0, %0}"
1591   [(set_attr "type" "alu1")
1592    (set_attr "mode" "QI")
1593    (set_attr "length_immediate" "0")])
1595 (define_insn "*movsi_extv_1"
1596   [(set (match_operand:SI 0 "register_operand" "=R")
1597         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1598                          (const_int 8)
1599                          (const_int 8)))]
1600   ""
1601   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1602   [(set_attr "type" "imovx")
1603    (set_attr "mode" "SI")])
1605 (define_insn "*movhi_extv_1"
1606   [(set (match_operand:HI 0 "register_operand" "=R")
1607         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1615 (define_insn "*movqi_extv_1"
1616   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1617         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   "!TARGET_64BIT"
1622   switch (get_attr_type (insn))
1623     {
1624     case TYPE_IMOVX:
1625       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1626     default:
1627       return "mov{b}\t{%h1, %0|%0, %h1}";
1628     }
1630   [(set (attr "type")
1631      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1632                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1633                              (ne (symbol_ref "TARGET_MOVX")
1634                                  (const_int 0))))
1635         (const_string "imovx")
1636         (const_string "imov")))
1637    (set (attr "mode")
1638      (if_then_else (eq_attr "type" "imovx")
1639         (const_string "SI")
1640         (const_string "QI")))])
1642 (define_insn "*movqi_extv_1_rex64"
1643   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1644         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1645                          (const_int 8)
1646                          (const_int 8)))]
1647   "TARGET_64BIT"
1649   switch (get_attr_type (insn))
1650     {
1651     case TYPE_IMOVX:
1652       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653     default:
1654       return "mov{b}\t{%h1, %0|%0, %h1}";
1655     }
1657   [(set (attr "type")
1658      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1659                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1660                              (ne (symbol_ref "TARGET_MOVX")
1661                                  (const_int 0))))
1662         (const_string "imovx")
1663         (const_string "imov")))
1664    (set (attr "mode")
1665      (if_then_else (eq_attr "type" "imovx")
1666         (const_string "SI")
1667         (const_string "QI")))])
1669 ;; Stores and loads of ax to arbitrary constant address.
1670 ;; We fake an second form of instruction to force reload to load address
1671 ;; into register when rax is not available
1672 (define_insn "*movabsqi_1_rex64"
1673   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1674         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1675   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1676   "@
1677    movabs{b}\t{%1, %P0|%P0, %1}
1678    mov{b}\t{%1, %a0|%a0, %1}"
1679   [(set_attr "type" "imov")
1680    (set_attr "modrm" "0,*")
1681    (set_attr "length_address" "8,0")
1682    (set_attr "length_immediate" "0,*")
1683    (set_attr "memory" "store")
1684    (set_attr "mode" "QI")])
1686 (define_insn "*movabsqi_2_rex64"
1687   [(set (match_operand:QI 0 "register_operand" "=a,r")
1688         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1689   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1690   "@
1691    movabs{b}\t{%P1, %0|%0, %P1}
1692    mov{b}\t{%a1, %0|%0, %a1}"
1693   [(set_attr "type" "imov")
1694    (set_attr "modrm" "0,*")
1695    (set_attr "length_address" "8,0")
1696    (set_attr "length_immediate" "0")
1697    (set_attr "memory" "load")
1698    (set_attr "mode" "QI")])
1700 (define_insn "*movdi_extzv_1"
1701   [(set (match_operand:DI 0 "register_operand" "=R")
1702         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1703                          (const_int 8)
1704                          (const_int 8)))]
1705   "TARGET_64BIT"
1706   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1707   [(set_attr "type" "imovx")
1708    (set_attr "mode" "DI")])
1710 (define_insn "*movsi_extzv_1"
1711   [(set (match_operand:SI 0 "register_operand" "=R")
1712         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   ""
1716   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "SI")])
1720 (define_insn "*movqi_extzv_2"
1721   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1722         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1723                                     (const_int 8)
1724                                     (const_int 8)) 0))]
1725   "!TARGET_64BIT"
1727   switch (get_attr_type (insn))
1728     {
1729     case TYPE_IMOVX:
1730       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1731     default:
1732       return "mov{b}\t{%h1, %0|%0, %h1}";
1733     }
1735   [(set (attr "type")
1736      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1737                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1738                              (ne (symbol_ref "TARGET_MOVX")
1739                                  (const_int 0))))
1740         (const_string "imovx")
1741         (const_string "imov")))
1742    (set (attr "mode")
1743      (if_then_else (eq_attr "type" "imovx")
1744         (const_string "SI")
1745         (const_string "QI")))])
1747 (define_insn "*movqi_extzv_2_rex64"
1748   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1749         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1750                                     (const_int 8)
1751                                     (const_int 8)) 0))]
1752   "TARGET_64BIT"
1754   switch (get_attr_type (insn))
1755     {
1756     case TYPE_IMOVX:
1757       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758     default:
1759       return "mov{b}\t{%h1, %0|%0, %h1}";
1760     }
1762   [(set (attr "type")
1763      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1764                         (ne (symbol_ref "TARGET_MOVX")
1765                             (const_int 0)))
1766         (const_string "imovx")
1767         (const_string "imov")))
1768    (set (attr "mode")
1769      (if_then_else (eq_attr "type" "imovx")
1770         (const_string "SI")
1771         (const_string "QI")))])
1773 (define_insn "movsi_insv_1"
1774   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1775                          (const_int 8)
1776                          (const_int 8))
1777         (match_operand:SI 1 "general_operand" "Qmn"))]
1778   "!TARGET_64BIT"
1779   "mov{b}\t{%b1, %h0|%h0, %b1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "QI")])
1783 (define_insn "movdi_insv_1_rex64"
1784   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1788   "TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1793 (define_insn "*movqi_insv_2"
1794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1798                      (const_int 8)))]
1799   ""
1800   "mov{b}\t{%h1, %h0|%h0, %h1}"
1801   [(set_attr "type" "imov")
1802    (set_attr "mode" "QI")])
1804 (define_expand "movdi"
1805   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1806         (match_operand:DI 1 "general_operand" ""))]
1807   ""
1808   "ix86_expand_move (DImode, operands); DONE;")
1810 (define_insn "*pushdi"
1811   [(set (match_operand:DI 0 "push_operand" "=<")
1812         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1813   "!TARGET_64BIT"
1814   "#")
1816 (define_insn "*pushdi2_rex64"
1817   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1818         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1819   "TARGET_64BIT"
1820   "@
1821    push{q}\t%1
1822    #"
1823   [(set_attr "type" "push,multi")
1824    (set_attr "mode" "DI")])
1826 ;; Convert impossible pushes of immediate to existing instructions.
1827 ;; First try to get scratch register and go through it.  In case this
1828 ;; fails, push sign extended lower part first and then overwrite
1829 ;; upper part by 32bit move.
1830 (define_peephole2
1831   [(match_scratch:DI 2 "r")
1832    (set (match_operand:DI 0 "push_operand" "")
1833         (match_operand:DI 1 "immediate_operand" ""))]
1834   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835    && !x86_64_immediate_operand (operands[1], DImode)"
1836   [(set (match_dup 2) (match_dup 1))
1837    (set (match_dup 0) (match_dup 2))]
1838   "")
1840 ;; We need to define this as both peepholer and splitter for case
1841 ;; peephole2 pass is not run.
1842 ;; "&& 1" is needed to keep it from matching the previous pattern.
1843 (define_peephole2
1844   [(set (match_operand:DI 0 "push_operand" "")
1845         (match_operand:DI 1 "immediate_operand" ""))]
1846   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1847    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1848   [(set (match_dup 0) (match_dup 1))
1849    (set (match_dup 2) (match_dup 3))]
1850   "split_di (operands + 1, 1, operands + 2, operands + 3);
1851    operands[1] = gen_lowpart (DImode, operands[2]);
1852    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1853                                                     GEN_INT (4)));
1854   ")
1856 (define_split
1857   [(set (match_operand:DI 0 "push_operand" "")
1858         (match_operand:DI 1 "immediate_operand" ""))]
1859   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1860    && !symbolic_operand (operands[1], DImode)
1861    && !x86_64_immediate_operand (operands[1], DImode)"
1862   [(set (match_dup 0) (match_dup 1))
1863    (set (match_dup 2) (match_dup 3))]
1864   "split_di (operands + 1, 1, operands + 2, operands + 3);
1865    operands[1] = gen_lowpart (DImode, operands[2]);
1866    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867                                                     GEN_INT (4)));
1868   ")
1870 (define_insn "*pushdi2_prologue_rex64"
1871   [(set (match_operand:DI 0 "push_operand" "=<")
1872         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1873    (clobber (mem:BLK (scratch)))]
1874   "TARGET_64BIT"
1875   "push{q}\t%1"
1876   [(set_attr "type" "push")
1877    (set_attr "mode" "DI")])
1879 (define_insn "*popdi1_epilogue_rex64"
1880   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881         (mem:DI (reg:DI SP_REG)))
1882    (set (reg:DI SP_REG)
1883         (plus:DI (reg:DI SP_REG) (const_int 8)))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "pop{q}\t%0"
1887   [(set_attr "type" "pop")
1888    (set_attr "mode" "DI")])
1890 (define_insn "popdi1"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1900 (define_insn "*movdi_xor_rex64"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (match_operand:DI 1 "const0_operand" "i"))
1903    (clobber (reg:CC FLAGS_REG))]
1904   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1905    && reload_completed"
1906   "xor{l}\t{%k0, %k0|%k0, %k0}"
1907   [(set_attr "type" "alu1")
1908    (set_attr "mode" "SI")
1909    (set_attr "length_immediate" "0")])
1911 (define_insn "*movdi_or_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const_int_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1916    && reload_completed
1917    && operands[1] == constm1_rtx"
1919   operands[1] = constm1_rtx;
1920   return "or{q}\t{%1, %0|%0, %1}";
1922   [(set_attr "type" "alu1")
1923    (set_attr "mode" "DI")
1924    (set_attr "length_immediate" "1")])
1926 (define_insn "*movdi_2"
1927   [(set (match_operand:DI 0 "nonimmediate_operand"
1928                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1929         (match_operand:DI 1 "general_operand"
1930                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1931   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932   "@
1933    #
1934    #
1935    pxor\t%0, %0
1936    movq\t{%1, %0|%0, %1}
1937    movq\t{%1, %0|%0, %1}
1938    pxor\t%0, %0
1939    movq\t{%1, %0|%0, %1}
1940    movdqa\t{%1, %0|%0, %1}
1941    movq\t{%1, %0|%0, %1}
1942    xorps\t%0, %0
1943    movlps\t{%1, %0|%0, %1}
1944    movaps\t{%1, %0|%0, %1}
1945    movlps\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1947    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1949 (define_split
1950   [(set (match_operand:DI 0 "push_operand" "")
1951         (match_operand:DI 1 "general_operand" ""))]
1952   "!TARGET_64BIT && reload_completed
1953    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1954   [(const_int 0)]
1955   "ix86_split_long_move (operands); DONE;")
1957 ;; %%% This multiword shite has got to go.
1958 (define_split
1959   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1960         (match_operand:DI 1 "general_operand" ""))]
1961   "!TARGET_64BIT && reload_completed
1962    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1963    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964   [(const_int 0)]
1965   "ix86_split_long_move (operands); DONE;")
1967 (define_insn "*movdi_1_rex64"
1968   [(set (match_operand:DI 0 "nonimmediate_operand"
1969                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1970         (match_operand:DI 1 "general_operand"
1971                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1972   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1974   switch (get_attr_type (insn))
1975     {
1976     case TYPE_SSECVT:
1977       if (which_alternative == 13)
1978         return "movq2dq\t{%1, %0|%0, %1}";
1979       else
1980         return "movdq2q\t{%1, %0|%0, %1}";
1981     case TYPE_SSEMOV:
1982       if (get_attr_mode (insn) == MODE_TI)
1983           return "movdqa\t{%1, %0|%0, %1}";
1984       /* FALLTHRU */
1985     case TYPE_MMXMOV:
1986       /* Moves from and into integer register is done using movd opcode with
1987          REX prefix.  */
1988       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1989           return "movd\t{%1, %0|%0, %1}";
1990       return "movq\t{%1, %0|%0, %1}";
1991     case TYPE_SSELOG1:
1992     case TYPE_MMXADD:
1993       return "pxor\t%0, %0";
1994     case TYPE_MULTI:
1995       return "#";
1996     case TYPE_LEA:
1997       return "lea{q}\t{%a1, %0|%0, %a1}";
1998     default:
1999       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000       if (get_attr_mode (insn) == MODE_SI)
2001         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002       else if (which_alternative == 2)
2003         return "movabs{q}\t{%1, %0|%0, %1}";
2004       else
2005         return "mov{q}\t{%1, %0|%0, %1}";
2006     }
2008   [(set (attr "type")
2009      (cond [(eq_attr "alternative" "5")
2010               (const_string "mmx")
2011             (eq_attr "alternative" "6,7,8")
2012               (const_string "mmxmov")
2013             (eq_attr "alternative" "9")
2014               (const_string "sselog1")
2015             (eq_attr "alternative" "10,11,12")
2016               (const_string "ssemov")
2017             (eq_attr "alternative" "13,14")
2018               (const_string "ssecvt")
2019             (eq_attr "alternative" "4")
2020               (const_string "multi")
2021             (match_operand:DI 1 "pic_32bit_operand" "")
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2026    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2027    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2029 ;; Stores and loads of ax to arbitrary constant address.
2030 ;; We fake an second form of instruction to force reload to load address
2031 ;; into register when rax is not available
2032 (define_insn "*movabsdi_1_rex64"
2033   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2034         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2035   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2036   "@
2037    movabs{q}\t{%1, %P0|%P0, %1}
2038    mov{q}\t{%1, %a0|%a0, %1}"
2039   [(set_attr "type" "imov")
2040    (set_attr "modrm" "0,*")
2041    (set_attr "length_address" "8,0")
2042    (set_attr "length_immediate" "0,*")
2043    (set_attr "memory" "store")
2044    (set_attr "mode" "DI")])
2046 (define_insn "*movabsdi_2_rex64"
2047   [(set (match_operand:DI 0 "register_operand" "=a,r")
2048         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2049   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2050   "@
2051    movabs{q}\t{%P1, %0|%0, %P1}
2052    mov{q}\t{%a1, %0|%0, %a1}"
2053   [(set_attr "type" "imov")
2054    (set_attr "modrm" "0,*")
2055    (set_attr "length_address" "8,0")
2056    (set_attr "length_immediate" "0")
2057    (set_attr "memory" "load")
2058    (set_attr "mode" "DI")])
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it.  In case this
2062 ;; fails, move by 32bit parts.
2063 (define_peephole2
2064   [(match_scratch:DI 2 "r")
2065    (set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068    && !x86_64_immediate_operand (operands[1], DImode)"
2069   [(set (match_dup 2) (match_dup 1))
2070    (set (match_dup 0) (match_dup 2))]
2071   "")
2073 ;; We need to define this as both peepholer and splitter for case
2074 ;; peephole2 pass is not run.
2075 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 (define_peephole2
2077   [(set (match_operand:DI 0 "memory_operand" "")
2078         (match_operand:DI 1 "immediate_operand" ""))]
2079   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2080    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2081   [(set (match_dup 2) (match_dup 3))
2082    (set (match_dup 4) (match_dup 5))]
2083   "split_di (operands, 2, operands + 2, operands + 4);")
2085 (define_split
2086   [(set (match_operand:DI 0 "memory_operand" "")
2087         (match_operand:DI 1 "immediate_operand" ""))]
2088   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2089    && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode)"
2091   [(set (match_dup 2) (match_dup 3))
2092    (set (match_dup 4) (match_dup 5))]
2093   "split_di (operands, 2, operands + 2, operands + 4);")
2095 (define_insn "*swapdi_rex64"
2096   [(set (match_operand:DI 0 "register_operand" "+r")
2097         (match_operand:DI 1 "register_operand" "+r"))
2098    (set (match_dup 1)
2099         (match_dup 0))]
2100   "TARGET_64BIT"
2101   "xchg{q}\t%1, %0"
2102   [(set_attr "type" "imov")
2103    (set_attr "mode" "DI")
2104    (set_attr "pent_pair" "np")
2105    (set_attr "athlon_decode" "vector")])
2107 (define_expand "movti"
2108   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2109         (match_operand:TI 1 "nonimmediate_operand" ""))]
2110   "TARGET_SSE || TARGET_64BIT"
2112   if (TARGET_64BIT)
2113     ix86_expand_move (TImode, operands);
2114   else
2115     ix86_expand_vector_move (TImode, operands);
2116   DONE;
2119 (define_insn "*movti_internal"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2121         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2122   "TARGET_SSE && !TARGET_64BIT
2123    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2125   switch (which_alternative)
2126     {
2127     case 0:
2128       if (get_attr_mode (insn) == MODE_V4SF)
2129         return "xorps\t%0, %0";
2130       else
2131         return "pxor\t%0, %0";
2132     case 1:
2133     case 2:
2134       if (get_attr_mode (insn) == MODE_V4SF)
2135         return "movaps\t{%1, %0|%0, %1}";
2136       else
2137         return "movdqa\t{%1, %0|%0, %1}";
2138     default:
2139       gcc_unreachable ();
2140     }
2142   [(set_attr "type" "ssemov,ssemov,ssemov")
2143    (set (attr "mode")
2144         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2145                  (const_string "V4SF")
2147                (eq_attr "alternative" "0,1")
2148                  (if_then_else
2149                    (ne (symbol_ref "optimize_size")
2150                        (const_int 0))
2151                    (const_string "V4SF")
2152                    (const_string "TI"))
2153                (eq_attr "alternative" "2")
2154                  (if_then_else
2155                    (ne (symbol_ref "optimize_size")
2156                        (const_int 0))
2157                    (const_string "V4SF")
2158                    (const_string "TI"))]
2159                (const_string "TI")))])
2161 (define_insn "*movti_rex64"
2162   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2163         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2164   "TARGET_64BIT
2165    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2167   switch (which_alternative)
2168     {
2169     case 0:
2170     case 1:
2171       return "#";
2172     case 2:
2173       if (get_attr_mode (insn) == MODE_V4SF)
2174         return "xorps\t%0, %0";
2175       else
2176         return "pxor\t%0, %0";
2177     case 3:
2178     case 4:
2179       if (get_attr_mode (insn) == MODE_V4SF)
2180         return "movaps\t{%1, %0|%0, %1}";
2181       else
2182         return "movdqa\t{%1, %0|%0, %1}";
2183     default:
2184       gcc_unreachable ();
2185     }
2187   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2188    (set (attr "mode")
2189         (cond [(eq_attr "alternative" "2,3")
2190                  (if_then_else
2191                    (ne (symbol_ref "optimize_size")
2192                        (const_int 0))
2193                    (const_string "V4SF")
2194                    (const_string "TI"))
2195                (eq_attr "alternative" "4")
2196                  (if_then_else
2197                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2198                             (const_int 0))
2199                         (ne (symbol_ref "optimize_size")
2200                             (const_int 0)))
2201                    (const_string "V4SF")
2202                    (const_string "TI"))]
2203                (const_string "DI")))])
2205 (define_split
2206   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2207         (match_operand:TI 1 "general_operand" ""))]
2208   "reload_completed && !SSE_REG_P (operands[0])
2209    && !SSE_REG_P (operands[1])"
2210   [(const_int 0)]
2211   "ix86_split_long_move (operands); DONE;")
2213 (define_expand "movsf"
2214   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2215         (match_operand:SF 1 "general_operand" ""))]
2216   ""
2217   "ix86_expand_move (SFmode, operands); DONE;")
2219 (define_insn "*pushsf"
2220   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2221         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2222   "!TARGET_64BIT"
2224   /* Anything else should be already split before reg-stack.  */
2225   gcc_assert (which_alternative == 1);
2226   return "push{l}\t%1";
2228   [(set_attr "type" "multi,push,multi")
2229    (set_attr "unit" "i387,*,*")
2230    (set_attr "mode" "SF,SI,SF")])
2232 (define_insn "*pushsf_rex64"
2233   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2234         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2235   "TARGET_64BIT"
2237   /* Anything else should be already split before reg-stack.  */
2238   gcc_assert (which_alternative == 1);
2239   return "push{q}\t%q1";
2241   [(set_attr "type" "multi,push,multi")
2242    (set_attr "unit" "i387,*,*")
2243    (set_attr "mode" "SF,DI,SF")])
2245 (define_split
2246   [(set (match_operand:SF 0 "push_operand" "")
2247         (match_operand:SF 1 "memory_operand" ""))]
2248   "reload_completed
2249    && GET_CODE (operands[1]) == MEM
2250    && constant_pool_reference_p (operands[1])"
2251   [(set (match_dup 0)
2252         (match_dup 1))]
2253   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2256 ;; %%% Kill this when call knows how to work this out.
2257 (define_split
2258   [(set (match_operand:SF 0 "push_operand" "")
2259         (match_operand:SF 1 "any_fp_register_operand" ""))]
2260   "!TARGET_64BIT"
2261   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2262    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2264 (define_split
2265   [(set (match_operand:SF 0 "push_operand" "")
2266         (match_operand:SF 1 "any_fp_register_operand" ""))]
2267   "TARGET_64BIT"
2268   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2269    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2271 (define_insn "*movsf_1"
2272   [(set (match_operand:SF 0 "nonimmediate_operand"
2273           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2274         (match_operand:SF 1 "general_operand"
2275           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2276   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2277    && (reload_in_progress || reload_completed
2278        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2279        || GET_CODE (operands[1]) != CONST_DOUBLE
2280        || memory_operand (operands[0], SFmode))" 
2282   switch (which_alternative)
2283     {
2284     case 0:
2285       return output_387_reg_move (insn, operands);
2287     case 1:
2288       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2289         return "fstp%z0\t%y0";
2290       else
2291         return "fst%z0\t%y0";
2293     case 2:
2294       return standard_80387_constant_opcode (operands[1]);
2296     case 3:
2297     case 4:
2298       return "mov{l}\t{%1, %0|%0, %1}";
2299     case 5:
2300       if (get_attr_mode (insn) == MODE_TI)
2301         return "pxor\t%0, %0";
2302       else
2303         return "xorps\t%0, %0";
2304     case 6:
2305       if (get_attr_mode (insn) == MODE_V4SF)
2306         return "movaps\t{%1, %0|%0, %1}";
2307       else
2308         return "movss\t{%1, %0|%0, %1}";
2309     case 7:
2310     case 8:
2311       return "movss\t{%1, %0|%0, %1}";
2313     case 9:
2314     case 10:
2315       return "movd\t{%1, %0|%0, %1}";
2317     case 11:
2318       return "movq\t{%1, %0|%0, %1}";
2320     default:
2321       gcc_unreachable ();
2322     }
2324   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2325    (set (attr "mode")
2326         (cond [(eq_attr "alternative" "3,4,9,10")
2327                  (const_string "SI")
2328                (eq_attr "alternative" "5")
2329                  (if_then_else
2330                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2331                                  (const_int 0))
2332                              (ne (symbol_ref "TARGET_SSE2")
2333                                  (const_int 0)))
2334                         (eq (symbol_ref "optimize_size")
2335                             (const_int 0)))
2336                    (const_string "TI")
2337                    (const_string "V4SF"))
2338                /* For architectures resolving dependencies on
2339                   whole SSE registers use APS move to break dependency
2340                   chains, otherwise use short move to avoid extra work. 
2342                   Do the same for architectures resolving dependencies on
2343                   the parts.  While in DF mode it is better to always handle
2344                   just register parts, the SF mode is different due to lack
2345                   of instructions to load just part of the register.  It is
2346                   better to maintain the whole registers in single format
2347                   to avoid problems on using packed logical operations.  */
2348                (eq_attr "alternative" "6")
2349                  (if_then_else
2350                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2351                             (const_int 0))
2352                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2353                             (const_int 0)))
2354                    (const_string "V4SF")
2355                    (const_string "SF"))
2356                (eq_attr "alternative" "11")
2357                  (const_string "DI")]
2358                (const_string "SF")))])
2360 (define_insn "*swapsf"
2361   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2362         (match_operand:SF 1 "fp_register_operand" "+f"))
2363    (set (match_dup 1)
2364         (match_dup 0))]
2365   "reload_completed || TARGET_80387"
2367   if (STACK_TOP_P (operands[0]))
2368     return "fxch\t%1";
2369   else
2370     return "fxch\t%0";
2372   [(set_attr "type" "fxch")
2373    (set_attr "mode" "SF")])
2375 (define_expand "movdf"
2376   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2377         (match_operand:DF 1 "general_operand" ""))]
2378   ""
2379   "ix86_expand_move (DFmode, operands); DONE;")
2381 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2382 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2383 ;; On the average, pushdf using integers can be still shorter.  Allow this
2384 ;; pattern for optimize_size too.
2386 (define_insn "*pushdf_nointeger"
2387   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2388         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2389   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2391   /* This insn should be already split before reg-stack.  */
2392   gcc_unreachable ();
2394   [(set_attr "type" "multi")
2395    (set_attr "unit" "i387,*,*,*")
2396    (set_attr "mode" "DF,SI,SI,DF")])
2398 (define_insn "*pushdf_integer"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2401   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2403   /* This insn should be already split before reg-stack.  */
2404   gcc_unreachable ();
2406   [(set_attr "type" "multi")
2407    (set_attr "unit" "i387,*,*")
2408    (set_attr "mode" "DF,SI,DF")])
2410 ;; %%% Kill this when call knows how to work this out.
2411 (define_split
2412   [(set (match_operand:DF 0 "push_operand" "")
2413         (match_operand:DF 1 "any_fp_register_operand" ""))]
2414   "!TARGET_64BIT && reload_completed"
2415   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2416    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2417   "")
2419 (define_split
2420   [(set (match_operand:DF 0 "push_operand" "")
2421         (match_operand:DF 1 "any_fp_register_operand" ""))]
2422   "TARGET_64BIT && reload_completed"
2423   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2424    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2425   "")
2427 (define_split
2428   [(set (match_operand:DF 0 "push_operand" "")
2429         (match_operand:DF 1 "general_operand" ""))]
2430   "reload_completed"
2431   [(const_int 0)]
2432   "ix86_split_long_move (operands); DONE;")
2434 ;; Moving is usually shorter when only FP registers are used. This separate
2435 ;; movdf pattern avoids the use of integer registers for FP operations
2436 ;; when optimizing for size.
2438 (define_insn "*movdf_nointeger"
2439   [(set (match_operand:DF 0 "nonimmediate_operand"
2440                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2441         (match_operand:DF 1 "general_operand"
2442                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2443   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2444    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2445    && (reload_in_progress || reload_completed
2446        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2447        || GET_CODE (operands[1]) != CONST_DOUBLE
2448        || memory_operand (operands[0], DFmode))" 
2450   switch (which_alternative)
2451     {
2452     case 0:
2453       return output_387_reg_move (insn, operands);
2455     case 1:
2456       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2457         return "fstp%z0\t%y0";
2458       else
2459         return "fst%z0\t%y0";
2461     case 2:
2462       return standard_80387_constant_opcode (operands[1]);
2464     case 3:
2465     case 4:
2466       return "#";
2467     case 5:
2468       switch (get_attr_mode (insn))
2469         {
2470         case MODE_V4SF:
2471           return "xorps\t%0, %0";
2472         case MODE_V2DF:
2473           return "xorpd\t%0, %0";
2474         case MODE_TI:
2475           return "pxor\t%0, %0";
2476         default:
2477           gcc_unreachable ();
2478         }
2479     case 6:
2480     case 7:
2481     case 8:
2482       switch (get_attr_mode (insn))
2483         {
2484         case MODE_V4SF:
2485           return "movaps\t{%1, %0|%0, %1}";
2486         case MODE_V2DF:
2487           return "movapd\t{%1, %0|%0, %1}";
2488         case MODE_TI:
2489           return "movdqa\t{%1, %0|%0, %1}";
2490         case MODE_DI:
2491           return "movq\t{%1, %0|%0, %1}";
2492         case MODE_DF:
2493           return "movsd\t{%1, %0|%0, %1}";
2494         case MODE_V1DF:
2495           return "movlpd\t{%1, %0|%0, %1}";
2496         case MODE_V2SF:
2497           return "movlps\t{%1, %0|%0, %1}";
2498         default:
2499           gcc_unreachable ();
2500         }
2502     default:
2503       gcc_unreachable ();
2504     }
2506   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2507    (set (attr "mode")
2508         (cond [(eq_attr "alternative" "0,1,2")
2509                  (const_string "DF")
2510                (eq_attr "alternative" "3,4")
2511                  (const_string "SI")
2513                /* For SSE1, we have many fewer alternatives.  */
2514                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2515                  (cond [(eq_attr "alternative" "5,6")
2516                           (const_string "V4SF")
2517                        ]
2518                    (const_string "V2SF"))
2520                /* xorps is one byte shorter.  */
2521                (eq_attr "alternative" "5")
2522                  (cond [(ne (symbol_ref "optimize_size")
2523                             (const_int 0))
2524                           (const_string "V4SF")
2525                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2526                             (const_int 0))
2527                           (const_string "TI")
2528                        ]
2529                        (const_string "V2DF"))
2531                /* For architectures resolving dependencies on
2532                   whole SSE registers use APD move to break dependency
2533                   chains, otherwise use short move to avoid extra work.
2535                   movaps encodes one byte shorter.  */
2536                (eq_attr "alternative" "6")
2537                  (cond
2538                    [(ne (symbol_ref "optimize_size")
2539                         (const_int 0))
2540                       (const_string "V4SF")
2541                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2542                         (const_int 0))
2543                       (const_string "V2DF")
2544                    ]
2545                    (const_string "DF"))
2546                /* For architectures resolving dependencies on register
2547                   parts we may avoid extra work to zero out upper part
2548                   of register.  */
2549                (eq_attr "alternative" "7")
2550                  (if_then_else
2551                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2552                        (const_int 0))
2553                    (const_string "V1DF")
2554                    (const_string "DF"))
2555               ]
2556               (const_string "DF")))])
2558 (define_insn "*movdf_integer"
2559   [(set (match_operand:DF 0 "nonimmediate_operand"
2560                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2561         (match_operand:DF 1 "general_operand"
2562                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2563   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2564    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2565    && (reload_in_progress || reload_completed
2566        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2567        || GET_CODE (operands[1]) != CONST_DOUBLE
2568        || memory_operand (operands[0], DFmode))" 
2570   switch (which_alternative)
2571     {
2572     case 0:
2573       return output_387_reg_move (insn, operands);
2575     case 1:
2576       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2577         return "fstp%z0\t%y0";
2578       else
2579         return "fst%z0\t%y0";
2581     case 2:
2582       return standard_80387_constant_opcode (operands[1]);
2584     case 3:
2585     case 4:
2586       return "#";
2588     case 5:
2589       switch (get_attr_mode (insn))
2590         {
2591         case MODE_V4SF:
2592           return "xorps\t%0, %0";
2593         case MODE_V2DF:
2594           return "xorpd\t%0, %0";
2595         case MODE_TI:
2596           return "pxor\t%0, %0";
2597         default:
2598           gcc_unreachable ();
2599         }
2600     case 6:
2601     case 7:
2602     case 8:
2603       switch (get_attr_mode (insn))
2604         {
2605         case MODE_V4SF:
2606           return "movaps\t{%1, %0|%0, %1}";
2607         case MODE_V2DF:
2608           return "movapd\t{%1, %0|%0, %1}";
2609         case MODE_TI:
2610           return "movdqa\t{%1, %0|%0, %1}";
2611         case MODE_DI:
2612           return "movq\t{%1, %0|%0, %1}";
2613         case MODE_DF:
2614           return "movsd\t{%1, %0|%0, %1}";
2615         case MODE_V1DF:
2616           return "movlpd\t{%1, %0|%0, %1}";
2617         case MODE_V2SF:
2618           return "movlps\t{%1, %0|%0, %1}";
2619         default:
2620           gcc_unreachable ();
2621         }
2623     default:
2624       gcc_unreachable();
2625     }
2627   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2628    (set (attr "mode")
2629         (cond [(eq_attr "alternative" "0,1,2")
2630                  (const_string "DF")
2631                (eq_attr "alternative" "3,4")
2632                  (const_string "SI")
2634                /* For SSE1, we have many fewer alternatives.  */
2635                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2636                  (cond [(eq_attr "alternative" "5,6")
2637                           (const_string "V4SF")
2638                        ]
2639                    (const_string "V2SF"))
2641                /* xorps is one byte shorter.  */
2642                (eq_attr "alternative" "5")
2643                  (cond [(ne (symbol_ref "optimize_size")
2644                             (const_int 0))
2645                           (const_string "V4SF")
2646                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647                             (const_int 0))
2648                           (const_string "TI")
2649                        ]
2650                        (const_string "V2DF"))
2652                /* For architectures resolving dependencies on
2653                   whole SSE registers use APD move to break dependency
2654                   chains, otherwise use short move to avoid extra work.
2656                   movaps encodes one byte shorter.  */
2657                (eq_attr "alternative" "6")
2658                  (cond
2659                    [(ne (symbol_ref "optimize_size")
2660                         (const_int 0))
2661                       (const_string "V4SF")
2662                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663                         (const_int 0))
2664                       (const_string "V2DF")
2665                    ]
2666                    (const_string "DF"))
2667                /* For architectures resolving dependencies on register
2668                   parts we may avoid extra work to zero out upper part
2669                   of register.  */
2670                (eq_attr "alternative" "7")
2671                  (if_then_else
2672                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673                        (const_int 0))
2674                    (const_string "V1DF")
2675                    (const_string "DF"))
2676               ]
2677               (const_string "DF")))])
2679 (define_split
2680   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2681         (match_operand:DF 1 "general_operand" ""))]
2682   "reload_completed
2683    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2684    && ! (ANY_FP_REG_P (operands[0]) || 
2685          (GET_CODE (operands[0]) == SUBREG
2686           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2687    && ! (ANY_FP_REG_P (operands[1]) || 
2688          (GET_CODE (operands[1]) == SUBREG
2689           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2693 (define_insn "*swapdf"
2694   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2695         (match_operand:DF 1 "fp_register_operand" "+f"))
2696    (set (match_dup 1)
2697         (match_dup 0))]
2698   "reload_completed || TARGET_80387"
2700   if (STACK_TOP_P (operands[0]))
2701     return "fxch\t%1";
2702   else
2703     return "fxch\t%0";
2705   [(set_attr "type" "fxch")
2706    (set_attr "mode" "DF")])
2708 (define_expand "movxf"
2709   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2710         (match_operand:XF 1 "general_operand" ""))]
2711   ""
2712   "ix86_expand_move (XFmode, operands); DONE;")
2714 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2715 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2716 ;; Pushing using integer instructions is longer except for constants
2717 ;; and direct memory references.
2718 ;; (assuming that any given constant is pushed only once, but this ought to be
2719 ;;  handled elsewhere).
2721 (define_insn "*pushxf_nointeger"
2722   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2723         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2724   "optimize_size"
2726   /* This insn should be already split before reg-stack.  */
2727   gcc_unreachable ();
2729   [(set_attr "type" "multi")
2730    (set_attr "unit" "i387,*,*")
2731    (set_attr "mode" "XF,SI,SI")])
2733 (define_insn "*pushxf_integer"
2734   [(set (match_operand:XF 0 "push_operand" "=<,<")
2735         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2736   "!optimize_size"
2738   /* This insn should be already split before reg-stack.  */
2739   gcc_unreachable ();
2741   [(set_attr "type" "multi")
2742    (set_attr "unit" "i387,*")
2743    (set_attr "mode" "XF,SI")])
2745 (define_split
2746   [(set (match_operand 0 "push_operand" "")
2747         (match_operand 1 "general_operand" ""))]
2748   "reload_completed
2749    && (GET_MODE (operands[0]) == XFmode
2750        || GET_MODE (operands[0]) == DFmode)
2751    && !ANY_FP_REG_P (operands[1])"
2752   [(const_int 0)]
2753   "ix86_split_long_move (operands); DONE;")
2755 (define_split
2756   [(set (match_operand:XF 0 "push_operand" "")
2757         (match_operand:XF 1 "any_fp_register_operand" ""))]
2758   "!TARGET_64BIT"
2759   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2760    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763 (define_split
2764   [(set (match_operand:XF 0 "push_operand" "")
2765         (match_operand:XF 1 "any_fp_register_operand" ""))]
2766   "TARGET_64BIT"
2767   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2768    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2769   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771 ;; Do not use integer registers when optimizing for size
2772 (define_insn "*movxf_nointeger"
2773   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2774         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775   "optimize_size
2776    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777    && (reload_in_progress || reload_completed
2778        || GET_CODE (operands[1]) != CONST_DOUBLE
2779        || memory_operand (operands[0], XFmode))" 
2781   switch (which_alternative)
2782     {
2783     case 0:
2784       return output_387_reg_move (insn, operands);
2786     case 1:
2787       /* There is no non-popping store to memory for XFmode.  So if
2788          we need one, follow the store with a load.  */
2789       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790         return "fstp%z0\t%y0\;fld%z0\t%y0";
2791       else
2792         return "fstp%z0\t%y0";
2794     case 2:
2795       return standard_80387_constant_opcode (operands[1]);
2797     case 3: case 4:
2798       return "#";
2799     default:
2800       gcc_unreachable ();
2801     }
2803   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2804    (set_attr "mode" "XF,XF,XF,SI,SI")])
2806 (define_insn "*movxf_integer"
2807   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2808         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2809   "!optimize_size
2810    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2811    && (reload_in_progress || reload_completed
2812        || GET_CODE (operands[1]) != CONST_DOUBLE
2813        || memory_operand (operands[0], XFmode))" 
2815   switch (which_alternative)
2816     {
2817     case 0:
2818       return output_387_reg_move (insn, operands);
2820     case 1:
2821       /* There is no non-popping store to memory for XFmode.  So if
2822          we need one, follow the store with a load.  */
2823       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2824         return "fstp%z0\t%y0\;fld%z0\t%y0";
2825       else
2826         return "fstp%z0\t%y0";
2828     case 2:
2829       return standard_80387_constant_opcode (operands[1]);
2831     case 3: case 4:
2832       return "#";
2834     default:
2835       gcc_unreachable ();
2836     }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 (define_split
2842   [(set (match_operand 0 "nonimmediate_operand" "")
2843         (match_operand 1 "general_operand" ""))]
2844   "reload_completed
2845    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2846    && GET_MODE (operands[0]) == XFmode
2847    && ! (ANY_FP_REG_P (operands[0]) || 
2848          (GET_CODE (operands[0]) == SUBREG
2849           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2850    && ! (ANY_FP_REG_P (operands[1]) || 
2851          (GET_CODE (operands[1]) == SUBREG
2852           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853   [(const_int 0)]
2854   "ix86_split_long_move (operands); DONE;")
2856 (define_split
2857   [(set (match_operand 0 "register_operand" "")
2858         (match_operand 1 "memory_operand" ""))]
2859   "reload_completed
2860    && GET_CODE (operands[1]) == MEM
2861    && (GET_MODE (operands[0]) == XFmode
2862        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2863    && constant_pool_reference_p (operands[1])"
2864   [(set (match_dup 0) (match_dup 1))]
2866   rtx c = avoid_constant_pool_reference (operands[1]);
2867   rtx r = operands[0];
2869   if (GET_CODE (r) == SUBREG)
2870     r = SUBREG_REG (r);
2872   if (SSE_REG_P (r))
2873     {
2874       if (!standard_sse_constant_p (c))
2875         FAIL;
2876     }
2877   else if (FP_REG_P (r))
2878     {
2879       if (!standard_80387_constant_p (c))
2880         FAIL;
2881     }
2882   else if (MMX_REG_P (r))
2883     FAIL;
2885   operands[1] = c;
2888 (define_insn "swapxf"
2889   [(set (match_operand:XF 0 "register_operand" "+f")
2890         (match_operand:XF 1 "register_operand" "+f"))
2891    (set (match_dup 1)
2892         (match_dup 0))]
2893   "TARGET_80387"
2895   if (STACK_TOP_P (operands[0]))
2896     return "fxch\t%1";
2897   else
2898     return "fxch\t%0";
2900   [(set_attr "type" "fxch")
2901    (set_attr "mode" "XF")])
2903 (define_expand "movtf"
2904   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2905         (match_operand:TF 1 "nonimmediate_operand" ""))]
2906   "TARGET_64BIT"
2908   ix86_expand_move (TFmode, operands);
2909   DONE;
2912 (define_insn "*movtf_internal"
2913   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2914         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2915   "TARGET_64BIT
2916    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2918   switch (which_alternative)
2919     {
2920     case 0:
2921     case 1:
2922       return "#";
2923     case 2:
2924       if (get_attr_mode (insn) == MODE_V4SF)
2925         return "xorps\t%0, %0";
2926       else
2927         return "pxor\t%0, %0";
2928     case 3:
2929     case 4:
2930       if (get_attr_mode (insn) == MODE_V4SF)
2931         return "movaps\t{%1, %0|%0, %1}";
2932       else
2933         return "movdqa\t{%1, %0|%0, %1}";
2934     default:
2935       gcc_unreachable ();
2936     }
2938   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2939    (set (attr "mode")
2940         (cond [(eq_attr "alternative" "2,3")
2941                  (if_then_else
2942                    (ne (symbol_ref "optimize_size")
2943                        (const_int 0))
2944                    (const_string "V4SF")
2945                    (const_string "TI"))
2946                (eq_attr "alternative" "4")
2947                  (if_then_else
2948                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2949                             (const_int 0))
2950                         (ne (symbol_ref "optimize_size")
2951                             (const_int 0)))
2952                    (const_string "V4SF")
2953                    (const_string "TI"))]
2954                (const_string "DI")))])
2956 (define_split
2957   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2958         (match_operand:TF 1 "general_operand" ""))]
2959   "reload_completed && !SSE_REG_P (operands[0])
2960    && !SSE_REG_P (operands[1])"
2961   [(const_int 0)]
2962   "ix86_split_long_move (operands); DONE;")
2964 ;; Zero extension instructions
2966 (define_expand "zero_extendhisi2"
2967   [(set (match_operand:SI 0 "register_operand" "")
2968      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2969   ""
2971   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2972     {
2973       operands[1] = force_reg (HImode, operands[1]);
2974       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2975       DONE;
2976     }
2979 (define_insn "zero_extendhisi2_and"
2980   [(set (match_operand:SI 0 "register_operand" "=r")
2981      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2982    (clobber (reg:CC FLAGS_REG))]
2983   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984   "#"
2985   [(set_attr "type" "alu1")
2986    (set_attr "mode" "SI")])
2988 (define_split
2989   [(set (match_operand:SI 0 "register_operand" "")
2990         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2991    (clobber (reg:CC FLAGS_REG))]
2992   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2994               (clobber (reg:CC FLAGS_REG))])]
2995   "")
2997 (define_insn "*zero_extendhisi2_movzwl"
2998   [(set (match_operand:SI 0 "register_operand" "=r")
2999      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3000   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3001   "movz{wl|x}\t{%1, %0|%0, %1}"
3002   [(set_attr "type" "imovx")
3003    (set_attr "mode" "SI")])
3005 (define_expand "zero_extendqihi2"
3006   [(parallel
3007     [(set (match_operand:HI 0 "register_operand" "")
3008        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3009      (clobber (reg:CC FLAGS_REG))])]
3010   ""
3011   "")
3013 (define_insn "*zero_extendqihi2_and"
3014   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3015      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018   "#"
3019   [(set_attr "type" "alu1")
3020    (set_attr "mode" "HI")])
3022 (define_insn "*zero_extendqihi2_movzbw_and"
3023   [(set (match_operand:HI 0 "register_operand" "=r,r")
3024      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3027   "#"
3028   [(set_attr "type" "imovx,alu1")
3029    (set_attr "mode" "HI")])
3031 (define_insn "*zero_extendqihi2_movzbw"
3032   [(set (match_operand:HI 0 "register_operand" "=r")
3033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3035   "movz{bw|x}\t{%1, %0|%0, %1}"
3036   [(set_attr "type" "imovx")
3037    (set_attr "mode" "HI")])
3039 ;; For the movzbw case strip only the clobber
3040 (define_split
3041   [(set (match_operand:HI 0 "register_operand" "")
3042         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043    (clobber (reg:CC FLAGS_REG))]
3044   "reload_completed 
3045    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3046    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3050 ;; When source and destination does not overlap, clear destination
3051 ;; first and then do the movb
3052 (define_split
3053   [(set (match_operand:HI 0 "register_operand" "")
3054         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3055    (clobber (reg:CC FLAGS_REG))]
3056   "reload_completed
3057    && ANY_QI_REG_P (operands[0])
3058    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3059    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3060   [(set (match_dup 0) (const_int 0))
3061    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3062   "operands[2] = gen_lowpart (QImode, operands[0]);")
3064 ;; Rest is handled by single and.
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && true_regnum (operands[0]) == true_regnum (operands[1])"
3071   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3072               (clobber (reg:CC FLAGS_REG))])]
3073   "")
3075 (define_expand "zero_extendqisi2"
3076   [(parallel
3077     [(set (match_operand:SI 0 "register_operand" "")
3078        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3079      (clobber (reg:CC FLAGS_REG))])]
3080   ""
3081   "")
3083 (define_insn "*zero_extendqisi2_and"
3084   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3085      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3086    (clobber (reg:CC FLAGS_REG))]
3087   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3088   "#"
3089   [(set_attr "type" "alu1")
3090    (set_attr "mode" "SI")])
3092 (define_insn "*zero_extendqisi2_movzbw_and"
3093   [(set (match_operand:SI 0 "register_operand" "=r,r")
3094      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3095    (clobber (reg:CC FLAGS_REG))]
3096   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3097   "#"
3098   [(set_attr "type" "imovx,alu1")
3099    (set_attr "mode" "SI")])
3101 (define_insn "*zero_extendqisi2_movzbw"
3102   [(set (match_operand:SI 0 "register_operand" "=r")
3103      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3104   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3105   "movz{bl|x}\t{%1, %0|%0, %1}"
3106   [(set_attr "type" "imovx")
3107    (set_attr "mode" "SI")])
3109 ;; For the movzbl case strip only the clobber
3110 (define_split
3111   [(set (match_operand:SI 0 "register_operand" "")
3112         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113    (clobber (reg:CC FLAGS_REG))]
3114   "reload_completed 
3115    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3116    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3117   [(set (match_dup 0)
3118         (zero_extend:SI (match_dup 1)))])
3120 ;; When source and destination does not overlap, clear destination
3121 ;; first and then do the movb
3122 (define_split
3123   [(set (match_operand:SI 0 "register_operand" "")
3124         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3125    (clobber (reg:CC FLAGS_REG))]
3126   "reload_completed
3127    && ANY_QI_REG_P (operands[0])
3128    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3129    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3130    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3131   [(set (match_dup 0) (const_int 0))
3132    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3133   "operands[2] = gen_lowpart (QImode, operands[0]);")
3135 ;; Rest is handled by single and.
3136 (define_split
3137   [(set (match_operand:SI 0 "register_operand" "")
3138         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3139    (clobber (reg:CC FLAGS_REG))]
3140   "reload_completed
3141    && true_regnum (operands[0]) == true_regnum (operands[1])"
3142   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3143               (clobber (reg:CC FLAGS_REG))])]
3144   "")
3146 ;; %%% Kill me once multi-word ops are sane.
3147 (define_expand "zero_extendsidi2"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3150   ""
3151   "if (!TARGET_64BIT)
3152      {
3153        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3154        DONE;
3155      }
3156   ")
3158 (define_insn "zero_extendsidi2_32"
3159   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3160         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3161    (clobber (reg:CC FLAGS_REG))]
3162   "!TARGET_64BIT"
3163   "@
3164    #
3165    #
3166    #
3167    movd\t{%1, %0|%0, %1}
3168    movd\t{%1, %0|%0, %1}"
3169   [(set_attr "mode" "SI,SI,SI,DI,TI")
3170    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3172 (define_insn "zero_extendsidi2_rex64"
3173   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3174      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3175   "TARGET_64BIT"
3176   "@
3177    mov\t{%k1, %k0|%k0, %k1}
3178    #
3179    movd\t{%1, %0|%0, %1}
3180    movd\t{%1, %0|%0, %1}"
3181   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3182    (set_attr "mode" "SI,DI,SI,SI")])
3184 (define_split
3185   [(set (match_operand:DI 0 "memory_operand" "")
3186      (zero_extend:DI (match_dup 0)))]
3187   "TARGET_64BIT"
3188   [(set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191 (define_split 
3192   [(set (match_operand:DI 0 "register_operand" "")
3193         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3194    (clobber (reg:CC FLAGS_REG))]
3195   "!TARGET_64BIT && reload_completed
3196    && true_regnum (operands[0]) == true_regnum (operands[1])"
3197   [(set (match_dup 4) (const_int 0))]
3198   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200 (define_split 
3201   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3202         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT && reload_completed
3205    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3206   [(set (match_dup 3) (match_dup 1))
3207    (set (match_dup 4) (const_int 0))]
3208   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210 (define_insn "zero_extendhidi2"
3211   [(set (match_operand:DI 0 "register_operand" "=r")
3212      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3213   "TARGET_64BIT"
3214   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3215   [(set_attr "type" "imovx")
3216    (set_attr "mode" "DI")])
3218 (define_insn "zero_extendqidi2"
3219   [(set (match_operand:DI 0 "register_operand" "=r")
3220      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3221   "TARGET_64BIT"
3222   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3223   [(set_attr "type" "imovx")
3224    (set_attr "mode" "DI")])
3226 ;; Sign extension instructions
3228 (define_expand "extendsidi2"
3229   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231               (clobber (reg:CC FLAGS_REG))
3232               (clobber (match_scratch:SI 2 ""))])]
3233   ""
3235   if (TARGET_64BIT)
3236     {
3237       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3238       DONE;
3239     }
3242 (define_insn "*extendsidi2_1"
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245    (clobber (reg:CC FLAGS_REG))
3246    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3247   "!TARGET_64BIT"
3248   "#")
3250 (define_insn "extendsidi2_rex64"
3251   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3253   "TARGET_64BIT"
3254   "@
3255    {cltq|cdqe}
3256    movs{lq|x}\t{%1,%0|%0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")
3259    (set_attr "prefix_0f" "0")
3260    (set_attr "modrm" "0,1")])
3262 (define_insn "extendhidi2"
3263   [(set (match_operand:DI 0 "register_operand" "=r")
3264         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265   "TARGET_64BIT"
3266   "movs{wq|x}\t{%1,%0|%0, %1}"
3267   [(set_attr "type" "imovx")
3268    (set_attr "mode" "DI")])
3270 (define_insn "extendqidi2"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3273   "TARGET_64BIT"
3274   "movs{bq|x}\t{%1,%0|%0, %1}"
3275    [(set_attr "type" "imovx")
3276     (set_attr "mode" "DI")])
3278 ;; Extend to memory case when source register does die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "(reload_completed
3285     && dead_or_set_p (insn, operands[1])
3286     && !reg_mentioned_p (operands[1], operands[0]))"
3287   [(set (match_dup 3) (match_dup 1))
3288    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289               (clobber (reg:CC FLAGS_REG))])
3290    (set (match_dup 4) (match_dup 1))]
3291   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293 ;; Extend to memory case when source register does not die.
3294 (define_split 
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))
3298    (clobber (match_operand:SI 2 "register_operand" ""))]
3299   "reload_completed"
3300   [(const_int 0)]
3302   split_di (&operands[0], 1, &operands[3], &operands[4]);
3304   emit_move_insn (operands[3], operands[1]);
3306   /* Generate a cltd if possible and doing so it profitable.  */
3307   if (true_regnum (operands[1]) == 0
3308       && true_regnum (operands[2]) == 1
3309       && (optimize_size || TARGET_USE_CLTD))
3310     {
3311       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3312     }
3313   else
3314     {
3315       emit_move_insn (operands[2], operands[1]);
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3317     }
3318   emit_move_insn (operands[4], operands[2]);
3319   DONE;
3322 ;; Extend to register case.  Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3324 (define_split 
3325   [(set (match_operand:DI 0 "register_operand" "")
3326         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327    (clobber (reg:CC FLAGS_REG))
3328    (clobber (match_scratch:SI 2 ""))]
3329   "reload_completed"
3330   [(const_int 0)]
3332   split_di (&operands[0], 1, &operands[3], &operands[4]);
3334   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335     emit_move_insn (operands[3], operands[1]);
3337   /* Generate a cltd if possible and doing so it profitable.  */
3338   if (true_regnum (operands[3]) == 0
3339       && (optimize_size || TARGET_USE_CLTD))
3340     {
3341       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3342       DONE;
3343     }
3345   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346     emit_move_insn (operands[4], operands[1]);
3348   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3349   DONE;
3352 (define_insn "extendhisi2"
3353   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355   ""
3357   switch (get_attr_prefix_0f (insn))
3358     {
3359     case 0:
3360       return "{cwtl|cwde}";
3361     default:
3362       return "movs{wl|x}\t{%1,%0|%0, %1}";
3363     }
3365   [(set_attr "type" "imovx")
3366    (set_attr "mode" "SI")
3367    (set (attr "prefix_0f")
3368      ;; movsx is short decodable while cwtl is vector decoded.
3369      (if_then_else (and (eq_attr "cpu" "!k6")
3370                         (eq_attr "alternative" "0"))
3371         (const_string "0")
3372         (const_string "1")))
3373    (set (attr "modrm")
3374      (if_then_else (eq_attr "prefix_0f" "0")
3375         (const_string "0")
3376         (const_string "1")))])
3378 (define_insn "*extendhisi2_zext"
3379   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3380         (zero_extend:DI
3381           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382   "TARGET_64BIT"
3384   switch (get_attr_prefix_0f (insn))
3385     {
3386     case 0:
3387       return "{cwtl|cwde}";
3388     default:
3389       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390     }
3392   [(set_attr "type" "imovx")
3393    (set_attr "mode" "SI")
3394    (set (attr "prefix_0f")
3395      ;; movsx is short decodable while cwtl is vector decoded.
3396      (if_then_else (and (eq_attr "cpu" "!k6")
3397                         (eq_attr "alternative" "0"))
3398         (const_string "0")
3399         (const_string "1")))
3400    (set (attr "modrm")
3401      (if_then_else (eq_attr "prefix_0f" "0")
3402         (const_string "0")
3403         (const_string "1")))])
3405 (define_insn "extendqihi2"
3406   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408   ""
3410   switch (get_attr_prefix_0f (insn))
3411     {
3412     case 0:
3413       return "{cbtw|cbw}";
3414     default:
3415       return "movs{bw|x}\t{%1,%0|%0, %1}";
3416     }
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "HI")
3420    (set (attr "prefix_0f")
3421      ;; movsx is short decodable while cwtl is vector decoded.
3422      (if_then_else (and (eq_attr "cpu" "!k6")
3423                         (eq_attr "alternative" "0"))
3424         (const_string "0")
3425         (const_string "1")))
3426    (set (attr "modrm")
3427      (if_then_else (eq_attr "prefix_0f" "0")
3428         (const_string "0")
3429         (const_string "1")))])
3431 (define_insn "extendqisi2"
3432   [(set (match_operand:SI 0 "register_operand" "=r")
3433         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3434   ""
3435   "movs{bl|x}\t{%1,%0|%0, %1}"
3436    [(set_attr "type" "imovx")
3437     (set_attr "mode" "SI")])
3439 (define_insn "*extendqisi2_zext"
3440   [(set (match_operand:DI 0 "register_operand" "=r")
3441         (zero_extend:DI
3442           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3443   "TARGET_64BIT"
3444   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445    [(set_attr "type" "imovx")
3446     (set_attr "mode" "SI")])
3448 ;; Conversions between float and double.
3450 ;; These are all no-ops in the model used for the 80387.  So just
3451 ;; emit moves.
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3454 (define_insn "*dummy_extendsfdf2"
3455   [(set (match_operand:DF 0 "push_operand" "=<")
3456         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3457   "0"
3458   "#")
3460 (define_split
3461   [(set (match_operand:DF 0 "push_operand" "")
3462         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463   "!TARGET_64BIT"
3464   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3467 (define_split
3468   [(set (match_operand:DF 0 "push_operand" "")
3469         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3470   "TARGET_64BIT"
3471   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3474 (define_insn "*dummy_extendsfxf2"
3475   [(set (match_operand:XF 0 "push_operand" "=<")
3476         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3477   "0"
3478   "#")
3480 (define_split
3481   [(set (match_operand:XF 0 "push_operand" "")
3482         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3483   ""
3484   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488 (define_split
3489   [(set (match_operand:XF 0 "push_operand" "")
3490         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3491   "TARGET_64BIT"
3492   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496 (define_split
3497   [(set (match_operand:XF 0 "push_operand" "")
3498         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3499   ""
3500   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3504 (define_split
3505   [(set (match_operand:XF 0 "push_operand" "")
3506         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3507   "TARGET_64BIT"
3508   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3512 (define_expand "extendsfdf2"
3513   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3517   /* ??? Needed for compress_float_constant since all fp constants
3518      are LEGITIMATE_CONSTANT_P.  */
3519   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522     operands[1] = force_reg (SFmode, operands[1]);
3525 (define_insn "*extendsfdf2_mixed"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531   switch (which_alternative)
3532     {
3533     case 0:
3534       return output_387_reg_move (insn, operands);
3536     case 1:
3537       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538         return "fstp%z0\t%y0";
3539       else
3540         return "fst%z0\t%y0";
3542     case 2:
3543       return "cvtss2sd\t{%1, %0|%0, %1}";
3545     default:
3546       gcc_unreachable ();
3547     }
3549   [(set_attr "type" "fmov,fmov,ssecvt")
3550    (set_attr "mode" "SF,XF,DF")])
3552 (define_insn "*extendsfdf2_sse"
3553   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555   "TARGET_SSE2 && TARGET_SSE_MATH
3556    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557   "cvtss2sd\t{%1, %0|%0, %1}"
3558   [(set_attr "type" "ssecvt")
3559    (set_attr "mode" "DF")])
3561 (define_insn "*extendsfdf2_i387"
3562   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3564   "TARGET_80387
3565    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567   switch (which_alternative)
3568     {
3569     case 0:
3570       return output_387_reg_move (insn, operands);
3572     case 1:
3573       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574         return "fstp%z0\t%y0";
3575       else
3576         return "fst%z0\t%y0";
3578     default:
3579       gcc_unreachable ();
3580     }
3582   [(set_attr "type" "fmov")
3583    (set_attr "mode" "SF,XF")])
3585 (define_expand "extendsfxf2"
3586   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588   "TARGET_80387"
3590   /* ??? Needed for compress_float_constant since all fp constants
3591      are LEGITIMATE_CONSTANT_P.  */
3592   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595     operands[1] = force_reg (SFmode, operands[1]);
3598 (define_insn "*extendsfxf2_i387"
3599   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3601   "TARGET_80387
3602    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3604   switch (which_alternative)
3605     {
3606     case 0:
3607       return output_387_reg_move (insn, operands);
3609     case 1:
3610       /* There is no non-popping store to memory for XFmode.  So if
3611          we need one, follow the store with a load.  */
3612       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613         return "fstp%z0\t%y0";
3614       else
3615         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3617     default:
3618       gcc_unreachable ();
3619     }
3621   [(set_attr "type" "fmov")
3622    (set_attr "mode" "SF,XF")])
3624 (define_expand "extenddfxf2"
3625   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627   "TARGET_80387"
3629   /* ??? Needed for compress_float_constant since all fp constants
3630      are LEGITIMATE_CONSTANT_P.  */
3631   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634     operands[1] = force_reg (DFmode, operands[1]);
3637 (define_insn "*extenddfxf2_i387"
3638   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3640   "TARGET_80387
3641    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3643   switch (which_alternative)
3644     {
3645     case 0:
3646       return output_387_reg_move (insn, operands);
3648     case 1:
3649       /* There is no non-popping store to memory for XFmode.  So if
3650          we need one, follow the store with a load.  */
3651       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3653       else
3654         return "fstp%z0\t%y0";
3656     default:
3657       gcc_unreachable ();
3658     }
3660   [(set_attr "type" "fmov")
3661    (set_attr "mode" "DF,XF")])
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case.  Otherwise this is just like a simple move
3666 ;; insn.  So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3669 ;; Conversion from DFmode to SFmode.
3671 (define_expand "truncdfsf2"
3672   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3673         (float_truncate:SF
3674           (match_operand:DF 1 "nonimmediate_operand" "")))]
3675   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3677   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678     operands[1] = force_reg (DFmode, operands[1]);
3680   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3681     ;
3682   else if (flag_unsafe_math_optimizations)
3683     ;
3684   else
3685     {
3686       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3687       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3688       DONE;
3689     }
3692 (define_expand "truncdfsf2_with_temp"
3693   [(parallel [(set (match_operand:SF 0 "" "")
3694                    (float_truncate:SF (match_operand:DF 1 "" "")))
3695               (clobber (match_operand:SF 2 "" ""))])]
3696   "")
3698 (define_insn "*truncdfsf_fast_mixed"
3699   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3700         (float_truncate:SF
3701           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708         return "fstp%z0\t%y0";
3709       else
3710         return "fst%z0\t%y0";
3711     case 1:
3712       return output_387_reg_move (insn, operands);
3713     case 2:
3714       return "cvtsd2ss\t{%1, %0|%0, %1}";
3715     default:
3716       gcc_unreachable ();
3717     }
3719   [(set_attr "type" "fmov,fmov,ssecvt")
3720    (set_attr "mode" "SF")])
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3726         (float_truncate:SF
3727           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728   "TARGET_SSE2 && TARGET_SSE_MATH"
3729   "cvtsd2ss\t{%1, %0|%0, %1}"
3730   [(set_attr "type" "ssecvt")
3731    (set_attr "mode" "SF")])
3733 (define_insn "*truncdfsf_fast_i387"
3734   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3735         (float_truncate:SF
3736           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737   "TARGET_80387 && flag_unsafe_math_optimizations"
3738   "* return output_387_reg_move (insn, operands);"
3739   [(set_attr "type" "fmov")
3740    (set_attr "mode" "SF")])
3742 (define_insn "*truncdfsf_mixed"
3743   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3744         (float_truncate:SF
3745           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3746    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3747   "TARGET_MIX_SSE_I387"
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753         return "fstp%z0\t%y0";
3754       else
3755         return "fst%z0\t%y0";
3756     case 1:
3757       return "#";
3758     case 2:
3759       return "cvtsd2ss\t{%1, %0|%0, %1}";
3760     default:
3761       gcc_unreachable ();
3762     }
3764   [(set_attr "type" "fmov,multi,ssecvt")
3765    (set_attr "unit" "*,i387,*")
3766    (set_attr "mode" "SF")])
3768 (define_insn "*truncdfsf_i387"
3769   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3770         (float_truncate:SF
3771           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3772    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3773   "TARGET_80387"
3775   switch (which_alternative)
3776     {
3777     case 0:
3778       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779         return "fstp%z0\t%y0";
3780       else
3781         return "fst%z0\t%y0";
3782     case 1:
3783       return "#";
3784     default:
3785       gcc_unreachable ();
3786     }
3788   [(set_attr "type" "fmov,multi")
3789    (set_attr "unit" "*,i387")
3790    (set_attr "mode" "SF")])
3792 (define_insn "*truncdfsf2_i387_1"
3793   [(set (match_operand:SF 0 "memory_operand" "=m")
3794         (float_truncate:SF
3795           (match_operand:DF 1 "register_operand" "f")))]
3796   "TARGET_80387
3797    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3798    && !TARGET_MIX_SSE_I387"
3800   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801     return "fstp%z0\t%y0";
3802   else
3803     return "fst%z0\t%y0";
3805   [(set_attr "type" "fmov")
3806    (set_attr "mode" "SF")])
3808 (define_split
3809   [(set (match_operand:SF 0 "register_operand" "")
3810         (float_truncate:SF
3811          (match_operand:DF 1 "fp_register_operand" "")))
3812    (clobber (match_operand 2 "" ""))]
3813   "reload_completed"
3814   [(set (match_dup 2) (match_dup 1))
3815    (set (match_dup 0) (match_dup 2))]
3817   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3820 ;; Conversion from XFmode to SFmode.
3822 (define_expand "truncxfsf2"
3823   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3824                    (float_truncate:SF
3825                     (match_operand:XF 1 "register_operand" "")))
3826               (clobber (match_dup 2))])]
3827   "TARGET_80387"
3829   if (flag_unsafe_math_optimizations)
3830     {
3831       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3832       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3833       if (reg != operands[0])
3834         emit_move_insn (operands[0], reg);
3835       DONE;
3836     }
3837   else
3838     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3841 (define_insn "*truncxfsf2_mixed"
3842   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3843         (float_truncate:SF
3844          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3845    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3846   "TARGET_MIX_SSE_I387"
3848   gcc_assert (!which_alternative);
3849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850     return "fstp%z0\t%y0";
3851   else
3852     return "fst%z0\t%y0";
3854   [(set_attr "type" "fmov,multi,multi,multi")
3855    (set_attr "unit" "*,i387,i387,i387")
3856    (set_attr "mode" "SF")])
3858 (define_insn "truncxfsf2_i387_noop"
3859   [(set (match_operand:SF 0 "register_operand" "=f")
3860         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3861   "TARGET_80387 && flag_unsafe_math_optimizations"
3863   return output_387_reg_move (insn, operands);
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3868 (define_insn "*truncxfsf2_i387"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3873   "TARGET_80387"
3875   gcc_assert (!which_alternative);
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878    else
3879      return "fst%z0\t%y0";
3881   [(set_attr "type" "fmov,multi,multi")
3882    (set_attr "unit" "*,i387,i387")
3883    (set_attr "mode" "SF")])
3885 (define_insn "*truncxfsf2_i387_1"
3886   [(set (match_operand:SF 0 "memory_operand" "=m")
3887         (float_truncate:SF
3888          (match_operand:XF 1 "register_operand" "f")))]
3889   "TARGET_80387"
3891   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3892     return "fstp%z0\t%y0";
3893   else
3894     return "fst%z0\t%y0";
3896   [(set_attr "type" "fmov")
3897    (set_attr "mode" "SF")])
3899 (define_split
3900   [(set (match_operand:SF 0 "register_operand" "")
3901         (float_truncate:SF
3902          (match_operand:XF 1 "register_operand" "")))
3903    (clobber (match_operand:SF 2 "memory_operand" ""))]
3904   "TARGET_80387 && reload_completed"
3905   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3906    (set (match_dup 0) (match_dup 2))]
3907   "")
3909 (define_split
3910   [(set (match_operand:SF 0 "memory_operand" "")
3911         (float_truncate:SF
3912          (match_operand:XF 1 "register_operand" "")))
3913    (clobber (match_operand:SF 2 "memory_operand" ""))]
3914   "TARGET_80387"
3915   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3916   "")
3918 ;; Conversion from XFmode to DFmode.
3920 (define_expand "truncxfdf2"
3921   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3922                    (float_truncate:DF
3923                     (match_operand:XF 1 "register_operand" "")))
3924               (clobber (match_dup 2))])]
3925   "TARGET_80387"
3927   if (flag_unsafe_math_optimizations)
3928     {
3929       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3930       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3931       if (reg != operands[0])
3932         emit_move_insn (operands[0], reg);
3933       DONE;
3934     }
3935   else
3936     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3939 (define_insn "*truncxfdf2_mixed"
3940   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3941         (float_truncate:DF
3942          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3943    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3944   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946   gcc_assert (!which_alternative);
3947   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948     return "fstp%z0\t%y0";
3949   else
3950     return "fst%z0\t%y0";
3952   [(set_attr "type" "fmov,multi,multi,multi")
3953    (set_attr "unit" "*,i387,i387,i387")
3954    (set_attr "mode" "DF")])
3956 (define_insn "truncxfdf2_i387_noop"
3957   [(set (match_operand:DF 0 "register_operand" "=f")
3958         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959   "TARGET_80387 && flag_unsafe_math_optimizations"
3961   return output_387_reg_move (insn, operands);
3963   [(set_attr "type" "fmov")
3964    (set_attr "mode" "DF")])
3966 (define_insn "*truncxfdf2_i387"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3971   "TARGET_80387"
3973   gcc_assert (!which_alternative);
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3979   [(set_attr "type" "fmov,multi,multi")
3980    (set_attr "unit" "*,i387,i387")
3981    (set_attr "mode" "DF")])
3983 (define_insn "*truncxfdf2_i387_1"
3984   [(set (match_operand:DF 0 "memory_operand" "=m")
3985         (float_truncate:DF
3986           (match_operand:XF 1 "register_operand" "f")))]
3987   "TARGET_80387"
3989   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3990     return "fstp%z0\t%y0";
3991   else
3992     return "fst%z0\t%y0";
3994   [(set_attr "type" "fmov")
3995    (set_attr "mode" "DF")])
3997 (define_split
3998   [(set (match_operand:DF 0 "register_operand" "")
3999         (float_truncate:DF
4000          (match_operand:XF 1 "register_operand" "")))
4001    (clobber (match_operand:DF 2 "memory_operand" ""))]
4002   "TARGET_80387 && reload_completed"
4003   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4004    (set (match_dup 0) (match_dup 2))]
4005   "")
4007 (define_split
4008   [(set (match_operand:DF 0 "memory_operand" "")
4009         (float_truncate:DF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:DF 2 "memory_operand" ""))]
4012   "TARGET_80387"
4013   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4014   "")
4016 ;; Signed conversion to DImode.
4018 (define_expand "fix_truncxfdi2"
4019   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4021               (clobber (reg:CC FLAGS_REG))])]
4022   "TARGET_80387"
4024   if (TARGET_FISTTP)
4025    {
4026      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4027      DONE;
4028    }
4031 (define_expand "fix_trunc<mode>di2"
4032   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4034               (clobber (reg:CC FLAGS_REG))])]
4035   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4037   if (TARGET_FISTTP
4038       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4039    {
4040      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4041      DONE;
4042    }
4043   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4044    {
4045      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4046      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4047      if (out != operands[0])
4048         emit_move_insn (operands[0], out);
4049      DONE;
4050    }
4053 ;; Signed conversion to SImode.
4055 (define_expand "fix_truncxfsi2"
4056   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4057                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4058               (clobber (reg:CC FLAGS_REG))])]
4059   "TARGET_80387"
4061   if (TARGET_FISTTP)
4062    {
4063      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4064      DONE;
4065    }
4068 (define_expand "fix_trunc<mode>si2"
4069   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))])]
4072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4074   if (TARGET_FISTTP
4075       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4076    {
4077      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4078      DONE;
4079    }
4080   if (SSE_FLOAT_MODE_P (<MODE>mode))
4081    {
4082      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4083      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4084      if (out != operands[0])
4085         emit_move_insn (operands[0], out);
4086      DONE;
4087    }
4090 ;; Signed conversion to HImode.
4092 (define_expand "fix_trunc<mode>hi2"
4093   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4094                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4095               (clobber (reg:CC FLAGS_REG))])]
4096   "TARGET_80387
4097    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4099   if (TARGET_FISTTP)
4100    {
4101      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4102      DONE;
4103    }
4106 ;; When SSE is available, it is always faster to use it!
4107 (define_insn "fix_truncsfdi_sse"
4108   [(set (match_operand:DI 0 "register_operand" "=r,r")
4109         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4110   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111   "cvttss2si{q}\t{%1, %0|%0, %1}"
4112   [(set_attr "type" "sseicvt")
4113    (set_attr "mode" "SF")
4114    (set_attr "athlon_decode" "double,vector")])
4116 (define_insn "fix_truncdfdi_sse"
4117   [(set (match_operand:DI 0 "register_operand" "=r,r")
4118         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4119   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4121   [(set_attr "type" "sseicvt")
4122    (set_attr "mode" "DF")
4123    (set_attr "athlon_decode" "double,vector")])
4125 (define_insn "fix_truncsfsi_sse"
4126   [(set (match_operand:SI 0 "register_operand" "=r,r")
4127         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4128   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129   "cvttss2si\t{%1, %0|%0, %1}"
4130   [(set_attr "type" "sseicvt")
4131    (set_attr "mode" "DF")
4132    (set_attr "athlon_decode" "double,vector")])
4134 (define_insn "fix_truncdfsi_sse"
4135   [(set (match_operand:SI 0 "register_operand" "=r,r")
4136         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4137   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttsd2si\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "DF")
4141    (set_attr "athlon_decode" "double,vector")])
4143 ;; Avoid vector decoded forms of the instruction.
4144 (define_peephole2
4145   [(match_scratch:DF 2 "Y")
4146    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4148   "TARGET_K8 && !optimize_size"
4149   [(set (match_dup 2) (match_dup 1))
4150    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4151   "")
4153 (define_peephole2
4154   [(match_scratch:SF 2 "x")
4155    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4157   "TARGET_K8 && !optimize_size"
4158   [(set (match_dup 2) (match_dup 1))
4159    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160   "")
4162 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4163   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4164         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4165   "TARGET_80387 && TARGET_FISTTP
4166    && FLOAT_MODE_P (GET_MODE (operands[1]))
4167    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4168          && (TARGET_64BIT || <MODE>mode != DImode))
4169         && TARGET_SSE_MATH)
4170    && !(reload_completed || reload_in_progress)"
4171   "#"
4172   "&& 1"
4173   [(const_int 0)]
4175   if (memory_operand (operands[0], VOIDmode))
4176     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4177   else
4178     {
4179       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4180       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4181                                                             operands[1],
4182                                                             operands[2]));
4183     }
4184   DONE;
4186   [(set_attr "type" "fisttp")
4187    (set_attr "mode" "<MODE>")])
4189 (define_insn "fix_trunc<mode>_i387_fisttp"
4190   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4191         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4192    (clobber (match_scratch:XF 2 "=&1f"))]
4193   "TARGET_80387 && TARGET_FISTTP
4194    && FLOAT_MODE_P (GET_MODE (operands[1]))
4195    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4196          && (TARGET_64BIT || <MODE>mode != DImode))
4197         && TARGET_SSE_MATH)"
4198   "* return output_fix_trunc (insn, operands, 1);"
4199   [(set_attr "type" "fisttp")
4200    (set_attr "mode" "<MODE>")])
4202 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4203   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4205    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4206    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4207   "TARGET_80387 && TARGET_FISTTP
4208    && FLOAT_MODE_P (GET_MODE (operands[1]))
4209    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4210         && (TARGET_64BIT || <MODE>mode != DImode))
4211         && TARGET_SSE_MATH)"
4212   "#"
4213   [(set_attr "type" "fisttp")
4214    (set_attr "mode" "<MODE>")])
4216 (define_split
4217   [(set (match_operand:X87MODEI 0 "register_operand" "")
4218         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4219    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4220    (clobber (match_scratch 3 ""))]
4221   "reload_completed"
4222   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4223               (clobber (match_dup 3))])
4224    (set (match_dup 0) (match_dup 2))]
4225   "")
4227 (define_split
4228   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4230    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4231    (clobber (match_scratch 3 ""))]
4232   "reload_completed"
4233   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4234               (clobber (match_dup 3))])]
4235   "")
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245    (clobber (reg:CC FLAGS_REG))]
4246   "TARGET_80387 && !TARGET_FISTTP
4247    && FLOAT_MODE_P (GET_MODE (operands[1]))
4248    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249          && (TARGET_64BIT || <MODE>mode != DImode))
4250    && !(reload_completed || reload_in_progress)"
4251   "#"
4252   "&& 1"
4253   [(const_int 0)]
4255   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4257   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259   if (memory_operand (operands[0], VOIDmode))
4260     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261                                          operands[2], operands[3]));
4262   else
4263     {
4264       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266                                                      operands[2], operands[3],
4267                                                      operands[4]));
4268     }
4269   DONE;
4271   [(set_attr "type" "fistp")
4272    (set_attr "i387_cw" "trunc")
4273    (set_attr "mode" "<MODE>")])
4275 (define_insn "fix_truncdi_i387"
4276   [(set (match_operand:DI 0 "memory_operand" "=m")
4277         (fix:DI (match_operand 1 "register_operand" "f")))
4278    (use (match_operand:HI 2 "memory_operand" "m"))
4279    (use (match_operand:HI 3 "memory_operand" "m"))
4280    (clobber (match_scratch:XF 4 "=&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "* return output_fix_trunc (insn, operands, 0);"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4289 (define_insn "fix_truncdi_i387_with_temp"
4290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:DI (match_operand 1 "register_operand" "f,f")))
4292    (use (match_operand:HI 2 "memory_operand" "m,m"))
4293    (use (match_operand:HI 3 "memory_operand" "m,m"))
4294    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296   "TARGET_80387 && !TARGET_FISTTP
4297    && FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4299   "#"
4300   [(set_attr "type" "fistp")
4301    (set_attr "i387_cw" "trunc")
4302    (set_attr "mode" "DI")])
4304 (define_split 
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])
4316    (set (match_dup 0) (match_dup 4))]
4317   "")
4319 (define_split 
4320   [(set (match_operand:DI 0 "memory_operand" "")
4321         (fix:DI (match_operand 1 "register_operand" "")))
4322    (use (match_operand:HI 2 "memory_operand" ""))
4323    (use (match_operand:HI 3 "memory_operand" ""))
4324    (clobber (match_operand:DI 4 "memory_operand" ""))
4325    (clobber (match_scratch 5 ""))]
4326   "reload_completed"
4327   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328               (use (match_dup 2))
4329               (use (match_dup 3))
4330               (clobber (match_dup 5))])]
4331   "")
4333 (define_insn "fix_trunc<mode>_i387"
4334   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336    (use (match_operand:HI 2 "memory_operand" "m"))
4337    (use (match_operand:HI 3 "memory_operand" "m"))]
4338   "TARGET_80387 && !TARGET_FISTTP
4339    && FLOAT_MODE_P (GET_MODE (operands[1]))
4340    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341   "* return output_fix_trunc (insn, operands, 0);"
4342   [(set_attr "type" "fistp")
4343    (set_attr "i387_cw" "trunc")
4344    (set_attr "mode" "<MODE>")])
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349    (use (match_operand:HI 2 "memory_operand" "m,m"))
4350    (use (match_operand:HI 3 "memory_operand" "m,m"))
4351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352   "TARGET_80387 && !TARGET_FISTTP
4353    && FLOAT_MODE_P (GET_MODE (operands[1]))
4354    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4355   "#"
4356   [(set_attr "type" "fistp")
4357    (set_attr "i387_cw" "trunc")
4358    (set_attr "mode" "<MODE>")])
4360 (define_split 
4361   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363    (use (match_operand:HI 2 "memory_operand" ""))
4364    (use (match_operand:HI 3 "memory_operand" ""))
4365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4366   "reload_completed"
4367   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4368               (use (match_dup 2))
4369               (use (match_dup 3))])
4370    (set (match_dup 0) (match_dup 4))]
4371   "")
4373 (define_split 
4374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376    (use (match_operand:HI 2 "memory_operand" ""))
4377    (use (match_operand:HI 3 "memory_operand" ""))
4378    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4379   "reload_completed"
4380   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4381               (use (match_dup 2))
4382               (use (match_dup 3))])]
4383   "")
4385 (define_insn "x86_fnstcw_1"
4386   [(set (match_operand:HI 0 "memory_operand" "=m")
4387         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388   "TARGET_80387"
4389   "fnstcw\t%0"
4390   [(set_attr "length" "2")
4391    (set_attr "mode" "HI")
4392    (set_attr "unit" "i387")])
4394 (define_insn "x86_fldcw_1"
4395   [(set (reg:HI FPSR_REG)
4396         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397   "TARGET_80387"
4398   "fldcw\t%0"
4399   [(set_attr "length" "2")
4400    (set_attr "mode" "HI")
4401    (set_attr "unit" "i387")
4402    (set_attr "athlon_decode" "vector")])
4404 ;; Conversion between fixed point and floating point.
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4409 (define_expand "floathisf2"
4410   [(set (match_operand:SF 0 "register_operand" "")
4411         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412   "TARGET_80387 || TARGET_SSE_MATH"
4414   if (TARGET_SSE_MATH)
4415     {
4416       emit_insn (gen_floatsisf2 (operands[0],
4417                                  convert_to_mode (SImode, operands[1], 0)));
4418       DONE;
4419     }
4422 (define_insn "*floathisf2_i387"
4423   [(set (match_operand:SF 0 "register_operand" "=f,f")
4424         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4426   "@
4427    fild%z1\t%1
4428    #"
4429   [(set_attr "type" "fmov,multi")
4430    (set_attr "mode" "SF")
4431    (set_attr "unit" "*,i387")
4432    (set_attr "fp_int_src" "true")])
4434 (define_expand "floatsisf2"
4435   [(set (match_operand:SF 0 "register_operand" "")
4436         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4437   "TARGET_80387 || TARGET_SSE_MATH"
4438   "")
4440 (define_insn "*floatsisf2_mixed"
4441   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4443   "TARGET_MIX_SSE_I387"
4444   "@
4445    fild%z1\t%1
4446    #
4447    cvtsi2ss\t{%1, %0|%0, %1}
4448    cvtsi2ss\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4450    (set_attr "mode" "SF")
4451    (set_attr "unit" "*,i387,*,*")
4452    (set_attr "athlon_decode" "*,*,vector,double")
4453    (set_attr "fp_int_src" "true")])
4455 (define_insn "*floatsisf2_sse"
4456   [(set (match_operand:SF 0 "register_operand" "=x,x")
4457         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4458   "TARGET_SSE_MATH"
4459   "cvtsi2ss\t{%1, %0|%0, %1}"
4460   [(set_attr "type" "sseicvt")
4461    (set_attr "mode" "SF")
4462    (set_attr "athlon_decode" "vector,double")
4463    (set_attr "fp_int_src" "true")])
4465 (define_insn "*floatsisf2_i387"
4466   [(set (match_operand:SF 0 "register_operand" "=f,f")
4467         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4468   "TARGET_80387"
4469   "@
4470    fild%z1\t%1
4471    #"
4472   [(set_attr "type" "fmov,multi")
4473    (set_attr "mode" "SF")
4474    (set_attr "unit" "*,i387")
4475    (set_attr "fp_int_src" "true")])
4477 (define_expand "floatdisf2"
4478   [(set (match_operand:SF 0 "register_operand" "")
4479         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4480   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4481   "")
4483 (define_insn "*floatdisf2_mixed"
4484   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4487   "@
4488    fild%z1\t%1
4489    #
4490    cvtsi2ss{q}\t{%1, %0|%0, %1}
4491    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493    (set_attr "mode" "SF")
4494    (set_attr "unit" "*,i387,*,*")
4495    (set_attr "athlon_decode" "*,*,vector,double")
4496    (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatdisf2_sse"
4499   [(set (match_operand:SF 0 "register_operand" "=x,x")
4500         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501   "TARGET_64BIT && TARGET_SSE_MATH"
4502   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503   [(set_attr "type" "sseicvt")
4504    (set_attr "mode" "SF")
4505    (set_attr "athlon_decode" "vector,double")
4506    (set_attr "fp_int_src" "true")])
4508 (define_insn "*floatdisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "unit" "*,i387")
4518    (set_attr "fp_int_src" "true")])
4520 (define_expand "floathidf2"
4521   [(set (match_operand:DF 0 "register_operand" "")
4522         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4523   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4525   if (TARGET_SSE2 && TARGET_SSE_MATH)
4526     {
4527       emit_insn (gen_floatsidf2 (operands[0],
4528                                  convert_to_mode (SImode, operands[1], 0)));
4529       DONE;
4530     }
4533 (define_insn "*floathidf2_i387"
4534   [(set (match_operand:DF 0 "register_operand" "=f,f")
4535         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4536   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4537   "@
4538    fild%z1\t%1
4539    #"
4540   [(set_attr "type" "fmov,multi")
4541    (set_attr "mode" "DF")
4542    (set_attr "unit" "*,i387")
4543    (set_attr "fp_int_src" "true")])
4545 (define_expand "floatsidf2"
4546   [(set (match_operand:DF 0 "register_operand" "")
4547         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549   "")
4551 (define_insn "*floatsidf2_mixed"
4552   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4555   "@
4556    fild%z1\t%1
4557    #
4558    cvtsi2sd\t{%1, %0|%0, %1}
4559    cvtsi2sd\t{%1, %0|%0, %1}"
4560   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561    (set_attr "mode" "DF")
4562    (set_attr "unit" "*,i387,*,*")
4563    (set_attr "athlon_decode" "*,*,double,direct")
4564    (set_attr "fp_int_src" "true")])
4566 (define_insn "*floatsidf2_sse"
4567   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4568         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_SSE2 && TARGET_SSE_MATH"
4570   "cvtsi2sd\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "DF")
4573    (set_attr "athlon_decode" "double,direct")
4574    (set_attr "fp_int_src" "true")])
4576 (define_insn "*floatsidf2_i387"
4577   [(set (match_operand:DF 0 "register_operand" "=f,f")
4578         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4579   "TARGET_80387"
4580   "@
4581    fild%z1\t%1
4582    #"
4583   [(set_attr "type" "fmov,multi")
4584    (set_attr "mode" "DF")
4585    (set_attr "unit" "*,i387")
4586    (set_attr "fp_int_src" "true")])
4588 (define_expand "floatdidf2"
4589   [(set (match_operand:DF 0 "register_operand" "")
4590         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4591   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4592   "")
4594 (define_insn "*floatdidf2_mixed"
4595   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4598   "@
4599    fild%z1\t%1
4600    #
4601    cvtsi2sd{q}\t{%1, %0|%0, %1}
4602    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4603   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604    (set_attr "mode" "DF")
4605    (set_attr "unit" "*,i387,*,*")
4606    (set_attr "athlon_decode" "*,*,double,direct")
4607    (set_attr "fp_int_src" "true")])
4609 (define_insn "*floatdidf2_sse"
4610   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4611         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4612   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4613   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4614   [(set_attr "type" "sseicvt")
4615    (set_attr "mode" "DF")
4616    (set_attr "athlon_decode" "double,direct")
4617    (set_attr "fp_int_src" "true")])
4619 (define_insn "*floatdidf2_i387"
4620   [(set (match_operand:DF 0 "register_operand" "=f,f")
4621         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4622   "TARGET_80387"
4623   "@
4624    fild%z1\t%1
4625    #"
4626   [(set_attr "type" "fmov,multi")
4627    (set_attr "mode" "DF")
4628    (set_attr "unit" "*,i387")
4629    (set_attr "fp_int_src" "true")])
4631 (define_insn "floathixf2"
4632   [(set (match_operand:XF 0 "register_operand" "=f,f")
4633         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4634   "TARGET_80387"
4635   "@
4636    fild%z1\t%1
4637    #"
4638   [(set_attr "type" "fmov,multi")
4639    (set_attr "mode" "XF")
4640    (set_attr "unit" "*,i387")
4641    (set_attr "fp_int_src" "true")])
4643 (define_insn "floatsixf2"
4644   [(set (match_operand:XF 0 "register_operand" "=f,f")
4645         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4646   "TARGET_80387"
4647   "@
4648    fild%z1\t%1
4649    #"
4650   [(set_attr "type" "fmov,multi")
4651    (set_attr "mode" "XF")
4652    (set_attr "unit" "*,i387")
4653    (set_attr "fp_int_src" "true")])
4655 (define_insn "floatdixf2"
4656   [(set (match_operand:XF 0 "register_operand" "=f,f")
4657         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4658   "TARGET_80387"
4659   "@
4660    fild%z1\t%1
4661    #"
4662   [(set_attr "type" "fmov,multi")
4663    (set_attr "mode" "XF")
4664    (set_attr "unit" "*,i387")
4665    (set_attr "fp_int_src" "true")])
4667 ;; %%% Kill these when reload knows how to do it.
4668 (define_split
4669   [(set (match_operand 0 "fp_register_operand" "")
4670         (float (match_operand 1 "register_operand" "")))]
4671   "reload_completed
4672    && TARGET_80387
4673    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4674   [(const_int 0)]
4676   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4677   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4678   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4679   ix86_free_from_memory (GET_MODE (operands[1]));
4680   DONE;
4683 (define_expand "floatunssisf2"
4684   [(use (match_operand:SF 0 "register_operand" ""))
4685    (use (match_operand:SI 1 "register_operand" ""))]
4686   "!TARGET_64BIT && TARGET_SSE_MATH"
4687   "x86_emit_floatuns (operands); DONE;")
4689 (define_expand "floatunsdisf2"
4690   [(use (match_operand:SF 0 "register_operand" ""))
4691    (use (match_operand:DI 1 "register_operand" ""))]
4692   "TARGET_64BIT && TARGET_SSE_MATH"
4693   "x86_emit_floatuns (operands); DONE;")
4695 (define_expand "floatunsdidf2"
4696   [(use (match_operand:DF 0 "register_operand" ""))
4697    (use (match_operand:DI 1 "register_operand" ""))]
4698   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699   "x86_emit_floatuns (operands); DONE;")
4701 ;; SSE extract/set expanders
4704 ;; Add instructions
4706 ;; %%% splits for addditi3
4708 (define_expand "addti3"
4709   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4711                  (match_operand:TI 2 "x86_64_general_operand" "")))
4712    (clobber (reg:CC FLAGS_REG))]
4713   "TARGET_64BIT"
4714   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4716 (define_insn "*addti3_1"
4717   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4719                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4720    (clobber (reg:CC FLAGS_REG))]
4721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4722   "#")
4724 (define_split
4725   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4726         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4727                  (match_operand:TI 2 "general_operand" "")))
4728    (clobber (reg:CC FLAGS_REG))]
4729   "TARGET_64BIT && reload_completed"
4730   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4731                                           UNSPEC_ADD_CARRY))
4732               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4733    (parallel [(set (match_dup 3)
4734                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4735                                      (match_dup 4))
4736                             (match_dup 5)))
4737               (clobber (reg:CC FLAGS_REG))])]
4738   "split_ti (operands+0, 1, operands+0, operands+3);
4739    split_ti (operands+1, 1, operands+1, operands+4);
4740    split_ti (operands+2, 1, operands+2, operands+5);")
4742 ;; %%% splits for addsidi3
4743 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4747 (define_expand "adddi3"
4748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750                  (match_operand:DI 2 "x86_64_general_operand" "")))
4751    (clobber (reg:CC FLAGS_REG))]
4752   ""
4753   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4755 (define_insn "*adddi3_1"
4756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4761   "#")
4763 (define_split
4764   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766                  (match_operand:DI 2 "general_operand" "")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "!TARGET_64BIT && reload_completed"
4769   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770                                           UNSPEC_ADD_CARRY))
4771               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772    (parallel [(set (match_dup 3)
4773                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774                                      (match_dup 4))
4775                             (match_dup 5)))
4776               (clobber (reg:CC FLAGS_REG))])]
4777   "split_di (operands+0, 1, operands+0, operands+3);
4778    split_di (operands+1, 1, operands+1, operands+4);
4779    split_di (operands+2, 1, operands+2, operands+5);")
4781 (define_insn "adddi3_carry_rex64"
4782   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786    (clobber (reg:CC FLAGS_REG))]
4787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788   "adc{q}\t{%2, %0|%0, %2}"
4789   [(set_attr "type" "alu")
4790    (set_attr "pent_pair" "pu")
4791    (set_attr "mode" "DI")])
4793 (define_insn "*adddi3_cc_rex64"
4794   [(set (reg:CC FLAGS_REG)
4795         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4797                    UNSPEC_ADD_CARRY))
4798    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799         (plus:DI (match_dup 1) (match_dup 2)))]
4800   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801   "add{q}\t{%2, %0|%0, %2}"
4802   [(set_attr "type" "alu")
4803    (set_attr "mode" "DI")])
4805 (define_insn "addqi3_carry"
4806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809                    (match_operand:QI 2 "general_operand" "qi,qm")))
4810    (clobber (reg:CC FLAGS_REG))]
4811   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812   "adc{b}\t{%2, %0|%0, %2}"
4813   [(set_attr "type" "alu")
4814    (set_attr "pent_pair" "pu")
4815    (set_attr "mode" "QI")])
4817 (define_insn "addhi3_carry"
4818   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821                    (match_operand:HI 2 "general_operand" "ri,rm")))
4822    (clobber (reg:CC FLAGS_REG))]
4823   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824   "adc{w}\t{%2, %0|%0, %2}"
4825   [(set_attr "type" "alu")
4826    (set_attr "pent_pair" "pu")
4827    (set_attr "mode" "HI")])
4829 (define_insn "addsi3_carry"
4830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:SI 2 "general_operand" "ri,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836   "adc{l}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "SI")])
4841 (define_insn "*addsi3_carry_zext"
4842   [(set (match_operand:DI 0 "register_operand" "=r")
4843           (zero_extend:DI 
4844             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846                      (match_operand:SI 2 "general_operand" "rim"))))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849   "adc{l}\t{%2, %k0|%k0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "pent_pair" "pu")
4852    (set_attr "mode" "SI")])
4854 (define_insn "*addsi3_cc"
4855   [(set (reg:CC FLAGS_REG)
4856         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857                     (match_operand:SI 2 "general_operand" "ri,rm")]
4858                    UNSPEC_ADD_CARRY))
4859    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860         (plus:SI (match_dup 1) (match_dup 2)))]
4861   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862   "add{l}\t{%2, %0|%0, %2}"
4863   [(set_attr "type" "alu")
4864    (set_attr "mode" "SI")])
4866 (define_insn "addqi3_cc"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:QI 2 "general_operand" "qi,qm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872         (plus:QI (match_dup 1) (match_dup 2)))]
4873   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874   "add{b}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "QI")])
4878 (define_expand "addsi3"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881                             (match_operand:SI 2 "general_operand" "")))
4882               (clobber (reg:CC FLAGS_REG))])]
4883   ""
4884   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4886 (define_insn "*lea_1"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4889   "!TARGET_64BIT"
4890   "lea{l}\t{%a1, %0|%0, %a1}"
4891   [(set_attr "type" "lea")
4892    (set_attr "mode" "SI")])
4894 (define_insn "*lea_1_rex64"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4897   "TARGET_64BIT"
4898   "lea{l}\t{%a1, %0|%0, %a1}"
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4902 (define_insn "*lea_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4906   "TARGET_64BIT"
4907   "lea{l}\t{%a1, %k0|%k0, %a1}"
4908   [(set_attr "type" "lea")
4909    (set_attr "mode" "SI")])
4911 (define_insn "*lea_2_rex64"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4914   "TARGET_64BIT"
4915   "lea{q}\t{%a1, %0|%0, %a1}"
4916   [(set_attr "type" "lea")
4917    (set_attr "mode" "DI")])
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4922 (define_insn_and_split "*lea_general_1"
4923   [(set (match_operand 0 "register_operand" "=r")
4924         (plus (plus (match_operand 1 "index_register_operand" "l")
4925                     (match_operand 2 "register_operand" "r"))
4926               (match_operand 3 "immediate_operand" "i")))]
4927   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[2] = gen_lowpart (Pmode, operands[2]);
4942   operands[3] = gen_lowpart (Pmode, operands[3]);
4943   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4944                       operands[3]);
4945   if (Pmode != SImode)
4946     pat = gen_rtx_SUBREG (SImode, pat, 0);
4947   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948   DONE;
4950   [(set_attr "type" "lea")
4951    (set_attr "mode" "SI")])
4953 (define_insn_and_split "*lea_general_1_zext"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (zero_extend:DI
4956           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957                             (match_operand:SI 2 "register_operand" "r"))
4958                    (match_operand:SI 3 "immediate_operand" "i"))))]
4959   "TARGET_64BIT"
4960   "#"
4961   "&& reload_completed"
4962   [(set (match_dup 0)
4963         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4964                                                      (match_dup 2))
4965                                             (match_dup 3)) 0)))]
4967   operands[1] = gen_lowpart (Pmode, operands[1]);
4968   operands[2] = gen_lowpart (Pmode, operands[2]);
4969   operands[3] = gen_lowpart (Pmode, operands[3]);
4971   [(set_attr "type" "lea")
4972    (set_attr "mode" "SI")])
4974 (define_insn_and_split "*lea_general_2"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (mult (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "const248_operand" "i"))
4978               (match_operand 3 "nonmemory_operand" "ri")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984        || GET_MODE (operands[3]) == VOIDmode)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4989   rtx pat;
4990   operands[0] = gen_lowpart (SImode, operands[0]);
4991   operands[1] = gen_lowpart (Pmode, operands[1]);
4992   operands[3] = gen_lowpart (Pmode, operands[3]);
4993   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4994                       operands[3]);
4995   if (Pmode != SImode)
4996     pat = gen_rtx_SUBREG (SImode, pat, 0);
4997   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998   DONE;
5000   [(set_attr "type" "lea")
5001    (set_attr "mode" "SI")])
5003 (define_insn_and_split "*lea_general_2_zext"
5004   [(set (match_operand:DI 0 "register_operand" "=r")
5005         (zero_extend:DI
5006           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007                             (match_operand:SI 2 "const248_operand" "n"))
5008                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009   "TARGET_64BIT"
5010   "#"
5011   "&& reload_completed"
5012   [(set (match_dup 0)
5013         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5014                                                      (match_dup 2))
5015                                             (match_dup 3)) 0)))]
5017   operands[1] = gen_lowpart (Pmode, operands[1]);
5018   operands[3] = gen_lowpart (Pmode, operands[3]);
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5023 (define_insn_and_split "*lea_general_3"
5024   [(set (match_operand 0 "register_operand" "=r")
5025         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026                           (match_operand 2 "const248_operand" "i"))
5027                     (match_operand 3 "register_operand" "r"))
5028               (match_operand 4 "immediate_operand" "i")))]
5029   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5034   "#"
5035   "&& reload_completed"
5036   [(const_int 0)]
5038   rtx pat;
5039   operands[0] = gen_lowpart (SImode, operands[0]);
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[3] = gen_lowpart (Pmode, operands[3]);
5042   operands[4] = gen_lowpart (Pmode, operands[4]);
5043   pat = gen_rtx_PLUS (Pmode,
5044                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5045                                                          operands[2]),
5046                                     operands[3]),
5047                       operands[4]);
5048   if (Pmode != SImode)
5049     pat = gen_rtx_SUBREG (SImode, pat, 0);
5050   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051   DONE;
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3_zext"
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (zero_extend:DI
5059           (plus:SI (plus:SI (mult:SI
5060                               (match_operand:SI 1 "index_register_operand" "l")
5061                               (match_operand:SI 2 "const248_operand" "n"))
5062                             (match_operand:SI 3 "register_operand" "r"))
5063                    (match_operand:SI 4 "immediate_operand" "i"))))]
5064   "TARGET_64BIT"
5065   "#"
5066   "&& reload_completed"
5067   [(set (match_dup 0)
5068         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069                                                               (match_dup 2))
5070                                                      (match_dup 3))
5071                                             (match_dup 4)) 0)))]
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5077   [(set_attr "type" "lea")
5078    (set_attr "mode" "SI")])
5080 (define_insn "*adddi_1_rex64"
5081   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5087   switch (get_attr_type (insn))
5088     {
5089     case TYPE_LEA:
5090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091       return "lea{q}\t{%a2, %0|%0, %a2}";
5093     case TYPE_INCDEC:
5094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5095       if (operands[2] == const1_rtx)
5096         return "inc{q}\t%0";
5097       else
5098         {
5099           gcc_assert (operands[2] == constm1_rtx);
5100           return "dec{q}\t%0";
5101         }
5103     default:
5104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5108       if (GET_CODE (operands[2]) == CONST_INT
5109           /* Avoid overflows.  */
5110           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5111           && (INTVAL (operands[2]) == 128
5112               || (INTVAL (operands[2]) < 0
5113                   && INTVAL (operands[2]) != -128)))
5114         {
5115           operands[2] = GEN_INT (-INTVAL (operands[2]));
5116           return "sub{q}\t{%2, %0|%0, %2}";
5117         }
5118       return "add{q}\t{%2, %0|%0, %2}";
5119     }
5121   [(set (attr "type")
5122      (cond [(eq_attr "alternative" "2")
5123               (const_string "lea")
5124             ; Current assemblers are broken and do not allow @GOTOFF in
5125             ; ought but a memory context.
5126             (match_operand:DI 2 "pic_symbolic_operand" "")
5127               (const_string "lea")
5128             (match_operand:DI 2 "incdec_operand" "")
5129               (const_string "incdec")
5130            ]
5131            (const_string "alu")))
5132    (set_attr "mode" "DI")])
5134 ;; Convert lea to the lea pattern to avoid flags dependency.
5135 (define_split
5136   [(set (match_operand:DI 0 "register_operand" "")
5137         (plus:DI (match_operand:DI 1 "register_operand" "")
5138                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5139    (clobber (reg:CC FLAGS_REG))]
5140   "TARGET_64BIT && reload_completed
5141    && true_regnum (operands[0]) != true_regnum (operands[1])"
5142   [(set (match_dup 0)
5143         (plus:DI (match_dup 1)
5144                  (match_dup 2)))]
5145   "")
5147 (define_insn "*adddi_2_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare
5150           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5151                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5152           (const_int 0)))                       
5153    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5154         (plus:DI (match_dup 1) (match_dup 2)))]
5155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5156    && ix86_binary_operator_ok (PLUS, DImode, operands)
5157    /* Current assemblers are broken and do not allow @GOTOFF in
5158       ought but a memory context.  */
5159    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5161   switch (get_attr_type (insn))
5162     {
5163     case TYPE_INCDEC:
5164       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else
5168         {
5169           gcc_assert (operands[2] == constm1_rtx);
5170           return "dec{q}\t%0";
5171         }
5173     default:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175       /* ???? We ought to handle there the 32bit case too
5176          - do we need new constraint?  */
5177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5179       if (GET_CODE (operands[2]) == CONST_INT
5180           /* Avoid overflows.  */
5181           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182           && (INTVAL (operands[2]) == 128
5183               || (INTVAL (operands[2]) < 0
5184                   && INTVAL (operands[2]) != -128)))
5185         {
5186           operands[2] = GEN_INT (-INTVAL (operands[2]));
5187           return "sub{q}\t{%2, %0|%0, %2}";
5188         }
5189       return "add{q}\t{%2, %0|%0, %2}";
5190     }
5192   [(set (attr "type")
5193      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194         (const_string "incdec")
5195         (const_string "alu")))
5196    (set_attr "mode" "DI")])
5198 (define_insn "*adddi_3_rex64"
5199   [(set (reg FLAGS_REG)
5200         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5201                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5202    (clobber (match_scratch:DI 0 "=r"))]
5203   "TARGET_64BIT
5204    && ix86_match_ccmode (insn, CCZmode)
5205    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5206    /* Current assemblers are broken and do not allow @GOTOFF in
5207       ought but a memory context.  */
5208    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_INCDEC:
5213       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214       if (operands[2] == const1_rtx)
5215         return "inc{q}\t%0";
5216       else
5217         {
5218           gcc_assert (operands[2] == constm1_rtx);
5219           return "dec{q}\t%0";
5220         }
5222     default:
5223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224       /* ???? We ought to handle there the 32bit case too
5225          - do we need new constraint?  */
5226       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5227          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5228       if (GET_CODE (operands[2]) == CONST_INT
5229           /* Avoid overflows.  */
5230           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5231           && (INTVAL (operands[2]) == 128
5232               || (INTVAL (operands[2]) < 0
5233                   && INTVAL (operands[2]) != -128)))
5234         {
5235           operands[2] = GEN_INT (-INTVAL (operands[2]));
5236           return "sub{q}\t{%2, %0|%0, %2}";
5237         }
5238       return "add{q}\t{%2, %0|%0, %2}";
5239     }
5241   [(set (attr "type")
5242      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5243         (const_string "incdec")
5244         (const_string "alu")))
5245    (set_attr "mode" "DI")])
5247 ; For comparisons against 1, -1 and 128, we may generate better code
5248 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5249 ; is matched then.  We can't accept general immediate, because for
5250 ; case of overflows,  the result is messed up.
5251 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5252 ; when negated.
5253 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5254 ; only for comparisons not depending on it.
5255 (define_insn "*adddi_4_rex64"
5256   [(set (reg FLAGS_REG)
5257         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5258                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5259    (clobber (match_scratch:DI 0 "=rm"))]
5260   "TARGET_64BIT
5261    &&  ix86_match_ccmode (insn, CCGCmode)"
5263   switch (get_attr_type (insn))
5264     {
5265     case TYPE_INCDEC:
5266       if (operands[2] == constm1_rtx)
5267         return "inc{q}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == const1_rtx);
5271           return "dec{q}\t%0";
5272         }
5274     default:
5275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5278       if ((INTVAL (operands[2]) == -128
5279            || (INTVAL (operands[2]) > 0
5280                && INTVAL (operands[2]) != 128))
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5283         return "sub{q}\t{%2, %0|%0, %2}";
5284       operands[2] = GEN_INT (-INTVAL (operands[2]));
5285       return "add{q}\t{%2, %0|%0, %2}";
5286     }
5288   [(set (attr "type")
5289      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290         (const_string "incdec")
5291         (const_string "alu")))
5292    (set_attr "mode" "DI")])
5294 (define_insn "*adddi_5_rex64"
5295   [(set (reg FLAGS_REG)
5296         (compare
5297           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5298                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5299           (const_int 0)))                       
5300    (clobber (match_scratch:DI 0 "=r"))]
5301   "TARGET_64BIT
5302    && ix86_match_ccmode (insn, CCGOCmode)
5303    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5304    /* Current assemblers are broken and do not allow @GOTOFF in
5305       ought but a memory context.  */
5306    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5308   switch (get_attr_type (insn))
5309     {
5310     case TYPE_INCDEC:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       if (operands[2] == const1_rtx)
5313         return "inc{q}\t%0";
5314       else
5315         {
5316           gcc_assert (operands[2] == constm1_rtx);
5317           return "dec{q}\t%0";
5318         }
5320     default:
5321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5324       if (GET_CODE (operands[2]) == CONST_INT
5325           /* Avoid overflows.  */
5326           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327           && (INTVAL (operands[2]) == 128
5328               || (INTVAL (operands[2]) < 0
5329                   && INTVAL (operands[2]) != -128)))
5330         {
5331           operands[2] = GEN_INT (-INTVAL (operands[2]));
5332           return "sub{q}\t{%2, %0|%0, %2}";
5333         }
5334       return "add{q}\t{%2, %0|%0, %2}";
5335     }
5337   [(set (attr "type")
5338      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339         (const_string "incdec")
5340         (const_string "alu")))
5341    (set_attr "mode" "DI")])
5344 (define_insn "*addsi_1"
5345   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355       return "lea{l}\t{%a2, %0|%0, %a2}";
5357     case TYPE_INCDEC:
5358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359       if (operands[2] == const1_rtx)
5360         return "inc{l}\t%0";
5361       else
5362         {
5363           gcc_assert (operands[2] == constm1_rtx);
5364           return "dec{l}\t%0";
5365         }
5367     default:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           && (INTVAL (operands[2]) == 128
5374               || (INTVAL (operands[2]) < 0
5375                   && INTVAL (operands[2]) != -128)))
5376         {
5377           operands[2] = GEN_INT (-INTVAL (operands[2]));
5378           return "sub{l}\t{%2, %0|%0, %2}";
5379         }
5380       return "add{l}\t{%2, %0|%0, %2}";
5381     }
5383   [(set (attr "type")
5384      (cond [(eq_attr "alternative" "2")
5385               (const_string "lea")
5386             ; Current assemblers are broken and do not allow @GOTOFF in
5387             ; ought but a memory context.
5388             (match_operand:SI 2 "pic_symbolic_operand" "")
5389               (const_string "lea")
5390             (match_operand:SI 2 "incdec_operand" "")
5391               (const_string "incdec")
5392            ]
5393            (const_string "alu")))
5394    (set_attr "mode" "SI")])
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5397 (define_split
5398   [(set (match_operand 0 "register_operand" "")
5399         (plus (match_operand 1 "register_operand" "")
5400               (match_operand 2 "nonmemory_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "reload_completed
5403    && true_regnum (operands[0]) != true_regnum (operands[1])"
5404   [(const_int 0)]
5406   rtx pat;
5407   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5408      may confuse gen_lowpart.  */
5409   if (GET_MODE (operands[0]) != Pmode)
5410     {
5411       operands[1] = gen_lowpart (Pmode, operands[1]);
5412       operands[2] = gen_lowpart (Pmode, operands[2]);
5413     }
5414   operands[0] = gen_lowpart (SImode, operands[0]);
5415   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5416   if (Pmode != SImode)
5417     pat = gen_rtx_SUBREG (SImode, pat, 0);
5418   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5419   DONE;
5422 ;; It may seem that nonimmediate operand is proper one for operand 1.
5423 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5424 ;; we take care in ix86_binary_operator_ok to not allow two memory
5425 ;; operands so proper swapping will be done in reload.  This allow
5426 ;; patterns constructed from addsi_1 to match.
5427 (define_insn "addsi_1_zext"
5428   [(set (match_operand:DI 0 "register_operand" "=r,r")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5431                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435   switch (get_attr_type (insn))
5436     {
5437     case TYPE_LEA:
5438       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5439       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5441     case TYPE_INCDEC:
5442       if (operands[2] == const1_rtx)
5443         return "inc{l}\t%k0";
5444       else
5445         {
5446           gcc_assert (operands[2] == constm1_rtx);
5447           return "dec{l}\t%k0";
5448         }
5450     default:
5451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5453       if (GET_CODE (operands[2]) == CONST_INT
5454           && (INTVAL (operands[2]) == 128
5455               || (INTVAL (operands[2]) < 0
5456                   && INTVAL (operands[2]) != -128)))
5457         {
5458           operands[2] = GEN_INT (-INTVAL (operands[2]));
5459           return "sub{l}\t{%2, %k0|%k0, %2}";
5460         }
5461       return "add{l}\t{%2, %k0|%k0, %2}";
5462     }
5464   [(set (attr "type")
5465      (cond [(eq_attr "alternative" "1")
5466               (const_string "lea")
5467             ; Current assemblers are broken and do not allow @GOTOFF in
5468             ; ought but a memory context.
5469             (match_operand:SI 2 "pic_symbolic_operand" "")
5470               (const_string "lea")
5471             (match_operand:SI 2 "incdec_operand" "")
5472               (const_string "incdec")
5473            ]
5474            (const_string "alu")))
5475    (set_attr "mode" "SI")])
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479   [(set (match_operand:DI 0 "register_operand" "")
5480         (zero_extend:DI
5481           (plus:SI (match_operand:SI 1 "register_operand" "")
5482                    (match_operand:SI 2 "nonmemory_operand" ""))))
5483    (clobber (reg:CC FLAGS_REG))]
5484   "TARGET_64BIT && reload_completed
5485    && true_regnum (operands[0]) != true_regnum (operands[1])"
5486   [(set (match_dup 0)
5487         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5489   operands[1] = gen_lowpart (Pmode, operands[1]);
5490   operands[2] = gen_lowpart (Pmode, operands[2]);
5493 (define_insn "*addsi_2"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5498           (const_int 0)))                       
5499    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:SI (match_dup 1) (match_dup 2)))]
5501   "ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, SImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{l}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{l}\t%0";
5517         }
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5523       if (GET_CODE (operands[2]) == CONST_INT
5524           && (INTVAL (operands[2]) == 128
5525               || (INTVAL (operands[2]) < 0
5526                   && INTVAL (operands[2]) != -128)))
5527         {
5528           operands[2] = GEN_INT (-INTVAL (operands[2]));
5529           return "sub{l}\t{%2, %0|%0, %2}";
5530         }
5531       return "add{l}\t{%2, %0|%0, %2}";
5532     }
5534   [(set (attr "type")
5535      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5536         (const_string "incdec")
5537         (const_string "alu")))
5538    (set_attr "mode" "SI")])
5540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5541 (define_insn "*addsi_2_zext"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5545                    (match_operand:SI 2 "general_operand" "rmni"))
5546           (const_int 0)))                       
5547    (set (match_operand:DI 0 "register_operand" "=r")
5548         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5549   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       if (operands[2] == const1_rtx)
5559         return "inc{l}\t%k0";
5560       else
5561         {
5562           gcc_assert (operands[2] == constm1_rtx);
5563           return "dec{l}\t%k0";
5564         }
5566     default:
5567       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5569       if (GET_CODE (operands[2]) == CONST_INT
5570           && (INTVAL (operands[2]) == 128
5571               || (INTVAL (operands[2]) < 0
5572                   && INTVAL (operands[2]) != -128)))
5573         {
5574           operands[2] = GEN_INT (-INTVAL (operands[2]));
5575           return "sub{l}\t{%2, %k0|%k0, %2}";
5576         }
5577       return "add{l}\t{%2, %k0|%k0, %2}";
5578     }
5580   [(set (attr "type")
5581      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582         (const_string "incdec")
5583         (const_string "alu")))
5584    (set_attr "mode" "SI")])
5586 (define_insn "*addsi_3"
5587   [(set (reg FLAGS_REG)
5588         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590    (clobber (match_scratch:SI 0 "=r"))]
5591   "ix86_match_ccmode (insn, CCZmode)
5592    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593    /* Current assemblers are broken and do not allow @GOTOFF in
5594       ought but a memory context.  */
5595    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597   switch (get_attr_type (insn))
5598     {
5599     case TYPE_INCDEC:
5600       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5601       if (operands[2] == const1_rtx)
5602         return "inc{l}\t%0";
5603       else
5604         {
5605           gcc_assert (operands[2] == constm1_rtx);
5606           return "dec{l}\t%0";
5607         }
5609     default:
5610       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5613       if (GET_CODE (operands[2]) == CONST_INT
5614           && (INTVAL (operands[2]) == 128
5615               || (INTVAL (operands[2]) < 0
5616                   && INTVAL (operands[2]) != -128)))
5617         {
5618           operands[2] = GEN_INT (-INTVAL (operands[2]));
5619           return "sub{l}\t{%2, %0|%0, %2}";
5620         }
5621       return "add{l}\t{%2, %0|%0, %2}";
5622     }
5624   [(set (attr "type")
5625      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5626         (const_string "incdec")
5627         (const_string "alu")))
5628    (set_attr "mode" "SI")])
5630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5631 (define_insn "*addsi_3_zext"
5632   [(set (reg FLAGS_REG)
5633         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5676 ; is matched then.  We can't accept general immediate, because for
5677 ; case of overflows,  the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683   [(set (reg FLAGS_REG)
5684         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685                  (match_operand:SI 2 "const_int_operand" "n")))
5686    (clobber (match_scratch:SI 0 "=rm"))]
5687   "ix86_match_ccmode (insn, CCGCmode)
5688    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == constm1_rtx)
5694         return "inc{l}\t%0";
5695       else
5696         {
5697           gcc_assert (operands[2] == const1_rtx);
5698           return "dec{l}\t%0";
5699         }
5701     default:
5702       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if ((INTVAL (operands[2]) == -128
5706            || (INTVAL (operands[2]) > 0
5707                && INTVAL (operands[2]) != 128)))
5708         return "sub{l}\t{%2, %0|%0, %2}";
5709       operands[2] = GEN_INT (-INTVAL (operands[2]));
5710       return "add{l}\t{%2, %0|%0, %2}";
5711     }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715         (const_string "incdec")
5716         (const_string "alu")))
5717    (set_attr "mode" "SI")])
5719 (define_insn "*addsi_5"
5720   [(set (reg FLAGS_REG)
5721         (compare
5722           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723                    (match_operand:SI 2 "general_operand" "rmni"))
5724           (const_int 0)))                       
5725    (clobber (match_scratch:SI 0 "=r"))]
5726   "ix86_match_ccmode (insn, CCGOCmode)
5727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728    /* Current assemblers are broken and do not allow @GOTOFF in
5729       ought but a memory context.  */
5730    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       if (operands[2] == const1_rtx)
5737         return "inc{l}\t%0";
5738       else
5739         {
5740           gcc_assert (operands[2] == constm1_rtx);
5741           return "dec{l}\t%0";
5742         }
5744     default:
5745       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5748       if (GET_CODE (operands[2]) == CONST_INT
5749           && (INTVAL (operands[2]) == 128
5750               || (INTVAL (operands[2]) < 0
5751                   && INTVAL (operands[2]) != -128)))
5752         {
5753           operands[2] = GEN_INT (-INTVAL (operands[2]));
5754           return "sub{l}\t{%2, %0|%0, %2}";
5755         }
5756       return "add{l}\t{%2, %0|%0, %2}";
5757     }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set_attr "mode" "SI")])
5765 (define_expand "addhi3"
5766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5767                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5768                             (match_operand:HI 2 "general_operand" "")))
5769               (clobber (reg:CC FLAGS_REG))])]
5770   "TARGET_HIMODE_MATH"
5771   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5774 ;; type optimizations enabled by define-splits.  This is not important
5775 ;; for PII, and in fact harmful because of partial register stalls.
5777 (define_insn "*addhi_1_lea"
5778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5779         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5780                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "!TARGET_PARTIAL_REG_STALL
5783    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785   switch (get_attr_type (insn))
5786     {
5787     case TYPE_LEA:
5788       return "#";
5789     case TYPE_INCDEC:
5790       if (operands[2] == const1_rtx)
5791         return "inc{w}\t%0";
5792       else
5793         {
5794           gcc_assert (operands[2] == constm1_rtx);
5795           return "dec{w}\t%0";
5796         }
5798     default:
5799       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5800          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5801       if (GET_CODE (operands[2]) == CONST_INT
5802           && (INTVAL (operands[2]) == 128
5803               || (INTVAL (operands[2]) < 0
5804                   && INTVAL (operands[2]) != -128)))
5805         {
5806           operands[2] = GEN_INT (-INTVAL (operands[2]));
5807           return "sub{w}\t{%2, %0|%0, %2}";
5808         }
5809       return "add{w}\t{%2, %0|%0, %2}";
5810     }
5812   [(set (attr "type")
5813      (if_then_else (eq_attr "alternative" "2")
5814         (const_string "lea")
5815         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5816            (const_string "incdec")
5817            (const_string "alu"))))
5818    (set_attr "mode" "HI,HI,SI")])
5820 (define_insn "*addhi_1"
5821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5822         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5823                  (match_operand:HI 2 "general_operand" "ri,rm")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "TARGET_PARTIAL_REG_STALL
5826    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5828   switch (get_attr_type (insn))
5829     {
5830     case TYPE_INCDEC:
5831       if (operands[2] == const1_rtx)
5832         return "inc{w}\t%0";
5833       else
5834         {
5835           gcc_assert (operands[2] == constm1_rtx);
5836           return "dec{w}\t%0";
5837         }
5839     default:
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (GET_CODE (operands[2]) == CONST_INT
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{w}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{w}\t{%2, %0|%0, %2}";
5851     }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "HI")])
5859 (define_insn "*addhi_2"
5860   [(set (reg FLAGS_REG)
5861         (compare
5862           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5864           (const_int 0)))                       
5865    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5866         (plus:HI (match_dup 1) (match_dup 2)))]
5867   "ix86_match_ccmode (insn, CCGOCmode)
5868    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870   switch (get_attr_type (insn))
5871     {
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{w}\t%0";
5875       else
5876         {
5877           gcc_assert (operands[2] == constm1_rtx);
5878           return "dec{w}\t%0";
5879         }
5881     default:
5882       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5883          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5884       if (GET_CODE (operands[2]) == CONST_INT
5885           && (INTVAL (operands[2]) == 128
5886               || (INTVAL (operands[2]) < 0
5887                   && INTVAL (operands[2]) != -128)))
5888         {
5889           operands[2] = GEN_INT (-INTVAL (operands[2]));
5890           return "sub{w}\t{%2, %0|%0, %2}";
5891         }
5892       return "add{w}\t{%2, %0|%0, %2}";
5893     }
5895   [(set (attr "type")
5896      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5897         (const_string "incdec")
5898         (const_string "alu")))
5899    (set_attr "mode" "HI")])
5901 (define_insn "*addhi_3"
5902   [(set (reg FLAGS_REG)
5903         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5904                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5905    (clobber (match_scratch:HI 0 "=r"))]
5906   "ix86_match_ccmode (insn, CCZmode)
5907    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{w}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{w}\t%0";
5918         }
5920     default:
5921       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923       if (GET_CODE (operands[2]) == CONST_INT
5924           && (INTVAL (operands[2]) == 128
5925               || (INTVAL (operands[2]) < 0
5926                   && INTVAL (operands[2]) != -128)))
5927         {
5928           operands[2] = GEN_INT (-INTVAL (operands[2]));
5929           return "sub{w}\t{%2, %0|%0, %2}";
5930         }
5931       return "add{w}\t{%2, %0|%0, %2}";
5932     }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936         (const_string "incdec")
5937         (const_string "alu")))
5938    (set_attr "mode" "HI")])
5940 ; See comments above addsi_4 for details.
5941 (define_insn "*addhi_4"
5942   [(set (reg FLAGS_REG)
5943         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5944                  (match_operand:HI 2 "const_int_operand" "n")))
5945    (clobber (match_scratch:HI 0 "=rm"))]
5946   "ix86_match_ccmode (insn, CCGCmode)
5947    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5949   switch (get_attr_type (insn))
5950     {
5951     case TYPE_INCDEC:
5952       if (operands[2] == constm1_rtx)
5953         return "inc{w}\t%0";
5954       else
5955         {
5956           gcc_assert (operands[2] == const1_rtx);
5957           return "dec{w}\t%0";
5958         }
5960     default:
5961       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5963          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5964       if ((INTVAL (operands[2]) == -128
5965            || (INTVAL (operands[2]) > 0
5966                && INTVAL (operands[2]) != 128)))
5967         return "sub{w}\t{%2, %0|%0, %2}";
5968       operands[2] = GEN_INT (-INTVAL (operands[2]));
5969       return "add{w}\t{%2, %0|%0, %2}";
5970     }
5972   [(set (attr "type")
5973      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974         (const_string "incdec")
5975         (const_string "alu")))
5976    (set_attr "mode" "SI")])
5979 (define_insn "*addhi_5"
5980   [(set (reg FLAGS_REG)
5981         (compare
5982           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5983                    (match_operand:HI 2 "general_operand" "rmni"))
5984           (const_int 0)))                       
5985    (clobber (match_scratch:HI 0 "=r"))]
5986   "ix86_match_ccmode (insn, CCGOCmode)
5987    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{w}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{w}\t%0";
5998         }
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{w}\t{%2, %0|%0, %2}";
6010         }
6011       return "add{w}\t{%2, %0|%0, %2}";
6012     }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "HI")])
6020 (define_expand "addqi3"
6021   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6022                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6023                             (match_operand:QI 2 "general_operand" "")))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "TARGET_QIMODE_MATH"
6026   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6028 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6029 (define_insn "*addqi_1_lea"
6030   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033    (clobber (reg:CC FLAGS_REG))]
6034   "!TARGET_PARTIAL_REG_STALL
6035    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6037   int widen = (which_alternative == 2);
6038   switch (get_attr_type (insn))
6039     {
6040     case TYPE_LEA:
6041       return "#";
6042     case TYPE_INCDEC:
6043       if (operands[2] == const1_rtx)
6044         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045       else
6046         {
6047           gcc_assert (operands[2] == constm1_rtx);
6048           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6049         }
6051     default:
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if (GET_CODE (operands[2]) == CONST_INT
6055           && (INTVAL (operands[2]) == 128
6056               || (INTVAL (operands[2]) < 0
6057                   && INTVAL (operands[2]) != -128)))
6058         {
6059           operands[2] = GEN_INT (-INTVAL (operands[2]));
6060           if (widen)
6061             return "sub{l}\t{%2, %k0|%k0, %2}";
6062           else
6063             return "sub{b}\t{%2, %0|%0, %2}";
6064         }
6065       if (widen)
6066         return "add{l}\t{%k2, %k0|%k0, %k2}";
6067       else
6068         return "add{b}\t{%2, %0|%0, %2}";
6069     }
6071   [(set (attr "type")
6072      (if_then_else (eq_attr "alternative" "3")
6073         (const_string "lea")
6074         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6075            (const_string "incdec")
6076            (const_string "alu"))))
6077    (set_attr "mode" "QI,QI,SI,SI")])
6079 (define_insn "*addqi_1"
6080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6081         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6082                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6083    (clobber (reg:CC FLAGS_REG))]
6084   "TARGET_PARTIAL_REG_STALL
6085    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6087   int widen = (which_alternative == 2);
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set_attr "mode" "QI,QI,SI")])
6125 (define_insn "*addqi_1_slp"
6126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127         (plus:QI (match_dup 0)
6128                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6129    (clobber (reg:CC FLAGS_REG))]
6130   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6133   switch (get_attr_type (insn))
6134     {
6135     case TYPE_INCDEC:
6136       if (operands[1] == const1_rtx)
6137         return "inc{b}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[1] == constm1_rtx);
6141           return "dec{b}\t%0";
6142         }
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6146       if (GET_CODE (operands[1]) == CONST_INT
6147           && INTVAL (operands[1]) < 0)
6148         {
6149           operands[1] = GEN_INT (-INTVAL (operands[1]));
6150           return "sub{b}\t{%1, %0|%0, %1}";
6151         }
6152       return "add{b}\t{%1, %0|%0, %1}";
6153     }
6155   [(set (attr "type")
6156      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6157         (const_string "incdec")
6158         (const_string "alu1")))
6159    (set (attr "memory")
6160      (if_then_else (match_operand 1 "memory_operand" "")
6161         (const_string "load")
6162         (const_string "none")))
6163    (set_attr "mode" "QI")])
6165 (define_insn "*addqi_2"
6166   [(set (reg FLAGS_REG)
6167         (compare
6168           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6169                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6170           (const_int 0)))
6171    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6172         (plus:QI (match_dup 1) (match_dup 2)))]
6173   "ix86_match_ccmode (insn, CCGOCmode)
6174    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx
6184                       || (GET_CODE (operands[2]) == CONST_INT
6185                           && INTVAL (operands[2]) == 255));
6186           return "dec{b}\t%0";
6187         }
6189     default:
6190       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6191       if (GET_CODE (operands[2]) == CONST_INT
6192           && INTVAL (operands[2]) < 0)
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           return "sub{b}\t{%2, %0|%0, %2}";
6196         }
6197       return "add{b}\t{%2, %0|%0, %2}";
6198     }
6200   [(set (attr "type")
6201      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6202         (const_string "incdec")
6203         (const_string "alu")))
6204    (set_attr "mode" "QI")])
6206 (define_insn "*addqi_3"
6207   [(set (reg FLAGS_REG)
6208         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6209                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6210    (clobber (match_scratch:QI 0 "=q"))]
6211   "ix86_match_ccmode (insn, CCZmode)
6212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6214   switch (get_attr_type (insn))
6215     {
6216     case TYPE_INCDEC:
6217       if (operands[2] == const1_rtx)
6218         return "inc{b}\t%0";
6219       else
6220         {
6221           gcc_assert (operands[2] == constm1_rtx
6222                       || (GET_CODE (operands[2]) == CONST_INT
6223                           && INTVAL (operands[2]) == 255));
6224           return "dec{b}\t%0";
6225         }
6227     default:
6228       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6229       if (GET_CODE (operands[2]) == CONST_INT
6230           && INTVAL (operands[2]) < 0)
6231         {
6232           operands[2] = GEN_INT (-INTVAL (operands[2]));
6233           return "sub{b}\t{%2, %0|%0, %2}";
6234         }
6235       return "add{b}\t{%2, %0|%0, %2}";
6236     }
6238   [(set (attr "type")
6239      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240         (const_string "incdec")
6241         (const_string "alu")))
6242    (set_attr "mode" "QI")])
6244 ; See comments above addsi_4 for details.
6245 (define_insn "*addqi_4"
6246   [(set (reg FLAGS_REG)
6247         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6248                  (match_operand:QI 2 "const_int_operand" "n")))
6249    (clobber (match_scratch:QI 0 "=qm"))]
6250   "ix86_match_ccmode (insn, CCGCmode)
6251    && (INTVAL (operands[2]) & 0xff) != 0x80"
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx
6257           || (GET_CODE (operands[2]) == CONST_INT
6258               && INTVAL (operands[2]) == 255))
6259         return "inc{b}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == const1_rtx);
6263           return "dec{b}\t%0";
6264         }
6266     default:
6267       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6268       if (INTVAL (operands[2]) < 0)
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "add{b}\t{%2, %0|%0, %2}";
6272         }
6273       return "sub{b}\t{%2, %0|%0, %2}";
6274     }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "QI")])
6283 (define_insn "*addqi_5"
6284   [(set (reg FLAGS_REG)
6285         (compare
6286           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6287                    (match_operand:QI 2 "general_operand" "qmni"))
6288           (const_int 0)))
6289    (clobber (match_scratch:QI 0 "=q"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{b}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx
6301                       || (GET_CODE (operands[2]) == CONST_INT
6302                           && INTVAL (operands[2]) == 255));
6303           return "dec{b}\t%0";
6304         }
6306     default:
6307       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6308       if (GET_CODE (operands[2]) == CONST_INT
6309           && INTVAL (operands[2]) < 0)
6310         {
6311           operands[2] = GEN_INT (-INTVAL (operands[2]));
6312           return "sub{b}\t{%2, %0|%0, %2}";
6313         }
6314       return "add{b}\t{%2, %0|%0, %2}";
6315     }
6317   [(set (attr "type")
6318      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319         (const_string "incdec")
6320         (const_string "alu")))
6321    (set_attr "mode" "QI")])
6324 (define_insn "addqi_ext_1"
6325   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6326                          (const_int 8)
6327                          (const_int 8))
6328         (plus:SI
6329           (zero_extract:SI
6330             (match_operand 1 "ext_register_operand" "0")
6331             (const_int 8)
6332             (const_int 8))
6333           (match_operand:QI 2 "general_operand" "Qmn")))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "!TARGET_64BIT"
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       if (operands[2] == const1_rtx)
6341         return "inc{b}\t%h0";
6342       else
6343         {
6344           gcc_assert (operands[2] == constm1_rtx
6345                       || (GET_CODE (operands[2]) == CONST_INT
6346                           && INTVAL (operands[2]) == 255));
6347           return "dec{b}\t%h0";
6348         }
6350     default:
6351       return "add{b}\t{%2, %h0|%h0, %2}";
6352     }
6354   [(set (attr "type")
6355      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356         (const_string "incdec")
6357         (const_string "alu")))
6358    (set_attr "mode" "QI")])
6360 (define_insn "*addqi_ext_1_rex64"
6361   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6362                          (const_int 8)
6363                          (const_int 8))
6364         (plus:SI
6365           (zero_extract:SI
6366             (match_operand 1 "ext_register_operand" "0")
6367             (const_int 8)
6368             (const_int 8))
6369           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "TARGET_64BIT"
6373   switch (get_attr_type (insn))
6374     {
6375     case TYPE_INCDEC:
6376       if (operands[2] == const1_rtx)
6377         return "inc{b}\t%h0";
6378       else
6379         {
6380           gcc_assert (operands[2] == constm1_rtx
6381                       || (GET_CODE (operands[2]) == CONST_INT
6382                           && INTVAL (operands[2]) == 255));
6383           return "dec{b}\t%h0";
6384         }
6386     default:
6387       return "add{b}\t{%2, %h0|%h0, %2}";
6388     }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6396 (define_insn "*addqi_ext_2"
6397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6398                          (const_int 8)
6399                          (const_int 8))
6400         (plus:SI
6401           (zero_extract:SI
6402             (match_operand 1 "ext_register_operand" "%0")
6403             (const_int 8)
6404             (const_int 8))
6405           (zero_extract:SI
6406             (match_operand 2 "ext_register_operand" "Q")
6407             (const_int 8)
6408             (const_int 8))))
6409    (clobber (reg:CC FLAGS_REG))]
6410   ""
6411   "add{b}\t{%h2, %h0|%h0, %h2}"
6412   [(set_attr "type" "alu")
6413    (set_attr "mode" "QI")])
6415 ;; The patterns that match these are at the end of this file.
6417 (define_expand "addxf3"
6418   [(set (match_operand:XF 0 "register_operand" "")
6419         (plus:XF (match_operand:XF 1 "register_operand" "")
6420                  (match_operand:XF 2 "register_operand" "")))]
6421   "TARGET_80387"
6422   "")
6424 (define_expand "adddf3"
6425   [(set (match_operand:DF 0 "register_operand" "")
6426         (plus:DF (match_operand:DF 1 "register_operand" "")
6427                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6428   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6429   "")
6431 (define_expand "addsf3"
6432   [(set (match_operand:SF 0 "register_operand" "")
6433         (plus:SF (match_operand:SF 1 "register_operand" "")
6434                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6435   "TARGET_80387 || TARGET_SSE_MATH"
6436   "")
6438 ;; Subtract instructions
6440 ;; %%% splits for subditi3
6442 (define_expand "subti3"
6443   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6444                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6445                              (match_operand:TI 2 "x86_64_general_operand" "")))
6446               (clobber (reg:CC FLAGS_REG))])]
6447   "TARGET_64BIT"
6448   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6450 (define_insn "*subti3_1"
6451   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6452         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6453                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6454    (clobber (reg:CC FLAGS_REG))]
6455   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6456   "#")
6458 (define_split
6459   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6460         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6461                   (match_operand:TI 2 "general_operand" "")))
6462    (clobber (reg:CC FLAGS_REG))]
6463   "TARGET_64BIT && reload_completed"
6464   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6465               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6466    (parallel [(set (match_dup 3)
6467                    (minus:DI (match_dup 4)
6468                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6469                                       (match_dup 5))))
6470               (clobber (reg:CC FLAGS_REG))])]
6471   "split_ti (operands+0, 1, operands+0, operands+3);
6472    split_ti (operands+1, 1, operands+1, operands+4);
6473    split_ti (operands+2, 1, operands+2, operands+5);")
6475 ;; %%% splits for subsidi3
6477 (define_expand "subdi3"
6478   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6479                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6480                              (match_operand:DI 2 "x86_64_general_operand" "")))
6481               (clobber (reg:CC FLAGS_REG))])]
6482   ""
6483   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6485 (define_insn "*subdi3_1"
6486   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6487         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6488                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6491   "#")
6493 (define_split
6494   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6495         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6496                   (match_operand:DI 2 "general_operand" "")))
6497    (clobber (reg:CC FLAGS_REG))]
6498   "!TARGET_64BIT && reload_completed"
6499   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6500               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6501    (parallel [(set (match_dup 3)
6502                    (minus:SI (match_dup 4)
6503                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6504                                       (match_dup 5))))
6505               (clobber (reg:CC FLAGS_REG))])]
6506   "split_di (operands+0, 1, operands+0, operands+3);
6507    split_di (operands+1, 1, operands+1, operands+4);
6508    split_di (operands+2, 1, operands+2, operands+5);")
6510 (define_insn "subdi3_carry_rex64"
6511   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6512           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6513             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6514                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6515    (clobber (reg:CC FLAGS_REG))]
6516   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6517   "sbb{q}\t{%2, %0|%0, %2}"
6518   [(set_attr "type" "alu")
6519    (set_attr "pent_pair" "pu")
6520    (set_attr "mode" "DI")])
6522 (define_insn "*subdi_1_rex64"
6523   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6524         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6525                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6526    (clobber (reg:CC FLAGS_REG))]
6527   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6528   "sub{q}\t{%2, %0|%0, %2}"
6529   [(set_attr "type" "alu")
6530    (set_attr "mode" "DI")])
6532 (define_insn "*subdi_2_rex64"
6533   [(set (reg FLAGS_REG)
6534         (compare
6535           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6537           (const_int 0)))
6538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6539         (minus:DI (match_dup 1) (match_dup 2)))]
6540   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6541    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542   "sub{q}\t{%2, %0|%0, %2}"
6543   [(set_attr "type" "alu")
6544    (set_attr "mode" "DI")])
6546 (define_insn "*subdi_3_rex63"
6547   [(set (reg FLAGS_REG)
6548         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6549                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6550    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551         (minus:DI (match_dup 1) (match_dup 2)))]
6552   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554   "sub{q}\t{%2, %0|%0, %2}"
6555   [(set_attr "type" "alu")
6556    (set_attr "mode" "DI")])
6558 (define_insn "subqi3_carry"
6559   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6560           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6561             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:QI 2 "general_operand" "qi,qm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6565   "sbb{b}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "QI")])
6570 (define_insn "subhi3_carry"
6571   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6573             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6574                (match_operand:HI 2 "general_operand" "ri,rm"))))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6577   "sbb{w}\t{%2, %0|%0, %2}"
6578   [(set_attr "type" "alu")
6579    (set_attr "pent_pair" "pu")
6580    (set_attr "mode" "HI")])
6582 (define_insn "subsi3_carry"
6583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6585             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6586                (match_operand:SI 2 "general_operand" "ri,rm"))))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6589   "sbb{l}\t{%2, %0|%0, %2}"
6590   [(set_attr "type" "alu")
6591    (set_attr "pent_pair" "pu")
6592    (set_attr "mode" "SI")])
6594 (define_insn "subsi3_carry_zext"
6595   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6596           (zero_extend:DI
6597             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6598               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6599                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sbb{l}\t{%2, %k0|%k0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "pent_pair" "pu")
6605    (set_attr "mode" "SI")])
6607 (define_expand "subsi3"
6608   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6609                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6610                              (match_operand:SI 2 "general_operand" "")))
6611               (clobber (reg:CC FLAGS_REG))])]
6612   ""
6613   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6615 (define_insn "*subsi_1"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618                   (match_operand:SI 2 "general_operand" "ri,rm")))
6619    (clobber (reg:CC FLAGS_REG))]
6620   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621   "sub{l}\t{%2, %0|%0, %2}"
6622   [(set_attr "type" "alu")
6623    (set_attr "mode" "SI")])
6625 (define_insn "*subsi_1_zext"
6626   [(set (match_operand:DI 0 "register_operand" "=r")
6627         (zero_extend:DI
6628           (minus:SI (match_operand:SI 1 "register_operand" "0")
6629                     (match_operand:SI 2 "general_operand" "rim"))))
6630    (clobber (reg:CC FLAGS_REG))]
6631   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632   "sub{l}\t{%2, %k0|%k0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "SI")])
6636 (define_insn "*subsi_2"
6637   [(set (reg FLAGS_REG)
6638         (compare
6639           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6640                     (match_operand:SI 2 "general_operand" "ri,rm"))
6641           (const_int 0)))
6642    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:SI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCGOCmode)
6645    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6646   "sub{l}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "SI")])
6650 (define_insn "*subsi_2_zext"
6651   [(set (reg FLAGS_REG)
6652         (compare
6653           (minus:SI (match_operand:SI 1 "register_operand" "0")
6654                     (match_operand:SI 2 "general_operand" "rim"))
6655           (const_int 0)))
6656    (set (match_operand:DI 0 "register_operand" "=r")
6657         (zero_extend:DI
6658           (minus:SI (match_dup 1)
6659                     (match_dup 2))))]
6660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sub{l}\t{%2, %k0|%k0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "mode" "SI")])
6666 (define_insn "*subsi_3"
6667   [(set (reg FLAGS_REG)
6668         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6669                  (match_operand:SI 2 "general_operand" "ri,rm")))
6670    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671         (minus:SI (match_dup 1) (match_dup 2)))]
6672   "ix86_match_ccmode (insn, CCmode)
6673    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674   "sub{l}\t{%2, %0|%0, %2}"
6675   [(set_attr "type" "alu")
6676    (set_attr "mode" "SI")])
6678 (define_insn "*subsi_3_zext"
6679   [(set (reg FLAGS_REG)
6680         (compare (match_operand:SI 1 "register_operand" "0")
6681                  (match_operand:SI 2 "general_operand" "rim")))
6682    (set (match_operand:DI 0 "register_operand" "=r")
6683         (zero_extend:DI
6684           (minus:SI (match_dup 1)
6685                     (match_dup 2))))]
6686   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6687    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688   "sub{q}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "mode" "DI")])
6692 (define_expand "subhi3"
6693   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6694                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6695                              (match_operand:HI 2 "general_operand" "")))
6696               (clobber (reg:CC FLAGS_REG))])]
6697   "TARGET_HIMODE_MATH"
6698   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6700 (define_insn "*subhi_1"
6701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703                   (match_operand:HI 2 "general_operand" "ri,rm")))
6704    (clobber (reg:CC FLAGS_REG))]
6705   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6706   "sub{w}\t{%2, %0|%0, %2}"
6707   [(set_attr "type" "alu")
6708    (set_attr "mode" "HI")])
6710 (define_insn "*subhi_2"
6711   [(set (reg FLAGS_REG)
6712         (compare
6713           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6714                     (match_operand:HI 2 "general_operand" "ri,rm"))
6715           (const_int 0)))
6716    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6717         (minus:HI (match_dup 1) (match_dup 2)))]
6718   "ix86_match_ccmode (insn, CCGOCmode)
6719    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6720   "sub{w}\t{%2, %0|%0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "HI")])
6724 (define_insn "*subhi_3"
6725   [(set (reg FLAGS_REG)
6726         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6727                  (match_operand:HI 2 "general_operand" "ri,rm")))
6728    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6729         (minus:HI (match_dup 1) (match_dup 2)))]
6730   "ix86_match_ccmode (insn, CCmode)
6731    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6732   "sub{w}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "HI")])
6736 (define_expand "subqi3"
6737   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6738                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6739                              (match_operand:QI 2 "general_operand" "")))
6740               (clobber (reg:CC FLAGS_REG))])]
6741   "TARGET_QIMODE_MATH"
6742   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6744 (define_insn "*subqi_1"
6745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6746         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6747                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6748    (clobber (reg:CC FLAGS_REG))]
6749   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6750   "sub{b}\t{%2, %0|%0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "QI")])
6754 (define_insn "*subqi_1_slp"
6755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6756         (minus:QI (match_dup 0)
6757                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6761   "sub{b}\t{%1, %0|%0, %1}"
6762   [(set_attr "type" "alu1")
6763    (set_attr "mode" "QI")])
6765 (define_insn "*subqi_2"
6766   [(set (reg FLAGS_REG)
6767         (compare
6768           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6769                     (match_operand:QI 2 "general_operand" "qi,qm"))
6770           (const_int 0)))
6771    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6772         (minus:HI (match_dup 1) (match_dup 2)))]
6773   "ix86_match_ccmode (insn, CCGOCmode)
6774    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6775   "sub{b}\t{%2, %0|%0, %2}"
6776   [(set_attr "type" "alu")
6777    (set_attr "mode" "QI")])
6779 (define_insn "*subqi_3"
6780   [(set (reg FLAGS_REG)
6781         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6782                  (match_operand:QI 2 "general_operand" "qi,qm")))
6783    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6784         (minus:HI (match_dup 1) (match_dup 2)))]
6785   "ix86_match_ccmode (insn, CCmode)
6786    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6787   "sub{b}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "QI")])
6791 ;; The patterns that match these are at the end of this file.
6793 (define_expand "subxf3"
6794   [(set (match_operand:XF 0 "register_operand" "")
6795         (minus:XF (match_operand:XF 1 "register_operand" "")
6796                   (match_operand:XF 2 "register_operand" "")))]
6797   "TARGET_80387"
6798   "")
6800 (define_expand "subdf3"
6801   [(set (match_operand:DF 0 "register_operand" "")
6802         (minus:DF (match_operand:DF 1 "register_operand" "")
6803                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6804   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6805   "")
6807 (define_expand "subsf3"
6808   [(set (match_operand:SF 0 "register_operand" "")
6809         (minus:SF (match_operand:SF 1 "register_operand" "")
6810                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6811   "TARGET_80387 || TARGET_SSE_MATH"
6812   "")
6814 ;; Multiply instructions
6816 (define_expand "muldi3"
6817   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6818                    (mult:DI (match_operand:DI 1 "register_operand" "")
6819                             (match_operand:DI 2 "x86_64_general_operand" "")))
6820               (clobber (reg:CC FLAGS_REG))])]
6821   "TARGET_64BIT"
6822   "")
6824 (define_insn "*muldi3_1_rex64"
6825   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6826         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6827                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "TARGET_64BIT
6830    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6831   "@
6832    imul{q}\t{%2, %1, %0|%0, %1, %2}
6833    imul{q}\t{%2, %1, %0|%0, %1, %2}
6834    imul{q}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "imul")
6836    (set_attr "prefix_0f" "0,0,1")
6837    (set (attr "athlon_decode")
6838         (cond [(eq_attr "cpu" "athlon")
6839                   (const_string "vector")
6840                (eq_attr "alternative" "1")
6841                   (const_string "vector")
6842                (and (eq_attr "alternative" "2")
6843                     (match_operand 1 "memory_operand" ""))
6844                   (const_string "vector")]
6845               (const_string "direct")))
6846    (set_attr "mode" "DI")])
6848 (define_expand "mulsi3"
6849   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6850                    (mult:SI (match_operand:SI 1 "register_operand" "")
6851                             (match_operand:SI 2 "general_operand" "")))
6852               (clobber (reg:CC FLAGS_REG))])]
6853   ""
6854   "")
6856 (define_insn "*mulsi3_1"
6857   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6858         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6859                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6862   "@
6863    imul{l}\t{%2, %1, %0|%0, %1, %2}
6864    imul{l}\t{%2, %1, %0|%0, %1, %2}
6865    imul{l}\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" "SI")])
6879 (define_insn "*mulsi3_1_zext"
6880   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881         (zero_extend:DI
6882           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6883                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_64BIT
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "@
6888    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890    imul{l}\t{%2, %k0|%k0, %2}"
6891   [(set_attr "type" "imul")
6892    (set_attr "prefix_0f" "0,0,1")
6893    (set (attr "athlon_decode")
6894         (cond [(eq_attr "cpu" "athlon")
6895                   (const_string "vector")
6896                (eq_attr "alternative" "1")
6897                   (const_string "vector")
6898                (and (eq_attr "alternative" "2")
6899                     (match_operand 1 "memory_operand" ""))
6900                   (const_string "vector")]
6901               (const_string "direct")))
6902    (set_attr "mode" "SI")])
6904 (define_expand "mulhi3"
6905   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6906                    (mult:HI (match_operand:HI 1 "register_operand" "")
6907                             (match_operand:HI 2 "general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_HIMODE_MATH"
6910   "")
6912 (define_insn "*mulhi3_1"
6913   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6914         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6918   "@
6919    imul{w}\t{%2, %1, %0|%0, %1, %2}
6920    imul{w}\t{%2, %1, %0|%0, %1, %2}
6921    imul{w}\t{%2, %0|%0, %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,2")
6928                   (const_string "vector")]
6929               (const_string "direct")))
6930    (set_attr "mode" "HI")])
6932 (define_expand "mulqi3"
6933   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6934                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6935                             (match_operand:QI 2 "register_operand" "")))
6936               (clobber (reg:CC FLAGS_REG))])]
6937   "TARGET_QIMODE_MATH"
6938   "")
6940 (define_insn "*mulqi3_1"
6941   [(set (match_operand:QI 0 "register_operand" "=a")
6942         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6943                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6944    (clobber (reg:CC FLAGS_REG))]
6945   "TARGET_QIMODE_MATH
6946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6947   "mul{b}\t%2"
6948   [(set_attr "type" "imul")
6949    (set_attr "length_immediate" "0")
6950    (set (attr "athlon_decode")
6951      (if_then_else (eq_attr "cpu" "athlon")
6952         (const_string "vector")
6953         (const_string "direct")))
6954    (set_attr "mode" "QI")])
6956 (define_expand "umulqihi3"
6957   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6958                    (mult:HI (zero_extend:HI
6959                               (match_operand:QI 1 "nonimmediate_operand" ""))
6960                             (zero_extend:HI
6961                               (match_operand:QI 2 "register_operand" ""))))
6962               (clobber (reg:CC FLAGS_REG))])]
6963   "TARGET_QIMODE_MATH"
6964   "")
6966 (define_insn "*umulqihi3_1"
6967   [(set (match_operand:HI 0 "register_operand" "=a")
6968         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970    (clobber (reg:CC FLAGS_REG))]
6971   "TARGET_QIMODE_MATH
6972    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6973   "mul{b}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "direct")))
6980    (set_attr "mode" "QI")])
6982 (define_expand "mulqihi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6985                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "TARGET_QIMODE_MATH"
6988   "")
6990 (define_insn "*mulqihi3_insn"
6991   [(set (match_operand:HI 0 "register_operand" "=a")
6992         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6993                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_QIMODE_MATH
6996    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6997   "imul{b}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "direct")))
7004    (set_attr "mode" "QI")])
7006 (define_expand "umulditi3"
7007   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7008                    (mult:TI (zero_extend:TI
7009                               (match_operand:DI 1 "nonimmediate_operand" ""))
7010                             (zero_extend:TI
7011                               (match_operand:DI 2 "register_operand" ""))))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_64BIT"
7014   "")
7016 (define_insn "*umulditi3_insn"
7017   [(set (match_operand:TI 0 "register_operand" "=A")
7018         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7019                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "TARGET_64BIT
7022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7023   "mul{q}\t%2"
7024   [(set_attr "type" "imul")
7025    (set_attr "length_immediate" "0")
7026    (set (attr "athlon_decode")
7027      (if_then_else (eq_attr "cpu" "athlon")
7028         (const_string "vector")
7029         (const_string "double")))
7030    (set_attr "mode" "DI")])
7032 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7033 (define_expand "umulsidi3"
7034   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035                    (mult:DI (zero_extend:DI
7036                               (match_operand:SI 1 "nonimmediate_operand" ""))
7037                             (zero_extend:DI
7038                               (match_operand:SI 2 "register_operand" ""))))
7039               (clobber (reg:CC FLAGS_REG))])]
7040   "!TARGET_64BIT"
7041   "")
7043 (define_insn "*umulsidi3_insn"
7044   [(set (match_operand:DI 0 "register_operand" "=A")
7045         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7046                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7047    (clobber (reg:CC FLAGS_REG))]
7048   "!TARGET_64BIT
7049    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7050   "mul{l}\t%2"
7051   [(set_attr "type" "imul")
7052    (set_attr "length_immediate" "0")
7053    (set (attr "athlon_decode")
7054      (if_then_else (eq_attr "cpu" "athlon")
7055         (const_string "vector")
7056         (const_string "double")))
7057    (set_attr "mode" "SI")])
7059 (define_expand "mulditi3"
7060   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7061                    (mult:TI (sign_extend:TI
7062                               (match_operand:DI 1 "nonimmediate_operand" ""))
7063                             (sign_extend:TI
7064                               (match_operand:DI 2 "register_operand" ""))))
7065               (clobber (reg:CC FLAGS_REG))])]
7066   "TARGET_64BIT"
7067   "")
7069 (define_insn "*mulditi3_insn"
7070   [(set (match_operand:TI 0 "register_operand" "=A")
7071         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7072                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "TARGET_64BIT
7075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7076   "imul{q}\t%2"
7077   [(set_attr "type" "imul")
7078    (set_attr "length_immediate" "0")
7079    (set (attr "athlon_decode")
7080      (if_then_else (eq_attr "cpu" "athlon")
7081         (const_string "vector")
7082         (const_string "double")))
7083    (set_attr "mode" "DI")])
7085 (define_expand "mulsidi3"
7086   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7087                    (mult:DI (sign_extend:DI
7088                               (match_operand:SI 1 "nonimmediate_operand" ""))
7089                             (sign_extend:DI
7090                               (match_operand:SI 2 "register_operand" ""))))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "!TARGET_64BIT"
7093   "")
7095 (define_insn "*mulsidi3_insn"
7096   [(set (match_operand:DI 0 "register_operand" "=A")
7097         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7098                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "!TARGET_64BIT
7101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7102   "imul{l}\t%2"
7103   [(set_attr "type" "imul")
7104    (set_attr "length_immediate" "0")
7105    (set (attr "athlon_decode")
7106      (if_then_else (eq_attr "cpu" "athlon")
7107         (const_string "vector")
7108         (const_string "double")))
7109    (set_attr "mode" "SI")])
7111 (define_expand "umuldi3_highpart"
7112   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7113                    (truncate:DI
7114                      (lshiftrt:TI
7115                        (mult:TI (zero_extend:TI
7116                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7117                                 (zero_extend:TI
7118                                   (match_operand:DI 2 "register_operand" "")))
7119                        (const_int 64))))
7120               (clobber (match_scratch:DI 3 ""))
7121               (clobber (reg:CC FLAGS_REG))])]
7122   "TARGET_64BIT"
7123   "")
7125 (define_insn "*umuldi3_highpart_rex64"
7126   [(set (match_operand:DI 0 "register_operand" "=d")
7127         (truncate:DI
7128           (lshiftrt:TI
7129             (mult:TI (zero_extend:TI
7130                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7131                      (zero_extend:TI
7132                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7133             (const_int 64))))
7134    (clobber (match_scratch:DI 3 "=1"))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "TARGET_64BIT
7137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138   "mul{q}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "DI")])
7147 (define_expand "umulsi3_highpart"
7148   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149                    (truncate:SI
7150                      (lshiftrt:DI
7151                        (mult:DI (zero_extend:DI
7152                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7153                                 (zero_extend:DI
7154                                   (match_operand:SI 2 "register_operand" "")))
7155                        (const_int 32))))
7156               (clobber (match_scratch:SI 3 ""))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   ""
7159   "")
7161 (define_insn "*umulsi3_highpart_insn"
7162   [(set (match_operand:SI 0 "register_operand" "=d")
7163         (truncate:SI
7164           (lshiftrt:DI
7165             (mult:DI (zero_extend:DI
7166                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7167                      (zero_extend:DI
7168                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7169             (const_int 32))))
7170    (clobber (match_scratch:SI 3 "=1"))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "mode" "SI")])
7182 (define_insn "*umulsi3_highpart_zext"
7183   [(set (match_operand:DI 0 "register_operand" "=d")
7184         (zero_extend:DI (truncate:SI
7185           (lshiftrt:DI
7186             (mult:DI (zero_extend:DI
7187                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7188                      (zero_extend:DI
7189                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7190             (const_int 32)))))
7191    (clobber (match_scratch:SI 3 "=1"))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195   "mul{l}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "mode" "SI")])
7204 (define_expand "smuldi3_highpart"
7205   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7206                    (truncate:DI
7207                      (lshiftrt:TI
7208                        (mult:TI (sign_extend:TI
7209                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7210                                 (sign_extend:TI
7211                                   (match_operand:DI 2 "register_operand" "")))
7212                        (const_int 64))))
7213               (clobber (match_scratch:DI 3 ""))
7214               (clobber (reg:CC FLAGS_REG))])]
7215   "TARGET_64BIT"
7216   "")
7218 (define_insn "*smuldi3_highpart_rex64"
7219   [(set (match_operand:DI 0 "register_operand" "=d")
7220         (truncate:DI
7221           (lshiftrt:TI
7222             (mult:TI (sign_extend:TI
7223                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7224                      (sign_extend:TI
7225                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7226             (const_int 64))))
7227    (clobber (match_scratch:DI 3 "=1"))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_64BIT
7230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7231   "imul{q}\t%2"
7232   [(set_attr "type" "imul")
7233    (set (attr "athlon_decode")
7234      (if_then_else (eq_attr "cpu" "athlon")
7235         (const_string "vector")
7236         (const_string "double")))
7237    (set_attr "mode" "DI")])
7239 (define_expand "smulsi3_highpart"
7240   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7241                    (truncate:SI
7242                      (lshiftrt:DI
7243                        (mult:DI (sign_extend:DI
7244                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7245                                 (sign_extend:DI
7246                                   (match_operand:SI 2 "register_operand" "")))
7247                        (const_int 32))))
7248               (clobber (match_scratch:SI 3 ""))
7249               (clobber (reg:CC FLAGS_REG))])]
7250   ""
7251   "")
7253 (define_insn "*smulsi3_highpart_insn"
7254   [(set (match_operand:SI 0 "register_operand" "=d")
7255         (truncate:SI
7256           (lshiftrt:DI
7257             (mult:DI (sign_extend:DI
7258                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7259                      (sign_extend:DI
7260                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7261             (const_int 32))))
7262    (clobber (match_scratch:SI 3 "=1"))
7263    (clobber (reg:CC FLAGS_REG))]
7264   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7265   "imul{l}\t%2"
7266   [(set_attr "type" "imul")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "mode" "SI")])
7273 (define_insn "*smulsi3_highpart_zext"
7274   [(set (match_operand:DI 0 "register_operand" "=d")
7275         (zero_extend:DI (truncate:SI
7276           (lshiftrt:DI
7277             (mult:DI (sign_extend:DI
7278                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7279                      (sign_extend:DI
7280                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7281             (const_int 32)))))
7282    (clobber (match_scratch:SI 3 "=1"))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT
7285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7286   "imul{l}\t%2"
7287   [(set_attr "type" "imul")
7288    (set (attr "athlon_decode")
7289      (if_then_else (eq_attr "cpu" "athlon")
7290         (const_string "vector")
7291         (const_string "double")))
7292    (set_attr "mode" "SI")])
7294 ;; The patterns that match these are at the end of this file.
7296 (define_expand "mulxf3"
7297   [(set (match_operand:XF 0 "register_operand" "")
7298         (mult:XF (match_operand:XF 1 "register_operand" "")
7299                  (match_operand:XF 2 "register_operand" "")))]
7300   "TARGET_80387"
7301   "")
7303 (define_expand "muldf3"
7304   [(set (match_operand:DF 0 "register_operand" "")
7305         (mult:DF (match_operand:DF 1 "register_operand" "")
7306                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7307   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7308   "")
7310 (define_expand "mulsf3"
7311   [(set (match_operand:SF 0 "register_operand" "")
7312         (mult:SF (match_operand:SF 1 "register_operand" "")
7313                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7314   "TARGET_80387 || TARGET_SSE_MATH"
7315   "")
7317 ;; Divide instructions
7319 (define_insn "divqi3"
7320   [(set (match_operand:QI 0 "register_operand" "=a")
7321         (div:QI (match_operand:HI 1 "register_operand" "0")
7322                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "TARGET_QIMODE_MATH"
7325   "idiv{b}\t%2"
7326   [(set_attr "type" "idiv")
7327    (set_attr "mode" "QI")])
7329 (define_insn "udivqi3"
7330   [(set (match_operand:QI 0 "register_operand" "=a")
7331         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7332                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "TARGET_QIMODE_MATH"
7335   "div{b}\t%2"
7336   [(set_attr "type" "idiv")
7337    (set_attr "mode" "QI")])
7339 ;; The patterns that match these are at the end of this file.
7341 (define_expand "divxf3"
7342   [(set (match_operand:XF 0 "register_operand" "")
7343         (div:XF (match_operand:XF 1 "register_operand" "")
7344                 (match_operand:XF 2 "register_operand" "")))]
7345   "TARGET_80387"
7346   "")
7348 (define_expand "divdf3"
7349   [(set (match_operand:DF 0 "register_operand" "")
7350         (div:DF (match_operand:DF 1 "register_operand" "")
7351                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353    "")
7355 (define_expand "divsf3"
7356   [(set (match_operand:SF 0 "register_operand" "")
7357         (div:SF (match_operand:SF 1 "register_operand" "")
7358                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359   "TARGET_80387 || TARGET_SSE_MATH"
7360   "")
7362 ;; Remainder instructions.
7364 (define_expand "divmoddi4"
7365   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7366                    (div:DI (match_operand:DI 1 "register_operand" "")
7367                            (match_operand:DI 2 "nonimmediate_operand" "")))
7368               (set (match_operand:DI 3 "register_operand" "")
7369                    (mod:DI (match_dup 1) (match_dup 2)))
7370               (clobber (reg:CC FLAGS_REG))])]
7371   "TARGET_64BIT"
7372   "")
7374 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7375 ;; Penalize eax case slightly because it results in worse scheduling
7376 ;; of code.
7377 (define_insn "*divmoddi4_nocltd_rex64"
7378   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7379         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7380                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7381    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7382         (mod:DI (match_dup 2) (match_dup 3)))
7383    (clobber (reg:CC FLAGS_REG))]
7384   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7385   "#"
7386   [(set_attr "type" "multi")])
7388 (define_insn "*divmoddi4_cltd_rex64"
7389   [(set (match_operand:DI 0 "register_operand" "=a")
7390         (div:DI (match_operand:DI 2 "register_operand" "a")
7391                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7392    (set (match_operand:DI 1 "register_operand" "=&d")
7393         (mod:DI (match_dup 2) (match_dup 3)))
7394    (clobber (reg:CC FLAGS_REG))]
7395   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7396   "#"
7397   [(set_attr "type" "multi")])
7399 (define_insn "*divmoddi_noext_rex64"
7400   [(set (match_operand:DI 0 "register_operand" "=a")
7401         (div:DI (match_operand:DI 1 "register_operand" "0")
7402                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403    (set (match_operand:DI 3 "register_operand" "=d")
7404         (mod:DI (match_dup 1) (match_dup 2)))
7405    (use (match_operand:DI 4 "register_operand" "3"))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_64BIT"
7408   "idiv{q}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "DI")])
7412 (define_split
7413   [(set (match_operand:DI 0 "register_operand" "")
7414         (div:DI (match_operand:DI 1 "register_operand" "")
7415                 (match_operand:DI 2 "nonimmediate_operand" "")))
7416    (set (match_operand:DI 3 "register_operand" "")
7417         (mod:DI (match_dup 1) (match_dup 2)))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_64BIT && reload_completed"
7420   [(parallel [(set (match_dup 3)
7421                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7422               (clobber (reg:CC FLAGS_REG))])
7423    (parallel [(set (match_dup 0)
7424                    (div:DI (reg:DI 0) (match_dup 2)))
7425               (set (match_dup 3)
7426                    (mod:DI (reg:DI 0) (match_dup 2)))
7427               (use (match_dup 3))
7428               (clobber (reg:CC FLAGS_REG))])]
7430   /* Avoid use of cltd in favor of a mov+shift.  */
7431   if (!TARGET_USE_CLTD && !optimize_size)
7432     {
7433       if (true_regnum (operands[1]))
7434         emit_move_insn (operands[0], operands[1]);
7435       else
7436         emit_move_insn (operands[3], operands[1]);
7437       operands[4] = operands[3];
7438     }
7439   else
7440     {
7441       gcc_assert (!true_regnum (operands[1]));
7442       operands[4] = operands[1];
7443     }
7447 (define_expand "divmodsi4"
7448   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7449                    (div:SI (match_operand:SI 1 "register_operand" "")
7450                            (match_operand:SI 2 "nonimmediate_operand" "")))
7451               (set (match_operand:SI 3 "register_operand" "")
7452                    (mod:SI (match_dup 1) (match_dup 2)))
7453               (clobber (reg:CC FLAGS_REG))])]
7454   ""
7455   "")
7457 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7458 ;; Penalize eax case slightly because it results in worse scheduling
7459 ;; of code.
7460 (define_insn "*divmodsi4_nocltd"
7461   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7462         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7463                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7464    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7465         (mod:SI (match_dup 2) (match_dup 3)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "!optimize_size && !TARGET_USE_CLTD"
7468   "#"
7469   [(set_attr "type" "multi")])
7471 (define_insn "*divmodsi4_cltd"
7472   [(set (match_operand:SI 0 "register_operand" "=a")
7473         (div:SI (match_operand:SI 2 "register_operand" "a")
7474                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7475    (set (match_operand:SI 1 "register_operand" "=&d")
7476         (mod:SI (match_dup 2) (match_dup 3)))
7477    (clobber (reg:CC FLAGS_REG))]
7478   "optimize_size || TARGET_USE_CLTD"
7479   "#"
7480   [(set_attr "type" "multi")])
7482 (define_insn "*divmodsi_noext"
7483   [(set (match_operand:SI 0 "register_operand" "=a")
7484         (div:SI (match_operand:SI 1 "register_operand" "0")
7485                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486    (set (match_operand:SI 3 "register_operand" "=d")
7487         (mod:SI (match_dup 1) (match_dup 2)))
7488    (use (match_operand:SI 4 "register_operand" "3"))
7489    (clobber (reg:CC FLAGS_REG))]
7490   ""
7491   "idiv{l}\t%2"
7492   [(set_attr "type" "idiv")
7493    (set_attr "mode" "SI")])
7495 (define_split
7496   [(set (match_operand:SI 0 "register_operand" "")
7497         (div:SI (match_operand:SI 1 "register_operand" "")
7498                 (match_operand:SI 2 "nonimmediate_operand" "")))
7499    (set (match_operand:SI 3 "register_operand" "")
7500         (mod:SI (match_dup 1) (match_dup 2)))
7501    (clobber (reg:CC FLAGS_REG))]
7502   "reload_completed"
7503   [(parallel [(set (match_dup 3)
7504                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7505               (clobber (reg:CC FLAGS_REG))])
7506    (parallel [(set (match_dup 0)
7507                    (div:SI (reg:SI 0) (match_dup 2)))
7508               (set (match_dup 3)
7509                    (mod:SI (reg:SI 0) (match_dup 2)))
7510               (use (match_dup 3))
7511               (clobber (reg:CC FLAGS_REG))])]
7513   /* Avoid use of cltd in favor of a mov+shift.  */
7514   if (!TARGET_USE_CLTD && !optimize_size)
7515     {
7516       if (true_regnum (operands[1]))
7517         emit_move_insn (operands[0], operands[1]);
7518       else
7519         emit_move_insn (operands[3], operands[1]);
7520       operands[4] = operands[3];
7521     }
7522   else
7523     {
7524       gcc_assert (!true_regnum (operands[1]));
7525       operands[4] = operands[1];
7526     }
7528 ;; %%% Split me.
7529 (define_insn "divmodhi4"
7530   [(set (match_operand:HI 0 "register_operand" "=a")
7531         (div:HI (match_operand:HI 1 "register_operand" "0")
7532                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7533    (set (match_operand:HI 3 "register_operand" "=&d")
7534         (mod:HI (match_dup 1) (match_dup 2)))
7535    (clobber (reg:CC FLAGS_REG))]
7536   "TARGET_HIMODE_MATH"
7537   "cwtd\;idiv{w}\t%2"
7538   [(set_attr "type" "multi")
7539    (set_attr "length_immediate" "0")
7540    (set_attr "mode" "SI")])
7542 (define_insn "udivmoddi4"
7543   [(set (match_operand:DI 0 "register_operand" "=a")
7544         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7545                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546    (set (match_operand:DI 3 "register_operand" "=&d")
7547         (umod:DI (match_dup 1) (match_dup 2)))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT"
7550   "xor{q}\t%3, %3\;div{q}\t%2"
7551   [(set_attr "type" "multi")
7552    (set_attr "length_immediate" "0")
7553    (set_attr "mode" "DI")])
7555 (define_insn "*udivmoddi4_noext"
7556   [(set (match_operand:DI 0 "register_operand" "=a")
7557         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7558                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559    (set (match_operand:DI 3 "register_operand" "=d")
7560         (umod:DI (match_dup 1) (match_dup 2)))
7561    (use (match_dup 3))
7562    (clobber (reg:CC FLAGS_REG))]
7563   "TARGET_64BIT"
7564   "div{q}\t%2"
7565   [(set_attr "type" "idiv")
7566    (set_attr "mode" "DI")])
7568 (define_split
7569   [(set (match_operand:DI 0 "register_operand" "")
7570         (udiv:DI (match_operand:DI 1 "register_operand" "")
7571                  (match_operand:DI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:DI 3 "register_operand" "")
7573         (umod:DI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "TARGET_64BIT && reload_completed"
7576   [(set (match_dup 3) (const_int 0))
7577    (parallel [(set (match_dup 0)
7578                    (udiv:DI (match_dup 1) (match_dup 2)))
7579               (set (match_dup 3)
7580                    (umod:DI (match_dup 1) (match_dup 2)))
7581               (use (match_dup 3))
7582               (clobber (reg:CC FLAGS_REG))])]
7583   "")
7585 (define_insn "udivmodsi4"
7586   [(set (match_operand:SI 0 "register_operand" "=a")
7587         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7588                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7589    (set (match_operand:SI 3 "register_operand" "=&d")
7590         (umod:SI (match_dup 1) (match_dup 2)))
7591    (clobber (reg:CC FLAGS_REG))]
7592   ""
7593   "xor{l}\t%3, %3\;div{l}\t%2"
7594   [(set_attr "type" "multi")
7595    (set_attr "length_immediate" "0")
7596    (set_attr "mode" "SI")])
7598 (define_insn "*udivmodsi4_noext"
7599   [(set (match_operand:SI 0 "register_operand" "=a")
7600         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7601                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602    (set (match_operand:SI 3 "register_operand" "=d")
7603         (umod:SI (match_dup 1) (match_dup 2)))
7604    (use (match_dup 3))
7605    (clobber (reg:CC FLAGS_REG))]
7606   ""
7607   "div{l}\t%2"
7608   [(set_attr "type" "idiv")
7609    (set_attr "mode" "SI")])
7611 (define_split
7612   [(set (match_operand:SI 0 "register_operand" "")
7613         (udiv:SI (match_operand:SI 1 "register_operand" "")
7614                  (match_operand:SI 2 "nonimmediate_operand" "")))
7615    (set (match_operand:SI 3 "register_operand" "")
7616         (umod:SI (match_dup 1) (match_dup 2)))
7617    (clobber (reg:CC FLAGS_REG))]
7618   "reload_completed"
7619   [(set (match_dup 3) (const_int 0))
7620    (parallel [(set (match_dup 0)
7621                    (udiv:SI (match_dup 1) (match_dup 2)))
7622               (set (match_dup 3)
7623                    (umod:SI (match_dup 1) (match_dup 2)))
7624               (use (match_dup 3))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   "")
7628 (define_expand "udivmodhi4"
7629   [(set (match_dup 4) (const_int 0))
7630    (parallel [(set (match_operand:HI 0 "register_operand" "")
7631                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7632                             (match_operand:HI 2 "nonimmediate_operand" "")))
7633               (set (match_operand:HI 3 "register_operand" "")
7634                    (umod:HI (match_dup 1) (match_dup 2)))
7635               (use (match_dup 4))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_HIMODE_MATH"
7638   "operands[4] = gen_reg_rtx (HImode);")
7640 (define_insn "*udivmodhi_noext"
7641   [(set (match_operand:HI 0 "register_operand" "=a")
7642         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7643                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:HI 3 "register_operand" "=d")
7645         (umod:HI (match_dup 1) (match_dup 2)))
7646    (use (match_operand:HI 4 "register_operand" "3"))
7647    (clobber (reg:CC FLAGS_REG))]
7648   ""
7649   "div{w}\t%2"
7650   [(set_attr "type" "idiv")
7651    (set_attr "mode" "HI")])
7653 ;; We cannot use div/idiv for double division, because it causes
7654 ;; "division by zero" on the overflow and that's not what we expect
7655 ;; from truncate.  Because true (non truncating) double division is
7656 ;; never generated, we can't create this insn anyway.
7658 ;(define_insn ""
7659 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7660 ;       (truncate:SI
7661 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7662 ;                  (zero_extend:DI
7663 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7664 ;   (set (match_operand:SI 3 "register_operand" "=d")
7665 ;       (truncate:SI
7666 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7667 ;   (clobber (reg:CC FLAGS_REG))]
7668 ;  ""
7669 ;  "div{l}\t{%2, %0|%0, %2}"
7670 ;  [(set_attr "type" "idiv")])
7672 ;;- Logical AND instructions
7674 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7675 ;; Note that this excludes ah.
7677 (define_insn "*testdi_1_rex64"
7678   [(set (reg FLAGS_REG)
7679         (compare
7680           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7681                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7682           (const_int 0)))]
7683   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685   "@
7686    test{l}\t{%k1, %k0|%k0, %k1}
7687    test{l}\t{%k1, %k0|%k0, %k1}
7688    test{q}\t{%1, %0|%0, %1}
7689    test{q}\t{%1, %0|%0, %1}
7690    test{q}\t{%1, %0|%0, %1}"
7691   [(set_attr "type" "test")
7692    (set_attr "modrm" "0,1,0,1,1")
7693    (set_attr "mode" "SI,SI,DI,DI,DI")
7694    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7696 (define_insn "testsi_1"
7697   [(set (reg FLAGS_REG)
7698         (compare
7699           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7700                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7701           (const_int 0)))]
7702   "ix86_match_ccmode (insn, CCNOmode)
7703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704   "test{l}\t{%1, %0|%0, %1}"
7705   [(set_attr "type" "test")
7706    (set_attr "modrm" "0,1,1")
7707    (set_attr "mode" "SI")
7708    (set_attr "pent_pair" "uv,np,uv")])
7710 (define_expand "testsi_ccno_1"
7711   [(set (reg:CCNO FLAGS_REG)
7712         (compare:CCNO
7713           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7714                   (match_operand:SI 1 "nonmemory_operand" ""))
7715           (const_int 0)))]
7716   ""
7717   "")
7719 (define_insn "*testhi_1"
7720   [(set (reg FLAGS_REG)
7721         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7722                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7723                  (const_int 0)))]
7724   "ix86_match_ccmode (insn, CCNOmode)
7725    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7726   "test{w}\t{%1, %0|%0, %1}"
7727   [(set_attr "type" "test")
7728    (set_attr "modrm" "0,1,1")
7729    (set_attr "mode" "HI")
7730    (set_attr "pent_pair" "uv,np,uv")])
7732 (define_expand "testqi_ccz_1"
7733   [(set (reg:CCZ FLAGS_REG)
7734         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7735                              (match_operand:QI 1 "nonmemory_operand" ""))
7736                  (const_int 0)))]
7737   ""
7738   "")
7740 (define_insn "*testqi_1_maybe_si"
7741   [(set (reg FLAGS_REG)
7742         (compare
7743           (and:QI
7744             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7745             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7746           (const_int 0)))]
7747    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7748     && ix86_match_ccmode (insn,
7749                          GET_CODE (operands[1]) == CONST_INT
7750                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7752   if (which_alternative == 3)
7753     {
7754       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7755         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7756       return "test{l}\t{%1, %k0|%k0, %1}";
7757     }
7758   return "test{b}\t{%1, %0|%0, %1}";
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1,1")
7762    (set_attr "mode" "QI,QI,QI,SI")
7763    (set_attr "pent_pair" "uv,np,uv,np")])
7765 (define_insn "*testqi_1"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:QI
7769             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7770             (match_operand:QI 1 "general_operand" "n,n,qn"))
7771           (const_int 0)))]
7772   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7773    && ix86_match_ccmode (insn, CCNOmode)"
7774   "test{b}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "QI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testqi_ext_ccno_0"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI
7784             (zero_extract:SI
7785               (match_operand 0 "ext_register_operand" "")
7786               (const_int 8)
7787               (const_int 8))
7788             (match_operand 1 "const_int_operand" ""))
7789           (const_int 0)))]
7790   ""
7791   "")
7793 (define_insn "*testqi_ext_0"
7794   [(set (reg FLAGS_REG)
7795         (compare
7796           (and:SI
7797             (zero_extract:SI
7798               (match_operand 0 "ext_register_operand" "Q")
7799               (const_int 8)
7800               (const_int 8))
7801             (match_operand 1 "const_int_operand" "n"))
7802           (const_int 0)))]
7803   "ix86_match_ccmode (insn, CCNOmode)"
7804   "test{b}\t{%1, %h0|%h0, %1}"
7805   [(set_attr "type" "test")
7806    (set_attr "mode" "QI")
7807    (set_attr "length_immediate" "1")
7808    (set_attr "pent_pair" "np")])
7810 (define_insn "*testqi_ext_1"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:SI
7814             (zero_extract:SI
7815               (match_operand 0 "ext_register_operand" "Q")
7816               (const_int 8)
7817               (const_int 8))
7818             (zero_extend:SI
7819               (match_operand:QI 1 "general_operand" "Qm")))
7820           (const_int 0)))]
7821   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")])
7827 (define_insn "*testqi_ext_1_rex64"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:SI
7831             (zero_extract:SI
7832               (match_operand 0 "ext_register_operand" "Q")
7833               (const_int 8)
7834               (const_int 8))
7835             (zero_extend:SI
7836               (match_operand:QI 1 "register_operand" "Q")))
7837           (const_int 0)))]
7838   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7839   "test{b}\t{%1, %h0|%h0, %1}"
7840   [(set_attr "type" "test")
7841    (set_attr "mode" "QI")])
7843 (define_insn "*testqi_ext_2"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extract:SI
7852               (match_operand 1 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8)))
7855           (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)"
7857   "test{b}\t{%h1, %h0|%h0, %h1}"
7858   [(set_attr "type" "test")
7859    (set_attr "mode" "QI")])
7861 ;; Combine likes to form bit extractions for some tests.  Humor it.
7862 (define_insn "*testqi_ext_3"
7863   [(set (reg FLAGS_REG)
7864         (compare (zero_extract:SI
7865                    (match_operand 0 "nonimmediate_operand" "rm")
7866                    (match_operand:SI 1 "const_int_operand" "")
7867                    (match_operand:SI 2 "const_int_operand" ""))
7868                  (const_int 0)))]
7869   "ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_MODE (operands[0]) == SImode
7871        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7872        || GET_MODE (operands[0]) == HImode
7873        || GET_MODE (operands[0]) == QImode)"
7874   "#")
7876 (define_insn "*testqi_ext_3_rex64"
7877   [(set (reg FLAGS_REG)
7878         (compare (zero_extract:DI
7879                    (match_operand 0 "nonimmediate_operand" "rm")
7880                    (match_operand:DI 1 "const_int_operand" "")
7881                    (match_operand:DI 2 "const_int_operand" ""))
7882                  (const_int 0)))]
7883   "TARGET_64BIT
7884    && ix86_match_ccmode (insn, CCNOmode)
7885    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7886    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7887    /* Ensure that resulting mask is zero or sign extended operand.  */
7888    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7889        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7890            && INTVAL (operands[1]) > 32))
7891    && (GET_MODE (operands[0]) == SImode
7892        || GET_MODE (operands[0]) == DImode
7893        || GET_MODE (operands[0]) == HImode
7894        || GET_MODE (operands[0]) == QImode)"
7895   "#")
7897 (define_split
7898   [(set (match_operand 0 "flags_reg_operand" "")
7899         (match_operator 1 "compare_operator"
7900           [(zero_extract
7901              (match_operand 2 "nonimmediate_operand" "")
7902              (match_operand 3 "const_int_operand" "")
7903              (match_operand 4 "const_int_operand" ""))
7904            (const_int 0)]))]
7905   "ix86_match_ccmode (insn, CCNOmode)"
7906   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7908   rtx val = operands[2];
7909   HOST_WIDE_INT len = INTVAL (operands[3]);
7910   HOST_WIDE_INT pos = INTVAL (operands[4]);
7911   HOST_WIDE_INT mask;
7912   enum machine_mode mode, submode;
7914   mode = GET_MODE (val);
7915   if (GET_CODE (val) == MEM)
7916     {
7917       /* ??? Combine likes to put non-volatile mem extractions in QImode
7918          no matter the size of the test.  So find a mode that works.  */
7919       if (! MEM_VOLATILE_P (val))
7920         {
7921           mode = smallest_mode_for_size (pos + len, MODE_INT);
7922           val = adjust_address (val, mode, 0);
7923         }
7924     }
7925   else if (GET_CODE (val) == SUBREG
7926            && (submode = GET_MODE (SUBREG_REG (val)),
7927                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7928            && pos + len <= GET_MODE_BITSIZE (submode))
7929     {
7930       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7931       mode = submode;
7932       val = SUBREG_REG (val);
7933     }
7934   else if (mode == HImode && pos + len <= 8)
7935     {
7936       /* Small HImode tests can be converted to QImode.  */
7937       mode = QImode;
7938       val = gen_lowpart (QImode, val);
7939     }
7941   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7942   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7944   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7947 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7948 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7949 ;; this is relatively important trick.
7950 ;; Do the conversion only post-reload to avoid limiting of the register class
7951 ;; to QI regs.
7952 (define_split
7953   [(set (match_operand 0 "flags_reg_operand" "")
7954         (match_operator 1 "compare_operator"
7955           [(and (match_operand 2 "register_operand" "")
7956                 (match_operand 3 "const_int_operand" ""))
7957            (const_int 0)]))]
7958    "reload_completed
7959     && QI_REG_P (operands[2])
7960     && GET_MODE (operands[2]) != QImode
7961     && ((ix86_match_ccmode (insn, CCZmode)
7962          && !(INTVAL (operands[3]) & ~(255 << 8)))
7963         || (ix86_match_ccmode (insn, CCNOmode)
7964             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7965   [(set (match_dup 0)
7966         (match_op_dup 1
7967           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7968                    (match_dup 3))
7969            (const_int 0)]))]
7970   "operands[2] = gen_lowpart (SImode, operands[2]);
7971    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7973 (define_split
7974   [(set (match_operand 0 "flags_reg_operand" "")
7975         (match_operator 1 "compare_operator"
7976           [(and (match_operand 2 "nonimmediate_operand" "")
7977                 (match_operand 3 "const_int_operand" ""))
7978            (const_int 0)]))]
7979    "reload_completed
7980     && GET_MODE (operands[2]) != QImode
7981     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7982     && ((ix86_match_ccmode (insn, CCZmode)
7983          && !(INTVAL (operands[3]) & ~255))
7984         || (ix86_match_ccmode (insn, CCNOmode)
7985             && !(INTVAL (operands[3]) & ~127)))"
7986   [(set (match_dup 0)
7987         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7988                          (const_int 0)]))]
7989   "operands[2] = gen_lowpart (QImode, operands[2]);
7990    operands[3] = gen_lowpart (QImode, operands[3]);")
7993 ;; %%% This used to optimize known byte-wide and operations to memory,
7994 ;; and sometimes to QImode registers.  If this is considered useful,
7995 ;; it should be done with splitters.
7997 (define_expand "anddi3"
7998   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "TARGET_64BIT"
8003   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8005 (define_insn "*anddi_1_rex64"
8006   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8007         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8008                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8009    (clobber (reg:CC FLAGS_REG))]
8010   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8012   switch (get_attr_type (insn))
8013     {
8014     case TYPE_IMOVX:
8015       {
8016         enum machine_mode mode;
8018         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8019         if (INTVAL (operands[2]) == 0xff)
8020           mode = QImode;
8021         else
8022           {
8023             gcc_assert (INTVAL (operands[2]) == 0xffff);
8024             mode = HImode;
8025           }
8026         
8027         operands[1] = gen_lowpart (mode, operands[1]);
8028         if (mode == QImode)
8029           return "movz{bq|x}\t{%1,%0|%0, %1}";
8030         else
8031           return "movz{wq|x}\t{%1,%0|%0, %1}";
8032       }
8034     default:
8035       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8036       if (get_attr_mode (insn) == MODE_SI)
8037         return "and{l}\t{%k2, %k0|%k0, %k2}";
8038       else
8039         return "and{q}\t{%2, %0|%0, %2}";
8040     }
8042   [(set_attr "type" "alu,alu,alu,imovx")
8043    (set_attr "length_immediate" "*,*,*,0")
8044    (set_attr "mode" "SI,DI,DI,DI")])
8046 (define_insn "*anddi_2"
8047   [(set (reg FLAGS_REG)
8048         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8049                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8050                  (const_int 0)))
8051    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8052         (and:DI (match_dup 1) (match_dup 2)))]
8053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8054    && ix86_binary_operator_ok (AND, DImode, operands)"
8055   "@
8056    and{l}\t{%k2, %k0|%k0, %k2}
8057    and{q}\t{%2, %0|%0, %2}
8058    and{q}\t{%2, %0|%0, %2}"
8059   [(set_attr "type" "alu")
8060    (set_attr "mode" "SI,DI,DI")])
8062 (define_expand "andsi3"
8063   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8064         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8065                 (match_operand:SI 2 "general_operand" "")))
8066    (clobber (reg:CC FLAGS_REG))]
8067   ""
8068   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8070 (define_insn "*andsi_1"
8071   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8072         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8073                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8074    (clobber (reg:CC FLAGS_REG))]
8075   "ix86_binary_operator_ok (AND, SImode, operands)"
8077   switch (get_attr_type (insn))
8078     {
8079     case TYPE_IMOVX:
8080       {
8081         enum machine_mode mode;
8083         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8084         if (INTVAL (operands[2]) == 0xff)
8085           mode = QImode;
8086         else
8087           {
8088             gcc_assert (INTVAL (operands[2]) == 0xffff);
8089             mode = HImode;
8090           }
8091         
8092         operands[1] = gen_lowpart (mode, operands[1]);
8093         if (mode == QImode)
8094           return "movz{bl|x}\t{%1,%0|%0, %1}";
8095         else
8096           return "movz{wl|x}\t{%1,%0|%0, %1}";
8097       }
8099     default:
8100       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8101       return "and{l}\t{%2, %0|%0, %2}";
8102     }
8104   [(set_attr "type" "alu,alu,imovx")
8105    (set_attr "length_immediate" "*,*,0")
8106    (set_attr "mode" "SI")])
8108 (define_split
8109   [(set (match_operand 0 "register_operand" "")
8110         (and (match_dup 0)
8111              (const_int -65536)))
8112    (clobber (reg:CC FLAGS_REG))]
8113   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8114   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8115   "operands[1] = gen_lowpart (HImode, operands[0]);")
8117 (define_split
8118   [(set (match_operand 0 "ext_register_operand" "")
8119         (and (match_dup 0)
8120              (const_int -256)))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8123   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8124   "operands[1] = gen_lowpart (QImode, operands[0]);")
8126 (define_split
8127   [(set (match_operand 0 "ext_register_operand" "")
8128         (and (match_dup 0)
8129              (const_int -65281)))
8130    (clobber (reg:CC FLAGS_REG))]
8131   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8132   [(parallel [(set (zero_extract:SI (match_dup 0)
8133                                     (const_int 8)
8134                                     (const_int 8))
8135                    (xor:SI 
8136                      (zero_extract:SI (match_dup 0)
8137                                       (const_int 8)
8138                                       (const_int 8))
8139                      (zero_extract:SI (match_dup 0)
8140                                       (const_int 8)
8141                                       (const_int 8))))
8142               (clobber (reg:CC FLAGS_REG))])]
8143   "operands[0] = gen_lowpart (SImode, operands[0]);")
8145 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8146 (define_insn "*andsi_1_zext"
8147   [(set (match_operand:DI 0 "register_operand" "=r")
8148         (zero_extend:DI
8149           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8150                   (match_operand:SI 2 "general_operand" "rim"))))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8153   "and{l}\t{%2, %k0|%k0, %2}"
8154   [(set_attr "type" "alu")
8155    (set_attr "mode" "SI")])
8157 (define_insn "*andsi_2"
8158   [(set (reg FLAGS_REG)
8159         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8160                          (match_operand:SI 2 "general_operand" "rim,ri"))
8161                  (const_int 0)))
8162    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8163         (and:SI (match_dup 1) (match_dup 2)))]
8164   "ix86_match_ccmode (insn, CCNOmode)
8165    && ix86_binary_operator_ok (AND, SImode, operands)"
8166   "and{l}\t{%2, %0|%0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8170 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171 (define_insn "*andsi_2_zext"
8172   [(set (reg FLAGS_REG)
8173         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8174                          (match_operand:SI 2 "general_operand" "rim"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, SImode, operands)"
8180   "and{l}\t{%2, %k0|%k0, %2}"
8181   [(set_attr "type" "alu")
8182    (set_attr "mode" "SI")])
8184 (define_expand "andhi3"
8185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8186         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8187                 (match_operand:HI 2 "general_operand" "")))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "TARGET_HIMODE_MATH"
8190   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8192 (define_insn "*andhi_1"
8193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8194         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8195                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8196    (clobber (reg:CC FLAGS_REG))]
8197   "ix86_binary_operator_ok (AND, HImode, operands)"
8199   switch (get_attr_type (insn))
8200     {
8201     case TYPE_IMOVX:
8202       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8203       gcc_assert (INTVAL (operands[2]) == 0xff);
8204       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8206     default:
8207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8209       return "and{w}\t{%2, %0|%0, %2}";
8210     }
8212   [(set_attr "type" "alu,alu,imovx")
8213    (set_attr "length_immediate" "*,*,0")
8214    (set_attr "mode" "HI,HI,SI")])
8216 (define_insn "*andhi_2"
8217   [(set (reg FLAGS_REG)
8218         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8219                          (match_operand:HI 2 "general_operand" "rim,ri"))
8220                  (const_int 0)))
8221    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8222         (and:HI (match_dup 1) (match_dup 2)))]
8223   "ix86_match_ccmode (insn, CCNOmode)
8224    && ix86_binary_operator_ok (AND, HImode, operands)"
8225   "and{w}\t{%2, %0|%0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "HI")])
8229 (define_expand "andqi3"
8230   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8231         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8232                 (match_operand:QI 2 "general_operand" "")))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_QIMODE_MATH"
8235   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8237 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8238 (define_insn "*andqi_1"
8239   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8240         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8241                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "ix86_binary_operator_ok (AND, QImode, operands)"
8244   "@
8245    and{b}\t{%2, %0|%0, %2}
8246    and{b}\t{%2, %0|%0, %2}
8247    and{l}\t{%k2, %k0|%k0, %k2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "QI,QI,SI")])
8251 (define_insn "*andqi_1_slp"
8252   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8253         (and:QI (match_dup 0)
8254                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8257    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8258   "and{b}\t{%1, %0|%0, %1}"
8259   [(set_attr "type" "alu1")
8260    (set_attr "mode" "QI")])
8262 (define_insn "*andqi_2_maybe_si"
8263   [(set (reg FLAGS_REG)
8264         (compare (and:QI
8265                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8267                  (const_int 0)))
8268    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8269         (and:QI (match_dup 1) (match_dup 2)))]
8270   "ix86_binary_operator_ok (AND, QImode, operands)
8271    && ix86_match_ccmode (insn,
8272                          GET_CODE (operands[2]) == CONST_INT
8273                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8275   if (which_alternative == 2)
8276     {
8277       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8278         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8279       return "and{l}\t{%2, %k0|%k0, %2}";
8280     }
8281   return "and{b}\t{%2, %0|%0, %2}";
8283   [(set_attr "type" "alu")
8284    (set_attr "mode" "QI,QI,SI")])
8286 (define_insn "*andqi_2"
8287   [(set (reg FLAGS_REG)
8288         (compare (and:QI
8289                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8290                    (match_operand:QI 2 "general_operand" "qim,qi"))
8291                  (const_int 0)))
8292    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8293         (and:QI (match_dup 1) (match_dup 2)))]
8294   "ix86_match_ccmode (insn, CCNOmode)
8295    && ix86_binary_operator_ok (AND, QImode, operands)"
8296   "and{b}\t{%2, %0|%0, %2}"
8297   [(set_attr "type" "alu")
8298    (set_attr "mode" "QI")])
8300 (define_insn "*andqi_2_slp"
8301   [(set (reg FLAGS_REG)
8302         (compare (and:QI
8303                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8304                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8305                  (const_int 0)))
8306    (set (strict_low_part (match_dup 0))
8307         (and:QI (match_dup 0) (match_dup 1)))]
8308   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8309    && ix86_match_ccmode (insn, CCNOmode)
8310    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8311   "and{b}\t{%1, %0|%0, %1}"
8312   [(set_attr "type" "alu1")
8313    (set_attr "mode" "QI")])
8315 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8316 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8317 ;; for a QImode operand, which of course failed.
8319 (define_insn "andqi_ext_0"
8320   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8321                          (const_int 8)
8322                          (const_int 8))
8323         (and:SI 
8324           (zero_extract:SI
8325             (match_operand 1 "ext_register_operand" "0")
8326             (const_int 8)
8327             (const_int 8))
8328           (match_operand 2 "const_int_operand" "n")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   ""
8331   "and{b}\t{%2, %h0|%h0, %2}"
8332   [(set_attr "type" "alu")
8333    (set_attr "length_immediate" "1")
8334    (set_attr "mode" "QI")])
8336 ;; Generated by peephole translating test to and.  This shows up
8337 ;; often in fp comparisons.
8339 (define_insn "*andqi_ext_0_cc"
8340   [(set (reg FLAGS_REG)
8341         (compare
8342           (and:SI
8343             (zero_extract:SI
8344               (match_operand 1 "ext_register_operand" "0")
8345               (const_int 8)
8346               (const_int 8))
8347             (match_operand 2 "const_int_operand" "n"))
8348           (const_int 0)))
8349    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8350                          (const_int 8)
8351                          (const_int 8))
8352         (and:SI 
8353           (zero_extract:SI
8354             (match_dup 1)
8355             (const_int 8)
8356             (const_int 8))
8357           (match_dup 2)))]
8358   "ix86_match_ccmode (insn, CCNOmode)"
8359   "and{b}\t{%2, %h0|%h0, %2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "length_immediate" "1")
8362    (set_attr "mode" "QI")])
8364 (define_insn "*andqi_ext_1"
8365   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366                          (const_int 8)
8367                          (const_int 8))
8368         (and:SI 
8369           (zero_extract:SI
8370             (match_operand 1 "ext_register_operand" "0")
8371             (const_int 8)
8372             (const_int 8))
8373           (zero_extend:SI
8374             (match_operand:QI 2 "general_operand" "Qm"))))
8375    (clobber (reg:CC FLAGS_REG))]
8376   "!TARGET_64BIT"
8377   "and{b}\t{%2, %h0|%h0, %2}"
8378   [(set_attr "type" "alu")
8379    (set_attr "length_immediate" "0")
8380    (set_attr "mode" "QI")])
8382 (define_insn "*andqi_ext_1_rex64"
8383   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8384                          (const_int 8)
8385                          (const_int 8))
8386         (and:SI 
8387           (zero_extract:SI
8388             (match_operand 1 "ext_register_operand" "0")
8389             (const_int 8)
8390             (const_int 8))
8391           (zero_extend:SI
8392             (match_operand 2 "ext_register_operand" "Q"))))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_64BIT"
8395   "and{b}\t{%2, %h0|%h0, %2}"
8396   [(set_attr "type" "alu")
8397    (set_attr "length_immediate" "0")
8398    (set_attr "mode" "QI")])
8400 (define_insn "*andqi_ext_2"
8401   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8402                          (const_int 8)
8403                          (const_int 8))
8404         (and:SI
8405           (zero_extract:SI
8406             (match_operand 1 "ext_register_operand" "%0")
8407             (const_int 8)
8408             (const_int 8))
8409           (zero_extract:SI
8410             (match_operand 2 "ext_register_operand" "Q")
8411             (const_int 8)
8412             (const_int 8))))
8413    (clobber (reg:CC FLAGS_REG))]
8414   ""
8415   "and{b}\t{%h2, %h0|%h0, %h2}"
8416   [(set_attr "type" "alu")
8417    (set_attr "length_immediate" "0")
8418    (set_attr "mode" "QI")])
8420 ;; Convert wide AND instructions with immediate operand to shorter QImode
8421 ;; equivalents when possible.
8422 ;; Don't do the splitting with memory operands, since it introduces risk
8423 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8424 ;; for size, but that can (should?) be handled by generic code instead.
8425 (define_split
8426   [(set (match_operand 0 "register_operand" "")
8427         (and (match_operand 1 "register_operand" "")
8428              (match_operand 2 "const_int_operand" "")))
8429    (clobber (reg:CC FLAGS_REG))]
8430    "reload_completed
8431     && QI_REG_P (operands[0])
8432     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8433     && !(~INTVAL (operands[2]) & ~(255 << 8))
8434     && GET_MODE (operands[0]) != QImode"
8435   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8436                    (and:SI (zero_extract:SI (match_dup 1)
8437                                             (const_int 8) (const_int 8))
8438                            (match_dup 2)))
8439               (clobber (reg:CC FLAGS_REG))])]
8440   "operands[0] = gen_lowpart (SImode, operands[0]);
8441    operands[1] = gen_lowpart (SImode, operands[1]);
8442    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8444 ;; Since AND can be encoded with sign extended immediate, this is only
8445 ;; profitable when 7th bit is not set.
8446 (define_split
8447   [(set (match_operand 0 "register_operand" "")
8448         (and (match_operand 1 "general_operand" "")
8449              (match_operand 2 "const_int_operand" "")))
8450    (clobber (reg:CC FLAGS_REG))]
8451    "reload_completed
8452     && ANY_QI_REG_P (operands[0])
8453     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8454     && !(~INTVAL (operands[2]) & ~255)
8455     && !(INTVAL (operands[2]) & 128)
8456     && GET_MODE (operands[0]) != QImode"
8457   [(parallel [(set (strict_low_part (match_dup 0))
8458                    (and:QI (match_dup 1)
8459                            (match_dup 2)))
8460               (clobber (reg:CC FLAGS_REG))])]
8461   "operands[0] = gen_lowpart (QImode, operands[0]);
8462    operands[1] = gen_lowpart (QImode, operands[1]);
8463    operands[2] = gen_lowpart (QImode, operands[2]);")
8465 ;; Logical inclusive OR instructions
8467 ;; %%% This used to optimize known byte-wide and operations to memory.
8468 ;; If this is considered useful, it should be done with splitters.
8470 (define_expand "iordi3"
8471   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8472         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8473                 (match_operand:DI 2 "x86_64_general_operand" "")))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "TARGET_64BIT"
8476   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8478 (define_insn "*iordi_1_rex64"
8479   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8480         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8481                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT
8484    && ix86_binary_operator_ok (IOR, DImode, operands)"
8485   "or{q}\t{%2, %0|%0, %2}"
8486   [(set_attr "type" "alu")
8487    (set_attr "mode" "DI")])
8489 (define_insn "*iordi_2_rex64"
8490   [(set (reg FLAGS_REG)
8491         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8492                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8493                  (const_int 0)))
8494    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8495         (ior:DI (match_dup 1) (match_dup 2)))]
8496   "TARGET_64BIT
8497    && ix86_match_ccmode (insn, CCNOmode)
8498    && ix86_binary_operator_ok (IOR, DImode, operands)"
8499   "or{q}\t{%2, %0|%0, %2}"
8500   [(set_attr "type" "alu")
8501    (set_attr "mode" "DI")])
8503 (define_insn "*iordi_3_rex64"
8504   [(set (reg FLAGS_REG)
8505         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8506                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8507                  (const_int 0)))
8508    (clobber (match_scratch:DI 0 "=r"))]
8509   "TARGET_64BIT
8510    && ix86_match_ccmode (insn, CCNOmode)
8511    && ix86_binary_operator_ok (IOR, DImode, operands)"
8512   "or{q}\t{%2, %0|%0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "mode" "DI")])
8517 (define_expand "iorsi3"
8518   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8519         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8520                 (match_operand:SI 2 "general_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   ""
8523   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8525 (define_insn "*iorsi_1"
8526   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8527         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8528                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8529    (clobber (reg:CC FLAGS_REG))]
8530   "ix86_binary_operator_ok (IOR, SImode, operands)"
8531   "or{l}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "SI")])
8535 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8536 (define_insn "*iorsi_1_zext"
8537   [(set (match_operand:DI 0 "register_operand" "=rm")
8538         (zero_extend:DI
8539           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8540                   (match_operand:SI 2 "general_operand" "rim"))))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8543   "or{l}\t{%2, %k0|%k0, %2}"
8544   [(set_attr "type" "alu")
8545    (set_attr "mode" "SI")])
8547 (define_insn "*iorsi_1_zext_imm"
8548   [(set (match_operand:DI 0 "register_operand" "=rm")
8549         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8550                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8551    (clobber (reg:CC FLAGS_REG))]
8552   "TARGET_64BIT"
8553   "or{l}\t{%2, %k0|%k0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "SI")])
8557 (define_insn "*iorsi_2"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8560                          (match_operand:SI 2 "general_operand" "rim,ri"))
8561                  (const_int 0)))
8562    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8563         (ior:SI (match_dup 1) (match_dup 2)))]
8564   "ix86_match_ccmode (insn, CCNOmode)
8565    && ix86_binary_operator_ok (IOR, SImode, operands)"
8566   "or{l}\t{%2, %0|%0, %2}"
8567   [(set_attr "type" "alu")
8568    (set_attr "mode" "SI")])
8570 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8571 ;; ??? Special case for immediate operand is missing - it is tricky.
8572 (define_insn "*iorsi_2_zext"
8573   [(set (reg FLAGS_REG)
8574         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:SI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (set (match_operand:DI 0 "register_operand" "=r")
8578         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8579   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8580    && ix86_binary_operator_ok (IOR, SImode, operands)"
8581   "or{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8585 (define_insn "*iorsi_2_zext_imm"
8586   [(set (reg FLAGS_REG)
8587         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8588                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8589                  (const_int 0)))
8590    (set (match_operand:DI 0 "register_operand" "=r")
8591         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8592   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8593    && ix86_binary_operator_ok (IOR, SImode, operands)"
8594   "or{l}\t{%2, %k0|%k0, %2}"
8595   [(set_attr "type" "alu")
8596    (set_attr "mode" "SI")])
8598 (define_insn "*iorsi_3"
8599   [(set (reg FLAGS_REG)
8600         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8601                          (match_operand:SI 2 "general_operand" "rim"))
8602                  (const_int 0)))
8603    (clobber (match_scratch:SI 0 "=r"))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8606   "or{l}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "SI")])
8610 (define_expand "iorhi3"
8611   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8612         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8613                 (match_operand:HI 2 "general_operand" "")))
8614    (clobber (reg:CC FLAGS_REG))]
8615   "TARGET_HIMODE_MATH"
8616   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8618 (define_insn "*iorhi_1"
8619   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8620         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8621                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "ix86_binary_operator_ok (IOR, HImode, operands)"
8624   "or{w}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "HI")])
8628 (define_insn "*iorhi_2"
8629   [(set (reg FLAGS_REG)
8630         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631                          (match_operand:HI 2 "general_operand" "rim,ri"))
8632                  (const_int 0)))
8633    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8634         (ior:HI (match_dup 1) (match_dup 2)))]
8635   "ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, HImode, operands)"
8637   "or{w}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "HI")])
8641 (define_insn "*iorhi_3"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:HI 2 "general_operand" "rim"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:HI 0 "=r"))]
8647   "ix86_match_ccmode (insn, CCNOmode)
8648    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8649   "or{w}\t{%2, %0|%0, %2}"
8650   [(set_attr "type" "alu")
8651    (set_attr "mode" "HI")])
8653 (define_expand "iorqi3"
8654   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8655         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8656                 (match_operand:QI 2 "general_operand" "")))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_QIMODE_MATH"
8659   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8661 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8662 (define_insn "*iorqi_1"
8663   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8664         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8665                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "ix86_binary_operator_ok (IOR, QImode, operands)"
8668   "@
8669    or{b}\t{%2, %0|%0, %2}
8670    or{b}\t{%2, %0|%0, %2}
8671    or{l}\t{%k2, %k0|%k0, %k2}"
8672   [(set_attr "type" "alu")
8673    (set_attr "mode" "QI,QI,SI")])
8675 (define_insn "*iorqi_1_slp"
8676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8677         (ior:QI (match_dup 0)
8678                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8681    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8682   "or{b}\t{%1, %0|%0, %1}"
8683   [(set_attr "type" "alu1")
8684    (set_attr "mode" "QI")])
8686 (define_insn "*iorqi_2"
8687   [(set (reg FLAGS_REG)
8688         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8689                          (match_operand:QI 2 "general_operand" "qim,qi"))
8690                  (const_int 0)))
8691    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8692         (ior:QI (match_dup 1) (match_dup 2)))]
8693   "ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (IOR, QImode, operands)"
8695   "or{b}\t{%2, %0|%0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "QI")])
8699 (define_insn "*iorqi_2_slp"
8700   [(set (reg FLAGS_REG)
8701         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8702                          (match_operand:QI 1 "general_operand" "qim,qi"))
8703                  (const_int 0)))
8704    (set (strict_low_part (match_dup 0))
8705         (ior:QI (match_dup 0) (match_dup 1)))]
8706   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8707    && ix86_match_ccmode (insn, CCNOmode)
8708    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8709   "or{b}\t{%1, %0|%0, %1}"
8710   [(set_attr "type" "alu1")
8711    (set_attr "mode" "QI")])
8713 (define_insn "*iorqi_3"
8714   [(set (reg FLAGS_REG)
8715         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8716                          (match_operand:QI 2 "general_operand" "qim"))
8717                  (const_int 0)))
8718    (clobber (match_scratch:QI 0 "=q"))]
8719   "ix86_match_ccmode (insn, CCNOmode)
8720    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8721   "or{b}\t{%2, %0|%0, %2}"
8722   [(set_attr "type" "alu")
8723    (set_attr "mode" "QI")])
8725 (define_insn "iorqi_ext_0"
8726   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8727                          (const_int 8)
8728                          (const_int 8))
8729         (ior:SI 
8730           (zero_extract:SI
8731             (match_operand 1 "ext_register_operand" "0")
8732             (const_int 8)
8733             (const_int 8))
8734           (match_operand 2 "const_int_operand" "n")))
8735    (clobber (reg:CC FLAGS_REG))]
8736   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8737   "or{b}\t{%2, %h0|%h0, %2}"
8738   [(set_attr "type" "alu")
8739    (set_attr "length_immediate" "1")
8740    (set_attr "mode" "QI")])
8742 (define_insn "*iorqi_ext_1"
8743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8744                          (const_int 8)
8745                          (const_int 8))
8746         (ior:SI 
8747           (zero_extract:SI
8748             (match_operand 1 "ext_register_operand" "0")
8749             (const_int 8)
8750             (const_int 8))
8751           (zero_extend:SI
8752             (match_operand:QI 2 "general_operand" "Qm"))))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "!TARGET_64BIT
8755    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8756   "or{b}\t{%2, %h0|%h0, %2}"
8757   [(set_attr "type" "alu")
8758    (set_attr "length_immediate" "0")
8759    (set_attr "mode" "QI")])
8761 (define_insn "*iorqi_ext_1_rex64"
8762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8763                          (const_int 8)
8764                          (const_int 8))
8765         (ior:SI 
8766           (zero_extract:SI
8767             (match_operand 1 "ext_register_operand" "0")
8768             (const_int 8)
8769             (const_int 8))
8770           (zero_extend:SI
8771             (match_operand 2 "ext_register_operand" "Q"))))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "TARGET_64BIT
8774    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8775   "or{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "length_immediate" "0")
8778    (set_attr "mode" "QI")])
8780 (define_insn "*iorqi_ext_2"
8781   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8782                          (const_int 8)
8783                          (const_int 8))
8784         (ior:SI 
8785           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8786                            (const_int 8)
8787                            (const_int 8))
8788           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8789                            (const_int 8)
8790                            (const_int 8))))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8793   "ior{b}\t{%h2, %h0|%h0, %h2}"
8794   [(set_attr "type" "alu")
8795    (set_attr "length_immediate" "0")
8796    (set_attr "mode" "QI")])
8798 (define_split
8799   [(set (match_operand 0 "register_operand" "")
8800         (ior (match_operand 1 "register_operand" "")
8801              (match_operand 2 "const_int_operand" "")))
8802    (clobber (reg:CC FLAGS_REG))]
8803    "reload_completed
8804     && QI_REG_P (operands[0])
8805     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8806     && !(INTVAL (operands[2]) & ~(255 << 8))
8807     && GET_MODE (operands[0]) != QImode"
8808   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8809                    (ior:SI (zero_extract:SI (match_dup 1)
8810                                             (const_int 8) (const_int 8))
8811                            (match_dup 2)))
8812               (clobber (reg:CC FLAGS_REG))])]
8813   "operands[0] = gen_lowpart (SImode, operands[0]);
8814    operands[1] = gen_lowpart (SImode, operands[1]);
8815    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8817 ;; Since OR can be encoded with sign extended immediate, this is only
8818 ;; profitable when 7th bit is set.
8819 (define_split
8820   [(set (match_operand 0 "register_operand" "")
8821         (ior (match_operand 1 "general_operand" "")
8822              (match_operand 2 "const_int_operand" "")))
8823    (clobber (reg:CC FLAGS_REG))]
8824    "reload_completed
8825     && ANY_QI_REG_P (operands[0])
8826     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8827     && !(INTVAL (operands[2]) & ~255)
8828     && (INTVAL (operands[2]) & 128)
8829     && GET_MODE (operands[0]) != QImode"
8830   [(parallel [(set (strict_low_part (match_dup 0))
8831                    (ior:QI (match_dup 1)
8832                            (match_dup 2)))
8833               (clobber (reg:CC FLAGS_REG))])]
8834   "operands[0] = gen_lowpart (QImode, operands[0]);
8835    operands[1] = gen_lowpart (QImode, operands[1]);
8836    operands[2] = gen_lowpart (QImode, operands[2]);")
8838 ;; Logical XOR instructions
8840 ;; %%% This used to optimize known byte-wide and operations to memory.
8841 ;; If this is considered useful, it should be done with splitters.
8843 (define_expand "xordi3"
8844   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8845         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8846                 (match_operand:DI 2 "x86_64_general_operand" "")))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "TARGET_64BIT"
8849   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8851 (define_insn "*xordi_1_rex64"
8852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8853         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8854                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8855    (clobber (reg:CC FLAGS_REG))]
8856   "TARGET_64BIT
8857    && ix86_binary_operator_ok (XOR, DImode, operands)"
8858   "@
8859    xor{q}\t{%2, %0|%0, %2}
8860    xor{q}\t{%2, %0|%0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "DI,DI")])
8864 (define_insn "*xordi_2_rex64"
8865   [(set (reg FLAGS_REG)
8866         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8867                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8868                  (const_int 0)))
8869    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8870         (xor:DI (match_dup 1) (match_dup 2)))]
8871   "TARGET_64BIT
8872    && ix86_match_ccmode (insn, CCNOmode)
8873    && ix86_binary_operator_ok (XOR, DImode, operands)"
8874   "@
8875    xor{q}\t{%2, %0|%0, %2}
8876    xor{q}\t{%2, %0|%0, %2}"
8877   [(set_attr "type" "alu")
8878    (set_attr "mode" "DI,DI")])
8880 (define_insn "*xordi_3_rex64"
8881   [(set (reg FLAGS_REG)
8882         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8883                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8884                  (const_int 0)))
8885    (clobber (match_scratch:DI 0 "=r"))]
8886   "TARGET_64BIT
8887    && ix86_match_ccmode (insn, CCNOmode)
8888    && ix86_binary_operator_ok (XOR, DImode, operands)"
8889   "xor{q}\t{%2, %0|%0, %2}"
8890   [(set_attr "type" "alu")
8891    (set_attr "mode" "DI")])
8893 (define_expand "xorsi3"
8894   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8895         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8896                 (match_operand:SI 2 "general_operand" "")))
8897    (clobber (reg:CC FLAGS_REG))]
8898   ""
8899   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8901 (define_insn "*xorsi_1"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8903         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8904                 (match_operand:SI 2 "general_operand" "ri,rm")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "ix86_binary_operator_ok (XOR, SImode, operands)"
8907   "xor{l}\t{%2, %0|%0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "mode" "SI")])
8911 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8912 ;; Add speccase for immediates
8913 (define_insn "*xorsi_1_zext"
8914   [(set (match_operand:DI 0 "register_operand" "=r")
8915         (zero_extend:DI
8916           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8917                   (match_operand:SI 2 "general_operand" "rim"))))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8920   "xor{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8924 (define_insn "*xorsi_1_zext_imm"
8925   [(set (match_operand:DI 0 "register_operand" "=r")
8926         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8927                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930   "xor{l}\t{%2, %k0|%k0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "SI")])
8934 (define_insn "*xorsi_2"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8937                          (match_operand:SI 2 "general_operand" "rim,ri"))
8938                  (const_int 0)))
8939    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8940         (xor:SI (match_dup 1) (match_dup 2)))]
8941   "ix86_match_ccmode (insn, CCNOmode)
8942    && ix86_binary_operator_ok (XOR, SImode, operands)"
8943   "xor{l}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "SI")])
8947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8948 ;; ??? Special case for immediate operand is missing - it is tricky.
8949 (define_insn "*xorsi_2_zext"
8950   [(set (reg FLAGS_REG)
8951         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8952                          (match_operand:SI 2 "general_operand" "rim"))
8953                  (const_int 0)))
8954    (set (match_operand:DI 0 "register_operand" "=r")
8955         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8956   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8957    && ix86_binary_operator_ok (XOR, SImode, operands)"
8958   "xor{l}\t{%2, %k0|%k0, %2}"
8959   [(set_attr "type" "alu")
8960    (set_attr "mode" "SI")])
8962 (define_insn "*xorsi_2_zext_imm"
8963   [(set (reg FLAGS_REG)
8964         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8965                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8966                  (const_int 0)))
8967    (set (match_operand:DI 0 "register_operand" "=r")
8968         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8969   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8970    && ix86_binary_operator_ok (XOR, SImode, operands)"
8971   "xor{l}\t{%2, %k0|%k0, %2}"
8972   [(set_attr "type" "alu")
8973    (set_attr "mode" "SI")])
8975 (define_insn "*xorsi_3"
8976   [(set (reg FLAGS_REG)
8977         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8978                          (match_operand:SI 2 "general_operand" "rim"))
8979                  (const_int 0)))
8980    (clobber (match_scratch:SI 0 "=r"))]
8981   "ix86_match_ccmode (insn, CCNOmode)
8982    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8983   "xor{l}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8987 (define_expand "xorhi3"
8988   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8989         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8990                 (match_operand:HI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "TARGET_HIMODE_MATH"
8993   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8995 (define_insn "*xorhi_1"
8996   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8997         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, HImode, operands)"
9001   "xor{w}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "HI")])
9005 (define_insn "*xorhi_2"
9006   [(set (reg FLAGS_REG)
9007         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008                          (match_operand:HI 2 "general_operand" "rim,ri"))
9009                  (const_int 0)))
9010    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9011         (xor:HI (match_dup 1) (match_dup 2)))]
9012   "ix86_match_ccmode (insn, CCNOmode)
9013    && ix86_binary_operator_ok (XOR, HImode, operands)"
9014   "xor{w}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "HI")])
9018 (define_insn "*xorhi_3"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:HI 2 "general_operand" "rim"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:HI 0 "=r"))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9026   "xor{w}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "HI")])
9030 (define_expand "xorqi3"
9031   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9032         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9033                 (match_operand:QI 2 "general_operand" "")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "TARGET_QIMODE_MATH"
9036   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9038 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9039 (define_insn "*xorqi_1"
9040   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9041         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9042                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, QImode, operands)"
9045   "@
9046    xor{b}\t{%2, %0|%0, %2}
9047    xor{b}\t{%2, %0|%0, %2}
9048    xor{l}\t{%k2, %k0|%k0, %k2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "QI,QI,SI")])
9052 (define_insn "*xorqi_1_slp"
9053   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9054         (xor:QI (match_dup 0)
9055                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9058    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9059   "xor{b}\t{%1, %0|%0, %1}"
9060   [(set_attr "type" "alu1")
9061    (set_attr "mode" "QI")])
9063 (define_insn "xorqi_ext_0"
9064   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065                          (const_int 8)
9066                          (const_int 8))
9067         (xor:SI 
9068           (zero_extract:SI
9069             (match_operand 1 "ext_register_operand" "0")
9070             (const_int 8)
9071             (const_int 8))
9072           (match_operand 2 "const_int_operand" "n")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9075   "xor{b}\t{%2, %h0|%h0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "length_immediate" "1")
9078    (set_attr "mode" "QI")])
9080 (define_insn "*xorqi_ext_1"
9081   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9082                          (const_int 8)
9083                          (const_int 8))
9084         (xor:SI 
9085           (zero_extract:SI
9086             (match_operand 1 "ext_register_operand" "0")
9087             (const_int 8)
9088             (const_int 8))
9089           (zero_extend:SI
9090             (match_operand:QI 2 "general_operand" "Qm"))))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "!TARGET_64BIT
9093    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9094   "xor{b}\t{%2, %h0|%h0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "length_immediate" "0")
9097    (set_attr "mode" "QI")])
9099 (define_insn "*xorqi_ext_1_rex64"
9100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9101                          (const_int 8)
9102                          (const_int 8))
9103         (xor:SI 
9104           (zero_extract:SI
9105             (match_operand 1 "ext_register_operand" "0")
9106             (const_int 8)
9107             (const_int 8))
9108           (zero_extend:SI
9109             (match_operand 2 "ext_register_operand" "Q"))))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "TARGET_64BIT
9112    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9113   "xor{b}\t{%2, %h0|%h0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "length_immediate" "0")
9116    (set_attr "mode" "QI")])
9118 (define_insn "*xorqi_ext_2"
9119   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9120                          (const_int 8)
9121                          (const_int 8))
9122         (xor:SI 
9123           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9124                            (const_int 8)
9125                            (const_int 8))
9126           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9127                            (const_int 8)
9128                            (const_int 8))))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9131   "xor{b}\t{%h2, %h0|%h0, %h2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "length_immediate" "0")
9134    (set_attr "mode" "QI")])
9136 (define_insn "*xorqi_cc_1"
9137   [(set (reg FLAGS_REG)
9138         (compare
9139           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9140                   (match_operand:QI 2 "general_operand" "qim,qi"))
9141           (const_int 0)))
9142    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9143         (xor:QI (match_dup 1) (match_dup 2)))]
9144   "ix86_match_ccmode (insn, CCNOmode)
9145    && ix86_binary_operator_ok (XOR, QImode, operands)"
9146   "xor{b}\t{%2, %0|%0, %2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "mode" "QI")])
9150 (define_insn "*xorqi_2_slp"
9151   [(set (reg FLAGS_REG)
9152         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9153                          (match_operand:QI 1 "general_operand" "qim,qi"))
9154                  (const_int 0)))
9155    (set (strict_low_part (match_dup 0))
9156         (xor:QI (match_dup 0) (match_dup 1)))]
9157   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9158    && ix86_match_ccmode (insn, CCNOmode)
9159    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9160   "xor{b}\t{%1, %0|%0, %1}"
9161   [(set_attr "type" "alu1")
9162    (set_attr "mode" "QI")])
9164 (define_insn "*xorqi_cc_2"
9165   [(set (reg FLAGS_REG)
9166         (compare
9167           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9168                   (match_operand:QI 2 "general_operand" "qim"))
9169           (const_int 0)))
9170    (clobber (match_scratch:QI 0 "=q"))]
9171   "ix86_match_ccmode (insn, CCNOmode)
9172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9173   "xor{b}\t{%2, %0|%0, %2}"
9174   [(set_attr "type" "alu")
9175    (set_attr "mode" "QI")])
9177 (define_insn "*xorqi_cc_ext_1"
9178   [(set (reg FLAGS_REG)
9179         (compare
9180           (xor:SI
9181             (zero_extract:SI
9182               (match_operand 1 "ext_register_operand" "0")
9183               (const_int 8)
9184               (const_int 8))
9185             (match_operand:QI 2 "general_operand" "qmn"))
9186           (const_int 0)))
9187    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9188                          (const_int 8)
9189                          (const_int 8))
9190         (xor:SI 
9191           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9192           (match_dup 2)))]
9193   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9194   "xor{b}\t{%2, %h0|%h0, %2}"
9195   [(set_attr "type" "alu")
9196    (set_attr "mode" "QI")])
9198 (define_insn "*xorqi_cc_ext_1_rex64"
9199   [(set (reg FLAGS_REG)
9200         (compare
9201           (xor:SI
9202             (zero_extract:SI
9203               (match_operand 1 "ext_register_operand" "0")
9204               (const_int 8)
9205               (const_int 8))
9206             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9207           (const_int 0)))
9208    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9209                          (const_int 8)
9210                          (const_int 8))
9211         (xor:SI 
9212           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9213           (match_dup 2)))]
9214   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9215   "xor{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "mode" "QI")])
9219 (define_expand "xorqi_cc_ext_1"
9220   [(parallel [
9221      (set (reg:CCNO FLAGS_REG)
9222           (compare:CCNO
9223             (xor:SI
9224               (zero_extract:SI
9225                 (match_operand 1 "ext_register_operand" "")
9226                 (const_int 8)
9227                 (const_int 8))
9228               (match_operand:QI 2 "general_operand" ""))
9229             (const_int 0)))
9230      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9231                            (const_int 8)
9232                            (const_int 8))
9233           (xor:SI 
9234             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9235             (match_dup 2)))])]
9236   ""
9237   "")
9239 (define_split
9240   [(set (match_operand 0 "register_operand" "")
9241         (xor (match_operand 1 "register_operand" "")
9242              (match_operand 2 "const_int_operand" "")))
9243    (clobber (reg:CC FLAGS_REG))]
9244    "reload_completed
9245     && QI_REG_P (operands[0])
9246     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9247     && !(INTVAL (operands[2]) & ~(255 << 8))
9248     && GET_MODE (operands[0]) != QImode"
9249   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9250                    (xor:SI (zero_extract:SI (match_dup 1)
9251                                             (const_int 8) (const_int 8))
9252                            (match_dup 2)))
9253               (clobber (reg:CC FLAGS_REG))])]
9254   "operands[0] = gen_lowpart (SImode, operands[0]);
9255    operands[1] = gen_lowpart (SImode, operands[1]);
9256    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9258 ;; Since XOR can be encoded with sign extended immediate, this is only
9259 ;; profitable when 7th bit is set.
9260 (define_split
9261   [(set (match_operand 0 "register_operand" "")
9262         (xor (match_operand 1 "general_operand" "")
9263              (match_operand 2 "const_int_operand" "")))
9264    (clobber (reg:CC FLAGS_REG))]
9265    "reload_completed
9266     && ANY_QI_REG_P (operands[0])
9267     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9268     && !(INTVAL (operands[2]) & ~255)
9269     && (INTVAL (operands[2]) & 128)
9270     && GET_MODE (operands[0]) != QImode"
9271   [(parallel [(set (strict_low_part (match_dup 0))
9272                    (xor:QI (match_dup 1)
9273                            (match_dup 2)))
9274               (clobber (reg:CC FLAGS_REG))])]
9275   "operands[0] = gen_lowpart (QImode, operands[0]);
9276    operands[1] = gen_lowpart (QImode, operands[1]);
9277    operands[2] = gen_lowpart (QImode, operands[2]);")
9279 ;; Negation instructions
9281 (define_expand "negti2"
9282   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9283                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9284               (clobber (reg:CC FLAGS_REG))])]
9285   "TARGET_64BIT"
9286   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9288 (define_insn "*negti2_1"
9289   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9290         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9291    (clobber (reg:CC FLAGS_REG))]
9292   "TARGET_64BIT
9293    && ix86_unary_operator_ok (NEG, TImode, operands)"
9294   "#")
9296 (define_split
9297   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9298         (neg:TI (match_operand:TI 1 "general_operand" "")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "TARGET_64BIT && reload_completed"
9301   [(parallel
9302     [(set (reg:CCZ FLAGS_REG)
9303           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9304      (set (match_dup 0) (neg:DI (match_dup 2)))])
9305    (parallel
9306     [(set (match_dup 1)
9307           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9308                             (match_dup 3))
9309                    (const_int 0)))
9310      (clobber (reg:CC FLAGS_REG))])
9311    (parallel
9312     [(set (match_dup 1)
9313           (neg:DI (match_dup 1)))
9314      (clobber (reg:CC FLAGS_REG))])]
9315   "split_ti (operands+1, 1, operands+2, operands+3);
9316    split_ti (operands+0, 1, operands+0, operands+1);")
9318 (define_expand "negdi2"
9319   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9320                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9321               (clobber (reg:CC FLAGS_REG))])]
9322   ""
9323   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9325 (define_insn "*negdi2_1"
9326   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9327         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "!TARGET_64BIT
9330    && ix86_unary_operator_ok (NEG, DImode, operands)"
9331   "#")
9333 (define_split
9334   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9335         (neg:DI (match_operand:DI 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:SI (match_dup 2)) (const_int 0)))
9341      (set (match_dup 0) (neg:SI (match_dup 2)))])
9342    (parallel
9343     [(set (match_dup 1)
9344           (plus:SI (plus:SI (ltu:SI (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:SI (match_dup 1)))
9351      (clobber (reg:CC FLAGS_REG))])]
9352   "split_di (operands+1, 1, operands+2, operands+3);
9353    split_di (operands+0, 1, operands+0, operands+1);")
9355 (define_insn "*negdi2_1_rex64"
9356   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9357         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9358    (clobber (reg:CC FLAGS_REG))]
9359   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9360   "neg{q}\t%0"
9361   [(set_attr "type" "negnot")
9362    (set_attr "mode" "DI")])
9364 ;; The problem with neg is that it does not perform (compare x 0),
9365 ;; it really performs (compare 0 x), which leaves us with the zero
9366 ;; flag being the only useful item.
9368 (define_insn "*negdi2_cmpz_rex64"
9369   [(set (reg:CCZ FLAGS_REG)
9370         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9371                      (const_int 0)))
9372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9373         (neg:DI (match_dup 1)))]
9374   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9375   "neg{q}\t%0"
9376   [(set_attr "type" "negnot")
9377    (set_attr "mode" "DI")])
9380 (define_expand "negsi2"
9381   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9382                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9383               (clobber (reg:CC FLAGS_REG))])]
9384   ""
9385   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9387 (define_insn "*negsi2_1"
9388   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9389         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "ix86_unary_operator_ok (NEG, SImode, operands)"
9392   "neg{l}\t%0"
9393   [(set_attr "type" "negnot")
9394    (set_attr "mode" "SI")])
9396 ;; Combine is quite creative about this pattern.
9397 (define_insn "*negsi2_1_zext"
9398   [(set (match_operand:DI 0 "register_operand" "=r")
9399         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9400                                         (const_int 32)))
9401                      (const_int 32)))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9404   "neg{l}\t%k0"
9405   [(set_attr "type" "negnot")
9406    (set_attr "mode" "SI")])
9408 ;; The problem with neg is that it does not perform (compare x 0),
9409 ;; it really performs (compare 0 x), which leaves us with the zero
9410 ;; flag being the only useful item.
9412 (define_insn "*negsi2_cmpz"
9413   [(set (reg:CCZ FLAGS_REG)
9414         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9415                      (const_int 0)))
9416    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9417         (neg:SI (match_dup 1)))]
9418   "ix86_unary_operator_ok (NEG, SImode, operands)"
9419   "neg{l}\t%0"
9420   [(set_attr "type" "negnot")
9421    (set_attr "mode" "SI")])
9423 (define_insn "*negsi2_cmpz_zext"
9424   [(set (reg:CCZ FLAGS_REG)
9425         (compare:CCZ (lshiftrt:DI
9426                        (neg:DI (ashift:DI
9427                                  (match_operand:DI 1 "register_operand" "0")
9428                                  (const_int 32)))
9429                        (const_int 32))
9430                      (const_int 0)))
9431    (set (match_operand:DI 0 "register_operand" "=r")
9432         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9433                                         (const_int 32)))
9434                      (const_int 32)))]
9435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9436   "neg{l}\t%k0"
9437   [(set_attr "type" "negnot")
9438    (set_attr "mode" "SI")])
9440 (define_expand "neghi2"
9441   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9442                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9443               (clobber (reg:CC FLAGS_REG))])]
9444   "TARGET_HIMODE_MATH"
9445   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9447 (define_insn "*neghi2_1"
9448   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9449         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "ix86_unary_operator_ok (NEG, HImode, operands)"
9452   "neg{w}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "HI")])
9456 (define_insn "*neghi2_cmpz"
9457   [(set (reg:CCZ FLAGS_REG)
9458         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9459                      (const_int 0)))
9460    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9461         (neg:HI (match_dup 1)))]
9462   "ix86_unary_operator_ok (NEG, HImode, operands)"
9463   "neg{w}\t%0"
9464   [(set_attr "type" "negnot")
9465    (set_attr "mode" "HI")])
9467 (define_expand "negqi2"
9468   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9469                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9470               (clobber (reg:CC FLAGS_REG))])]
9471   "TARGET_QIMODE_MATH"
9472   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9474 (define_insn "*negqi2_1"
9475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9476         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9477    (clobber (reg:CC FLAGS_REG))]
9478   "ix86_unary_operator_ok (NEG, QImode, operands)"
9479   "neg{b}\t%0"
9480   [(set_attr "type" "negnot")
9481    (set_attr "mode" "QI")])
9483 (define_insn "*negqi2_cmpz"
9484   [(set (reg:CCZ FLAGS_REG)
9485         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9486                      (const_int 0)))
9487    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9488         (neg:QI (match_dup 1)))]
9489   "ix86_unary_operator_ok (NEG, QImode, operands)"
9490   "neg{b}\t%0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "QI")])
9494 ;; Changing of sign for FP values is doable using integer unit too.
9496 (define_expand "negsf2"
9497   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9498         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9499   "TARGET_80387 || TARGET_SSE_MATH"
9500   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9502 (define_expand "abssf2"
9503   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9504         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9505   "TARGET_80387 || TARGET_SSE_MATH"
9506   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9508 (define_insn "*absnegsf2_mixed"
9509   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9510         (match_operator:SF 3 "absneg_operator"
9511           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9512    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9515    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9516   "#")
9518 (define_insn "*absnegsf2_sse"
9519   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9520         (match_operator:SF 3 "absneg_operator"
9521           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9522    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9523    (clobber (reg:CC FLAGS_REG))]
9524   "TARGET_SSE_MATH
9525    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526   "#")
9528 (define_insn "*absnegsf2_i387"
9529   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9530         (match_operator:SF 3 "absneg_operator"
9531           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9532    (use (match_operand 2 "" ""))
9533    (clobber (reg:CC FLAGS_REG))]
9534   "TARGET_80387 && !TARGET_SSE_MATH
9535    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536   "#")
9538 (define_expand "copysignsf3"
9539   [(match_operand:SF 0 "register_operand" "")
9540    (match_operand:SF 1 "nonmemory_operand" "")
9541    (match_operand:SF 2 "register_operand" "")]
9542   "TARGET_SSE_MATH"
9544   ix86_expand_copysign (operands);
9545   DONE;
9548 (define_insn_and_split "copysignsf3_const"
9549   [(set (match_operand:SF 0 "register_operand"          "=x")
9550         (unspec:SF
9551           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9552            (match_operand:SF 2 "register_operand"       "0")
9553            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9554           UNSPEC_COPYSIGN))]
9555   "TARGET_SSE_MATH"
9556   "#"
9557   "&& reload_completed"
9558   [(const_int 0)]
9560   ix86_split_copysign_const (operands);
9561   DONE;
9564 (define_insn "copysignsf3_var"
9565   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9566         (unspec:SF
9567           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9568            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9569            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9570            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9571           UNSPEC_COPYSIGN))
9572    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9573   "TARGET_SSE_MATH"
9574   "#")
9576 (define_split
9577   [(set (match_operand:SF 0 "register_operand" "")
9578         (unspec:SF
9579           [(match_operand:SF 2 "register_operand" "")
9580            (match_operand:SF 3 "register_operand" "")
9581            (match_operand:V4SF 4 "" "")
9582            (match_operand:V4SF 5 "" "")]
9583           UNSPEC_COPYSIGN))
9584    (clobber (match_scratch:V4SF 1 ""))]
9585   "TARGET_SSE_MATH && reload_completed"
9586   [(const_int 0)]
9588   ix86_split_copysign_var (operands);
9589   DONE;
9592 (define_expand "negdf2"
9593   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9594         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9595   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9596   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9598 (define_expand "absdf2"
9599   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9600         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9601   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9602   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9604 (define_insn "*absnegdf2_mixed"
9605   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9606         (match_operator:DF 3 "absneg_operator"
9607           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9608    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9611    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9612   "#")
9614 (define_insn "*absnegdf2_sse"
9615   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9616         (match_operator:DF 3 "absneg_operator"
9617           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9618    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9619    (clobber (reg:CC FLAGS_REG))]
9620   "TARGET_SSE2 && TARGET_SSE_MATH
9621    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622   "#")
9624 (define_insn "*absnegdf2_i387"
9625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9626         (match_operator:DF 3 "absneg_operator"
9627           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9628    (use (match_operand 2 "" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9631    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632   "#")
9634 (define_expand "copysigndf3"
9635   [(match_operand:DF 0 "register_operand" "")
9636    (match_operand:DF 1 "nonmemory_operand" "")
9637    (match_operand:DF 2 "register_operand" "")]
9638   "TARGET_SSE2 && TARGET_SSE_MATH"
9640   ix86_expand_copysign (operands);
9641   DONE;
9644 (define_insn_and_split "copysigndf3_const"
9645   [(set (match_operand:DF 0 "register_operand"          "=x")
9646         (unspec:DF
9647           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9648            (match_operand:DF 2 "register_operand"       "0")
9649            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9650           UNSPEC_COPYSIGN))]
9651   "TARGET_SSE2 && TARGET_SSE_MATH"
9652   "#"
9653   "&& reload_completed"
9654   [(const_int 0)]
9656   ix86_split_copysign_const (operands);
9657   DONE;
9660 (define_insn "copysigndf3_var"
9661   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9662         (unspec:DF
9663           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9664            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9665            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9666            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9667           UNSPEC_COPYSIGN))
9668    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9669   "TARGET_SSE2 && TARGET_SSE_MATH"
9670   "#")
9672 (define_split
9673   [(set (match_operand:DF 0 "register_operand" "")
9674         (unspec:DF
9675           [(match_operand:DF 2 "register_operand" "")
9676            (match_operand:DF 3 "register_operand" "")
9677            (match_operand:V2DF 4 "" "")
9678            (match_operand:V2DF 5 "" "")]
9679           UNSPEC_COPYSIGN))
9680    (clobber (match_scratch:V2DF 1 ""))]
9681   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9682   [(const_int 0)]
9684   ix86_split_copysign_var (operands);
9685   DONE;
9688 (define_expand "negxf2"
9689   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9690         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9691   "TARGET_80387"
9692   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9694 (define_expand "absxf2"
9695   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9696         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9697   "TARGET_80387"
9698   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9700 (define_insn "*absnegxf2_i387"
9701   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9702         (match_operator:XF 3 "absneg_operator"
9703           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9704    (use (match_operand 2 "" ""))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_80387
9707    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9708   "#")
9710 ;; Splitters for fp abs and neg.
9712 (define_split
9713   [(set (match_operand 0 "fp_register_operand" "")
9714         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9715    (use (match_operand 2 "" ""))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "reload_completed"
9718   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9720 (define_split
9721   [(set (match_operand 0 "register_operand" "")
9722         (match_operator 3 "absneg_operator"
9723           [(match_operand 1 "register_operand" "")]))
9724    (use (match_operand 2 "nonimmediate_operand" ""))
9725    (clobber (reg:CC FLAGS_REG))]
9726   "reload_completed && SSE_REG_P (operands[0])"
9727   [(set (match_dup 0) (match_dup 3))]
9729   enum machine_mode mode = GET_MODE (operands[0]);
9730   enum machine_mode vmode = GET_MODE (operands[2]);
9731   rtx tmp;
9732   
9733   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9734   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9735   if (operands_match_p (operands[0], operands[2]))
9736     {
9737       tmp = operands[1];
9738       operands[1] = operands[2];
9739       operands[2] = tmp;
9740     }
9741   if (GET_CODE (operands[3]) == ABS)
9742     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9743   else
9744     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9745   operands[3] = tmp;
9748 (define_split
9749   [(set (match_operand:SF 0 "register_operand" "")
9750         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9751    (use (match_operand:V4SF 2 "" ""))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "reload_completed"
9754   [(parallel [(set (match_dup 0) (match_dup 1))
9755               (clobber (reg:CC FLAGS_REG))])]
9757   rtx tmp;
9758   operands[0] = gen_lowpart (SImode, operands[0]);
9759   if (GET_CODE (operands[1]) == ABS)
9760     {
9761       tmp = gen_int_mode (0x7fffffff, SImode);
9762       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9763     }
9764   else
9765     {
9766       tmp = gen_int_mode (0x80000000, SImode);
9767       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9768     }
9769   operands[1] = tmp;
9772 (define_split
9773   [(set (match_operand:DF 0 "register_operand" "")
9774         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9775    (use (match_operand 2 "" ""))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "reload_completed"
9778   [(parallel [(set (match_dup 0) (match_dup 1))
9779               (clobber (reg:CC FLAGS_REG))])]
9781   rtx tmp;
9782   if (TARGET_64BIT)
9783     {
9784       tmp = gen_lowpart (DImode, operands[0]);
9785       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9786       operands[0] = tmp;
9788       if (GET_CODE (operands[1]) == ABS)
9789         tmp = const0_rtx;
9790       else
9791         tmp = gen_rtx_NOT (DImode, tmp);
9792     }
9793   else
9794     {
9795       operands[0] = gen_highpart (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     }
9807   operands[1] = tmp;
9810 (define_split
9811   [(set (match_operand:XF 0 "register_operand" "")
9812         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9813    (use (match_operand 2 "" ""))
9814    (clobber (reg:CC FLAGS_REG))]
9815   "reload_completed"
9816   [(parallel [(set (match_dup 0) (match_dup 1))
9817               (clobber (reg:CC FLAGS_REG))])]
9819   rtx tmp;
9820   operands[0] = gen_rtx_REG (SImode,
9821                              true_regnum (operands[0])
9822                              + (TARGET_64BIT ? 1 : 2));
9823   if (GET_CODE (operands[1]) == ABS)
9824     {
9825       tmp = GEN_INT (0x7fff);
9826       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9827     }
9828   else
9829     {
9830       tmp = GEN_INT (0x8000);
9831       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9832     }
9833   operands[1] = tmp;
9836 (define_split
9837   [(set (match_operand 0 "memory_operand" "")
9838         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9839    (use (match_operand 2 "" ""))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "reload_completed"
9842   [(parallel [(set (match_dup 0) (match_dup 1))
9843               (clobber (reg:CC FLAGS_REG))])]
9845   enum machine_mode mode = GET_MODE (operands[0]);
9846   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9847   rtx tmp;
9849   operands[0] = adjust_address (operands[0], QImode, size - 1);
9850   if (GET_CODE (operands[1]) == ABS)
9851     {
9852       tmp = gen_int_mode (0x7f, QImode);
9853       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9854     }
9855   else
9856     {
9857       tmp = gen_int_mode (0x80, QImode);
9858       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9859     }
9860   operands[1] = tmp;
9863 ;; Conditionalize these after reload. If they match before reload, we 
9864 ;; lose the clobber and ability to use integer instructions.
9866 (define_insn "*negsf2_1"
9867   [(set (match_operand:SF 0 "register_operand" "=f")
9868         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9869   "TARGET_80387 && reload_completed"
9870   "fchs"
9871   [(set_attr "type" "fsgn")
9872    (set_attr "mode" "SF")])
9874 (define_insn "*negdf2_1"
9875   [(set (match_operand:DF 0 "register_operand" "=f")
9876         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9877   "TARGET_80387 && reload_completed"
9878   "fchs"
9879   [(set_attr "type" "fsgn")
9880    (set_attr "mode" "DF")])
9882 (define_insn "*negxf2_1"
9883   [(set (match_operand:XF 0 "register_operand" "=f")
9884         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9885   "TARGET_80387 && reload_completed"
9886   "fchs"
9887   [(set_attr "type" "fsgn")
9888    (set_attr "mode" "XF")])
9890 (define_insn "*abssf2_1"
9891   [(set (match_operand:SF 0 "register_operand" "=f")
9892         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9893   "TARGET_80387 && reload_completed"
9894   "fabs"
9895   [(set_attr "type" "fsgn")
9896    (set_attr "mode" "SF")])
9898 (define_insn "*absdf2_1"
9899   [(set (match_operand:DF 0 "register_operand" "=f")
9900         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9901   "TARGET_80387 && reload_completed"
9902   "fabs"
9903   [(set_attr "type" "fsgn")
9904    (set_attr "mode" "DF")])
9906 (define_insn "*absxf2_1"
9907   [(set (match_operand:XF 0 "register_operand" "=f")
9908         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9909   "TARGET_80387 && reload_completed"
9910   "fabs"
9911   [(set_attr "type" "fsgn")
9912    (set_attr "mode" "DF")])
9914 (define_insn "*negextendsfdf2"
9915   [(set (match_operand:DF 0 "register_operand" "=f")
9916         (neg:DF (float_extend:DF
9917                   (match_operand:SF 1 "register_operand" "0"))))]
9918   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9919   "fchs"
9920   [(set_attr "type" "fsgn")
9921    (set_attr "mode" "DF")])
9923 (define_insn "*negextenddfxf2"
9924   [(set (match_operand:XF 0 "register_operand" "=f")
9925         (neg:XF (float_extend:XF
9926                   (match_operand:DF 1 "register_operand" "0"))))]
9927   "TARGET_80387"
9928   "fchs"
9929   [(set_attr "type" "fsgn")
9930    (set_attr "mode" "XF")])
9932 (define_insn "*negextendsfxf2"
9933   [(set (match_operand:XF 0 "register_operand" "=f")
9934         (neg:XF (float_extend:XF
9935                   (match_operand:SF 1 "register_operand" "0"))))]
9936   "TARGET_80387"
9937   "fchs"
9938   [(set_attr "type" "fsgn")
9939    (set_attr "mode" "XF")])
9941 (define_insn "*absextendsfdf2"
9942   [(set (match_operand:DF 0 "register_operand" "=f")
9943         (abs:DF (float_extend:DF
9944                   (match_operand:SF 1 "register_operand" "0"))))]
9945   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9946   "fabs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "DF")])
9950 (define_insn "*absextenddfxf2"
9951   [(set (match_operand:XF 0 "register_operand" "=f")
9952         (abs:XF (float_extend:XF
9953           (match_operand:DF 1 "register_operand" "0"))))]
9954   "TARGET_80387"
9955   "fabs"
9956   [(set_attr "type" "fsgn")
9957    (set_attr "mode" "XF")])
9959 (define_insn "*absextendsfxf2"
9960   [(set (match_operand:XF 0 "register_operand" "=f")
9961         (abs:XF (float_extend:XF
9962           (match_operand:SF 1 "register_operand" "0"))))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "XF")])
9968 ;; One complement instructions
9970 (define_expand "one_cmpldi2"
9971   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9972         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9973   "TARGET_64BIT"
9974   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9976 (define_insn "*one_cmpldi2_1_rex64"
9977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9978         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9979   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9980   "not{q}\t%0"
9981   [(set_attr "type" "negnot")
9982    (set_attr "mode" "DI")])
9984 (define_insn "*one_cmpldi2_2_rex64"
9985   [(set (reg FLAGS_REG)
9986         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9987                  (const_int 0)))
9988    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9989         (not:DI (match_dup 1)))]
9990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9991    && ix86_unary_operator_ok (NOT, DImode, operands)"
9992   "#"
9993   [(set_attr "type" "alu1")
9994    (set_attr "mode" "DI")])
9996 (define_split
9997   [(set (match_operand 0 "flags_reg_operand" "")
9998         (match_operator 2 "compare_operator"
9999           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10000            (const_int 0)]))
10001    (set (match_operand:DI 1 "nonimmediate_operand" "")
10002         (not:DI (match_dup 3)))]
10003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10004   [(parallel [(set (match_dup 0)
10005                    (match_op_dup 2
10006                      [(xor:DI (match_dup 3) (const_int -1))
10007                       (const_int 0)]))
10008               (set (match_dup 1)
10009                    (xor:DI (match_dup 3) (const_int -1)))])]
10010   "")
10012 (define_expand "one_cmplsi2"
10013   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10014         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10015   ""
10016   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10018 (define_insn "*one_cmplsi2_1"
10019   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10020         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10021   "ix86_unary_operator_ok (NOT, SImode, operands)"
10022   "not{l}\t%0"
10023   [(set_attr "type" "negnot")
10024    (set_attr "mode" "SI")])
10026 ;; ??? Currently never generated - xor is used instead.
10027 (define_insn "*one_cmplsi2_1_zext"
10028   [(set (match_operand:DI 0 "register_operand" "=r")
10029         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10030   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10031   "not{l}\t%k0"
10032   [(set_attr "type" "negnot")
10033    (set_attr "mode" "SI")])
10035 (define_insn "*one_cmplsi2_2"
10036   [(set (reg FLAGS_REG)
10037         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10038                  (const_int 0)))
10039    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10040         (not:SI (match_dup 1)))]
10041   "ix86_match_ccmode (insn, CCNOmode)
10042    && ix86_unary_operator_ok (NOT, SImode, operands)"
10043   "#"
10044   [(set_attr "type" "alu1")
10045    (set_attr "mode" "SI")])
10047 (define_split
10048   [(set (match_operand 0 "flags_reg_operand" "")
10049         (match_operator 2 "compare_operator"
10050           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10051            (const_int 0)]))
10052    (set (match_operand:SI 1 "nonimmediate_operand" "")
10053         (not:SI (match_dup 3)))]
10054   "ix86_match_ccmode (insn, CCNOmode)"
10055   [(parallel [(set (match_dup 0)
10056                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057                                     (const_int 0)]))
10058               (set (match_dup 1)
10059                    (xor:SI (match_dup 3) (const_int -1)))])]
10060   "")
10062 ;; ??? Currently never generated - xor is used instead.
10063 (define_insn "*one_cmplsi2_2_zext"
10064   [(set (reg FLAGS_REG)
10065         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10066                  (const_int 0)))
10067    (set (match_operand:DI 0 "register_operand" "=r")
10068         (zero_extend:DI (not:SI (match_dup 1))))]
10069   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10070    && ix86_unary_operator_ok (NOT, SImode, operands)"
10071   "#"
10072   [(set_attr "type" "alu1")
10073    (set_attr "mode" "SI")])
10075 (define_split
10076   [(set (match_operand 0 "flags_reg_operand" "")
10077         (match_operator 2 "compare_operator"
10078           [(not:SI (match_operand:SI 3 "register_operand" ""))
10079            (const_int 0)]))
10080    (set (match_operand:DI 1 "register_operand" "")
10081         (zero_extend:DI (not:SI (match_dup 3))))]
10082   "ix86_match_ccmode (insn, CCNOmode)"
10083   [(parallel [(set (match_dup 0)
10084                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10085                                     (const_int 0)]))
10086               (set (match_dup 1)
10087                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10088   "")
10090 (define_expand "one_cmplhi2"
10091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10092         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10093   "TARGET_HIMODE_MATH"
10094   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10096 (define_insn "*one_cmplhi2_1"
10097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10098         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10099   "ix86_unary_operator_ok (NOT, HImode, operands)"
10100   "not{w}\t%0"
10101   [(set_attr "type" "negnot")
10102    (set_attr "mode" "HI")])
10104 (define_insn "*one_cmplhi2_2"
10105   [(set (reg FLAGS_REG)
10106         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10107                  (const_int 0)))
10108    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10109         (not:HI (match_dup 1)))]
10110   "ix86_match_ccmode (insn, CCNOmode)
10111    && ix86_unary_operator_ok (NEG, HImode, operands)"
10112   "#"
10113   [(set_attr "type" "alu1")
10114    (set_attr "mode" "HI")])
10116 (define_split
10117   [(set (match_operand 0 "flags_reg_operand" "")
10118         (match_operator 2 "compare_operator"
10119           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10120            (const_int 0)]))
10121    (set (match_operand:HI 1 "nonimmediate_operand" "")
10122         (not:HI (match_dup 3)))]
10123   "ix86_match_ccmode (insn, CCNOmode)"
10124   [(parallel [(set (match_dup 0)
10125                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10126                                     (const_int 0)]))
10127               (set (match_dup 1)
10128                    (xor:HI (match_dup 3) (const_int -1)))])]
10129   "")
10131 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10132 (define_expand "one_cmplqi2"
10133   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10134         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10135   "TARGET_QIMODE_MATH"
10136   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10138 (define_insn "*one_cmplqi2_1"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10141   "ix86_unary_operator_ok (NOT, QImode, operands)"
10142   "@
10143    not{b}\t%0
10144    not{l}\t%k0"
10145   [(set_attr "type" "negnot")
10146    (set_attr "mode" "QI,SI")])
10148 (define_insn "*one_cmplqi2_2"
10149   [(set (reg FLAGS_REG)
10150         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10151                  (const_int 0)))
10152    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10153         (not:QI (match_dup 1)))]
10154   "ix86_match_ccmode (insn, CCNOmode)
10155    && ix86_unary_operator_ok (NOT, QImode, operands)"
10156   "#"
10157   [(set_attr "type" "alu1")
10158    (set_attr "mode" "QI")])
10160 (define_split
10161   [(set (match_operand 0 "flags_reg_operand" "")
10162         (match_operator 2 "compare_operator"
10163           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10164            (const_int 0)]))
10165    (set (match_operand:QI 1 "nonimmediate_operand" "")
10166         (not:QI (match_dup 3)))]
10167   "ix86_match_ccmode (insn, CCNOmode)"
10168   [(parallel [(set (match_dup 0)
10169                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10170                                     (const_int 0)]))
10171               (set (match_dup 1)
10172                    (xor:QI (match_dup 3) (const_int -1)))])]
10173   "")
10175 ;; Arithmetic shift instructions
10177 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10178 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10179 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10180 ;; from the assembler input.
10182 ;; This instruction shifts the target reg/mem as usual, but instead of
10183 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10184 ;; is a left shift double, bits are taken from the high order bits of
10185 ;; reg, else if the insn is a shift right double, bits are taken from the
10186 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10187 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10189 ;; Since sh[lr]d does not change the `reg' operand, that is done
10190 ;; separately, making all shifts emit pairs of shift double and normal
10191 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10192 ;; support a 63 bit shift, each shift where the count is in a reg expands
10193 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10195 ;; If the shift count is a constant, we need never emit more than one
10196 ;; shift pair, instead using moves and sign extension for counts greater
10197 ;; than 31.
10199 (define_expand "ashlti3"
10200   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10201                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10202                               (match_operand:QI 2 "nonmemory_operand" "")))
10203               (clobber (reg:CC FLAGS_REG))])]
10204   "TARGET_64BIT"
10206   if (! immediate_operand (operands[2], QImode))
10207     {
10208       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10209       DONE;
10210     }
10211   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10212   DONE;
10215 (define_insn "ashlti3_1"
10216   [(set (match_operand:TI 0 "register_operand" "=r")
10217         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10218                    (match_operand:QI 2 "register_operand" "c")))
10219    (clobber (match_scratch:DI 3 "=&r"))
10220    (clobber (reg:CC FLAGS_REG))]
10221   "TARGET_64BIT"
10222   "#"
10223   [(set_attr "type" "multi")])
10225 (define_insn "*ashlti3_2"
10226   [(set (match_operand:TI 0 "register_operand" "=r")
10227         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228                    (match_operand:QI 2 "immediate_operand" "O")))
10229    (clobber (reg:CC FLAGS_REG))]
10230   "TARGET_64BIT"
10231   "#"
10232   [(set_attr "type" "multi")])
10234 (define_split
10235   [(set (match_operand:TI 0 "register_operand" "")
10236         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10237                    (match_operand:QI 2 "register_operand" "")))
10238    (clobber (match_scratch:DI 3 ""))
10239    (clobber (reg:CC FLAGS_REG))]
10240   "TARGET_64BIT && reload_completed"
10241   [(const_int 0)]
10242   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10244 (define_split
10245   [(set (match_operand:TI 0 "register_operand" "")
10246         (ashift:TI (match_operand:TI 1 "register_operand" "")
10247                    (match_operand:QI 2 "immediate_operand" "")))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && reload_completed"
10250   [(const_int 0)]
10251   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10253 (define_insn "x86_64_shld"
10254   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10255         (ior:DI (ashift:DI (match_dup 0)
10256                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10257                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10258                   (minus:QI (const_int 64) (match_dup 2)))))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_64BIT"
10261   "@
10262    shld{q}\t{%2, %1, %0|%0, %1, %2}
10263    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10264   [(set_attr "type" "ishift")
10265    (set_attr "prefix_0f" "1")
10266    (set_attr "mode" "DI")
10267    (set_attr "athlon_decode" "vector")])
10269 (define_expand "x86_64_shift_adj"
10270   [(set (reg:CCZ FLAGS_REG)
10271         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10272                              (const_int 64))
10273                      (const_int 0)))
10274    (set (match_operand:DI 0 "register_operand" "")
10275         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10276                          (match_operand:DI 1 "register_operand" "")
10277                          (match_dup 0)))
10278    (set (match_dup 1)
10279         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280                          (match_operand:DI 3 "register_operand" "r")
10281                          (match_dup 1)))]
10282   "TARGET_64BIT"
10283   "")
10285 (define_expand "ashldi3"
10286   [(set (match_operand:DI 0 "shiftdi_operand" "")
10287         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10288                    (match_operand:QI 2 "nonmemory_operand" "")))]
10289   ""
10290   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10292 (define_insn "*ashldi3_1_rex64"
10293   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10294         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10295                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10299   switch (get_attr_type (insn))
10300     {
10301     case TYPE_ALU:
10302       gcc_assert (operands[2] == const1_rtx);
10303       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10304       return "add{q}\t{%0, %0|%0, %0}";
10306     case TYPE_LEA:
10307       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10308       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10309       operands[1] = gen_rtx_MULT (DImode, operands[1],
10310                                   GEN_INT (1 << INTVAL (operands[2])));
10311       return "lea{q}\t{%a1, %0|%0, %a1}";
10313     default:
10314       if (REG_P (operands[2]))
10315         return "sal{q}\t{%b2, %0|%0, %b2}";
10316       else if (operands[2] == const1_rtx
10317                && (TARGET_SHIFT1 || optimize_size))
10318         return "sal{q}\t%0";
10319       else
10320         return "sal{q}\t{%2, %0|%0, %2}";
10321     }
10323   [(set (attr "type")
10324      (cond [(eq_attr "alternative" "1")
10325               (const_string "lea")
10326             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10327                           (const_int 0))
10328                       (match_operand 0 "register_operand" ""))
10329                  (match_operand 2 "const1_operand" ""))
10330               (const_string "alu")
10331            ]
10332            (const_string "ishift")))
10333    (set_attr "mode" "DI")])
10335 ;; Convert lea to the lea pattern to avoid flags dependency.
10336 (define_split
10337   [(set (match_operand:DI 0 "register_operand" "")
10338         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10339                    (match_operand:QI 2 "immediate_operand" "")))
10340    (clobber (reg:CC FLAGS_REG))]
10341   "TARGET_64BIT && reload_completed
10342    && true_regnum (operands[0]) != true_regnum (operands[1])"
10343   [(set (match_dup 0)
10344         (mult:DI (match_dup 1)
10345                  (match_dup 2)))]
10346   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10348 ;; This pattern can't accept a variable shift count, since shifts by
10349 ;; zero don't affect the flags.  We assume that shifts by constant
10350 ;; zero are optimized away.
10351 (define_insn "*ashldi3_cmp_rex64"
10352   [(set (reg FLAGS_REG)
10353         (compare
10354           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10355                      (match_operand:QI 2 "immediate_operand" "e"))
10356           (const_int 0)))
10357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10358         (ashift:DI (match_dup 1) (match_dup 2)))]
10359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10360    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10362   switch (get_attr_type (insn))
10363     {
10364     case TYPE_ALU:
10365       gcc_assert (operands[2] == const1_rtx);
10366       return "add{q}\t{%0, %0|%0, %0}";
10368     default:
10369       if (REG_P (operands[2]))
10370         return "sal{q}\t{%b2, %0|%0, %b2}";
10371       else if (operands[2] == const1_rtx
10372                && (TARGET_SHIFT1 || optimize_size))
10373         return "sal{q}\t%0";
10374       else
10375         return "sal{q}\t{%2, %0|%0, %2}";
10376     }
10378   [(set (attr "type")
10379      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10380                           (const_int 0))
10381                       (match_operand 0 "register_operand" ""))
10382                  (match_operand 2 "const1_operand" ""))
10383               (const_string "alu")
10384            ]
10385            (const_string "ishift")))
10386    (set_attr "mode" "DI")])
10388 (define_insn "*ashldi3_1"
10389   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10390         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10391                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "!TARGET_64BIT"
10394   "#"
10395   [(set_attr "type" "multi")])
10397 ;; By default we don't ask for a scratch register, because when DImode
10398 ;; values are manipulated, registers are already at a premium.  But if
10399 ;; we have one handy, we won't turn it away.
10400 (define_peephole2
10401   [(match_scratch:SI 3 "r")
10402    (parallel [(set (match_operand:DI 0 "register_operand" "")
10403                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10404                               (match_operand:QI 2 "nonmemory_operand" "")))
10405               (clobber (reg:CC FLAGS_REG))])
10406    (match_dup 3)]
10407   "!TARGET_64BIT && TARGET_CMOVE"
10408   [(const_int 0)]
10409   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10411 (define_split
10412   [(set (match_operand:DI 0 "register_operand" "")
10413         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414                    (match_operand:QI 2 "nonmemory_operand" "")))
10415    (clobber (reg:CC FLAGS_REG))]
10416   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10417   [(const_int 0)]
10418   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10420 (define_insn "x86_shld_1"
10421   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10422         (ior:SI (ashift:SI (match_dup 0)
10423                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10424                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10425                   (minus:QI (const_int 32) (match_dup 2)))))
10426    (clobber (reg:CC FLAGS_REG))]
10427   ""
10428   "@
10429    shld{l}\t{%2, %1, %0|%0, %1, %2}
10430    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10431   [(set_attr "type" "ishift")
10432    (set_attr "prefix_0f" "1")
10433    (set_attr "mode" "SI")
10434    (set_attr "pent_pair" "np")
10435    (set_attr "athlon_decode" "vector")])
10437 (define_expand "x86_shift_adj_1"
10438   [(set (reg:CCZ FLAGS_REG)
10439         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10440                              (const_int 32))
10441                      (const_int 0)))
10442    (set (match_operand:SI 0 "register_operand" "")
10443         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10444                          (match_operand:SI 1 "register_operand" "")
10445                          (match_dup 0)))
10446    (set (match_dup 1)
10447         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10448                          (match_operand:SI 3 "register_operand" "r")
10449                          (match_dup 1)))]
10450   "TARGET_CMOVE"
10451   "")
10453 (define_expand "x86_shift_adj_2"
10454   [(use (match_operand:SI 0 "register_operand" ""))
10455    (use (match_operand:SI 1 "register_operand" ""))
10456    (use (match_operand:QI 2 "register_operand" ""))]
10457   ""
10459   rtx label = gen_label_rtx ();
10460   rtx tmp;
10462   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10464   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10465   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10466   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10467                               gen_rtx_LABEL_REF (VOIDmode, label),
10468                               pc_rtx);
10469   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10470   JUMP_LABEL (tmp) = label;
10472   emit_move_insn (operands[0], operands[1]);
10473   ix86_expand_clear (operands[1]);
10475   emit_label (label);
10476   LABEL_NUSES (label) = 1;
10478   DONE;
10481 (define_expand "ashlsi3"
10482   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10483         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10484                    (match_operand:QI 2 "nonmemory_operand" "")))
10485    (clobber (reg:CC FLAGS_REG))]
10486   ""
10487   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10489 (define_insn "*ashlsi3_1"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10491         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10492                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10496   switch (get_attr_type (insn))
10497     {
10498     case TYPE_ALU:
10499       gcc_assert (operands[2] == const1_rtx);
10500       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10501       return "add{l}\t{%0, %0|%0, %0}";
10503     case TYPE_LEA:
10504       return "#";
10506     default:
10507       if (REG_P (operands[2]))
10508         return "sal{l}\t{%b2, %0|%0, %b2}";
10509       else if (operands[2] == const1_rtx
10510                && (TARGET_SHIFT1 || optimize_size))
10511         return "sal{l}\t%0";
10512       else
10513         return "sal{l}\t{%2, %0|%0, %2}";
10514     }
10516   [(set (attr "type")
10517      (cond [(eq_attr "alternative" "1")
10518               (const_string "lea")
10519             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "SI")])
10528 ;; Convert lea to the lea pattern to avoid flags dependency.
10529 (define_split
10530   [(set (match_operand 0 "register_operand" "")
10531         (ashift (match_operand 1 "index_register_operand" "")
10532                 (match_operand:QI 2 "const_int_operand" "")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "reload_completed
10535    && true_regnum (operands[0]) != true_regnum (operands[1])
10536    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10537   [(const_int 0)]
10539   rtx pat;
10540   enum machine_mode mode = GET_MODE (operands[0]);
10542   if (GET_MODE_SIZE (mode) < 4)
10543     operands[0] = gen_lowpart (SImode, operands[0]);
10544   if (mode != Pmode)
10545     operands[1] = gen_lowpart (Pmode, operands[1]);
10546   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10548   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10549   if (Pmode != SImode)
10550     pat = gen_rtx_SUBREG (SImode, pat, 0);
10551   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10552   DONE;
10555 ;; Rare case of shifting RSP is handled by generating move and shift
10556 (define_split
10557   [(set (match_operand 0 "register_operand" "")
10558         (ashift (match_operand 1 "register_operand" "")
10559                 (match_operand:QI 2 "const_int_operand" "")))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "reload_completed
10562    && true_regnum (operands[0]) != true_regnum (operands[1])"
10563   [(const_int 0)]
10565   rtx pat, clob;
10566   emit_move_insn (operands[1], operands[0]);
10567   pat = gen_rtx_SET (VOIDmode, operands[0],
10568                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10569                                      operands[0], operands[2]));
10570   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10571   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10572   DONE;
10575 (define_insn "*ashlsi3_1_zext"
10576   [(set (match_operand:DI 0 "register_operand" "=r,r")
10577         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10578                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       return "add{l}\t{%k0, %k0|%k0, %k0}";
10588     case TYPE_LEA:
10589       return "#";
10591     default:
10592       if (REG_P (operands[2]))
10593         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10594       else if (operands[2] == const1_rtx
10595                && (TARGET_SHIFT1 || optimize_size))
10596         return "sal{l}\t%k0";
10597       else
10598         return "sal{l}\t{%2, %k0|%k0, %2}";
10599     }
10601   [(set (attr "type")
10602      (cond [(eq_attr "alternative" "1")
10603               (const_string "lea")
10604             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10605                      (const_int 0))
10606                  (match_operand 2 "const1_operand" ""))
10607               (const_string "alu")
10608            ]
10609            (const_string "ishift")))
10610    (set_attr "mode" "SI")])
10612 ;; Convert lea to the lea pattern to avoid flags dependency.
10613 (define_split
10614   [(set (match_operand:DI 0 "register_operand" "")
10615         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10616                                 (match_operand:QI 2 "const_int_operand" ""))))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "TARGET_64BIT && reload_completed
10619    && true_regnum (operands[0]) != true_regnum (operands[1])"
10620   [(set (match_dup 0) (zero_extend:DI
10621                         (subreg:SI (mult:SI (match_dup 1)
10622                                             (match_dup 2)) 0)))]
10624   operands[1] = gen_lowpart (Pmode, operands[1]);
10625   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10628 ;; This pattern can't accept a variable shift count, since shifts by
10629 ;; zero don't affect the flags.  We assume that shifts by constant
10630 ;; zero are optimized away.
10631 (define_insn "*ashlsi3_cmp"
10632   [(set (reg FLAGS_REG)
10633         (compare
10634           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10635                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10636           (const_int 0)))
10637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10638         (ashift:SI (match_dup 1) (match_dup 2)))]
10639   "ix86_match_ccmode (insn, CCGOCmode)
10640    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10642   switch (get_attr_type (insn))
10643     {
10644     case TYPE_ALU:
10645       gcc_assert (operands[2] == const1_rtx);
10646       return "add{l}\t{%0, %0|%0, %0}";
10648     default:
10649       if (REG_P (operands[2]))
10650         return "sal{l}\t{%b2, %0|%0, %b2}";
10651       else if (operands[2] == const1_rtx
10652                && (TARGET_SHIFT1 || optimize_size))
10653         return "sal{l}\t%0";
10654       else
10655         return "sal{l}\t{%2, %0|%0, %2}";
10656     }
10658   [(set (attr "type")
10659      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660                           (const_int 0))
10661                       (match_operand 0 "register_operand" ""))
10662                  (match_operand 2 "const1_operand" ""))
10663               (const_string "alu")
10664            ]
10665            (const_string "ishift")))
10666    (set_attr "mode" "SI")])
10668 (define_insn "*ashlsi3_cmp_zext"
10669   [(set (reg FLAGS_REG)
10670         (compare
10671           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10672                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10673           (const_int 0)))
10674    (set (match_operand:DI 0 "register_operand" "=r")
10675         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10677    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10679   switch (get_attr_type (insn))
10680     {
10681     case TYPE_ALU:
10682       gcc_assert (operands[2] == const1_rtx);
10683       return "add{l}\t{%k0, %k0|%k0, %k0}";
10685     default:
10686       if (REG_P (operands[2]))
10687         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10688       else if (operands[2] == const1_rtx
10689                && (TARGET_SHIFT1 || optimize_size))
10690         return "sal{l}\t%k0";
10691       else
10692         return "sal{l}\t{%2, %k0|%k0, %2}";
10693     }
10695   [(set (attr "type")
10696      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697                      (const_int 0))
10698                  (match_operand 2 "const1_operand" ""))
10699               (const_string "alu")
10700            ]
10701            (const_string "ishift")))
10702    (set_attr "mode" "SI")])
10704 (define_expand "ashlhi3"
10705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10706         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10707                    (match_operand:QI 2 "nonmemory_operand" "")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_HIMODE_MATH"
10710   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10712 (define_insn "*ashlhi3_1_lea"
10713   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10714         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10715                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10716    (clobber (reg:CC FLAGS_REG))]
10717   "!TARGET_PARTIAL_REG_STALL
10718    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10720   switch (get_attr_type (insn))
10721     {
10722     case TYPE_LEA:
10723       return "#";
10724     case TYPE_ALU:
10725       gcc_assert (operands[2] == const1_rtx);
10726       return "add{w}\t{%0, %0|%0, %0}";
10728     default:
10729       if (REG_P (operands[2]))
10730         return "sal{w}\t{%b2, %0|%0, %b2}";
10731       else if (operands[2] == const1_rtx
10732                && (TARGET_SHIFT1 || optimize_size))
10733         return "sal{w}\t%0";
10734       else
10735         return "sal{w}\t{%2, %0|%0, %2}";
10736     }
10738   [(set (attr "type")
10739      (cond [(eq_attr "alternative" "1")
10740               (const_string "lea")
10741             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742                           (const_int 0))
10743                       (match_operand 0 "register_operand" ""))
10744                  (match_operand 2 "const1_operand" ""))
10745               (const_string "alu")
10746            ]
10747            (const_string "ishift")))
10748    (set_attr "mode" "HI,SI")])
10750 (define_insn "*ashlhi3_1"
10751   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10752         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10753                    (match_operand:QI 2 "nonmemory_operand" "cI")))
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_ALU:
10761       gcc_assert (operands[2] == const1_rtx);
10762       return "add{w}\t{%0, %0|%0, %0}";
10764     default:
10765       if (REG_P (operands[2]))
10766         return "sal{w}\t{%b2, %0|%0, %b2}";
10767       else if (operands[2] == const1_rtx
10768                && (TARGET_SHIFT1 || optimize_size))
10769         return "sal{w}\t%0";
10770       else
10771         return "sal{w}\t{%2, %0|%0, %2}";
10772     }
10774   [(set (attr "type")
10775      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776                           (const_int 0))
10777                       (match_operand 0 "register_operand" ""))
10778                  (match_operand 2 "const1_operand" ""))
10779               (const_string "alu")
10780            ]
10781            (const_string "ishift")))
10782    (set_attr "mode" "HI")])
10784 ;; This pattern can't accept a variable shift count, since shifts by
10785 ;; zero don't affect the flags.  We assume that shifts by constant
10786 ;; zero are optimized away.
10787 (define_insn "*ashlhi3_cmp"
10788   [(set (reg FLAGS_REG)
10789         (compare
10790           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10791                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10792           (const_int 0)))
10793    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10794         (ashift:HI (match_dup 1) (match_dup 2)))]
10795   "ix86_match_ccmode (insn, CCGOCmode)
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10824 (define_expand "ashlqi3"
10825   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10826         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10827                    (match_operand:QI 2 "nonmemory_operand" "")))
10828    (clobber (reg:CC FLAGS_REG))]
10829   "TARGET_QIMODE_MATH"
10830   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10832 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10834 (define_insn "*ashlqi3_1_lea"
10835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10836         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10837                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "!TARGET_PARTIAL_REG_STALL
10840    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10842   switch (get_attr_type (insn))
10843     {
10844     case TYPE_LEA:
10845       return "#";
10846     case TYPE_ALU:
10847       gcc_assert (operands[2] == const1_rtx);
10848       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10849         return "add{l}\t{%k0, %k0|%k0, %k0}";
10850       else
10851         return "add{b}\t{%0, %0|%0, %0}";
10853     default:
10854       if (REG_P (operands[2]))
10855         {
10856           if (get_attr_mode (insn) == MODE_SI)
10857             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10858           else
10859             return "sal{b}\t{%b2, %0|%0, %b2}";
10860         }
10861       else if (operands[2] == const1_rtx
10862                && (TARGET_SHIFT1 || optimize_size))
10863         {
10864           if (get_attr_mode (insn) == MODE_SI)
10865             return "sal{l}\t%0";
10866           else
10867             return "sal{b}\t%0";
10868         }
10869       else
10870         {
10871           if (get_attr_mode (insn) == MODE_SI)
10872             return "sal{l}\t{%2, %k0|%k0, %2}";
10873           else
10874             return "sal{b}\t{%2, %0|%0, %2}";
10875         }
10876     }
10878   [(set (attr "type")
10879      (cond [(eq_attr "alternative" "2")
10880               (const_string "lea")
10881             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10882                           (const_int 0))
10883                       (match_operand 0 "register_operand" ""))
10884                  (match_operand 2 "const1_operand" ""))
10885               (const_string "alu")
10886            ]
10887            (const_string "ishift")))
10888    (set_attr "mode" "QI,SI,SI")])
10890 (define_insn "*ashlqi3_1"
10891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10892         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10893                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_PARTIAL_REG_STALL
10896    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10898   switch (get_attr_type (insn))
10899     {
10900     case TYPE_ALU:
10901       gcc_assert (operands[2] == const1_rtx);
10902       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10903         return "add{l}\t{%k0, %k0|%k0, %k0}";
10904       else
10905         return "add{b}\t{%0, %0|%0, %0}";
10907     default:
10908       if (REG_P (operands[2]))
10909         {
10910           if (get_attr_mode (insn) == MODE_SI)
10911             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10912           else
10913             return "sal{b}\t{%b2, %0|%0, %b2}";
10914         }
10915       else if (operands[2] == const1_rtx
10916                && (TARGET_SHIFT1 || optimize_size))
10917         {
10918           if (get_attr_mode (insn) == MODE_SI)
10919             return "sal{l}\t%0";
10920           else
10921             return "sal{b}\t%0";
10922         }
10923       else
10924         {
10925           if (get_attr_mode (insn) == MODE_SI)
10926             return "sal{l}\t{%2, %k0|%k0, %2}";
10927           else
10928             return "sal{b}\t{%2, %0|%0, %2}";
10929         }
10930     }
10932   [(set (attr "type")
10933      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "QI,SI")])
10942 ;; This pattern can't accept a variable shift count, since shifts by
10943 ;; zero don't affect the flags.  We assume that shifts by constant
10944 ;; zero are optimized away.
10945 (define_insn "*ashlqi3_cmp"
10946   [(set (reg FLAGS_REG)
10947         (compare
10948           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10949                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10950           (const_int 0)))
10951    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10952         (ashift:QI (match_dup 1) (match_dup 2)))]
10953   "ix86_match_ccmode (insn, CCGOCmode)
10954    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       return "add{b}\t{%0, %0|%0, %0}";
10962     default:
10963       if (REG_P (operands[2]))
10964         return "sal{b}\t{%b2, %0|%0, %b2}";
10965       else if (operands[2] == const1_rtx
10966                && (TARGET_SHIFT1 || optimize_size))
10967         return "sal{b}\t%0";
10968       else
10969         return "sal{b}\t{%2, %0|%0, %2}";
10970     }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI")])
10982 ;; See comment above `ashldi3' about how this works.
10984 (define_expand "ashrti3"
10985   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10986                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10987                                 (match_operand:QI 2 "nonmemory_operand" "")))
10988               (clobber (reg:CC FLAGS_REG))])]
10989   "TARGET_64BIT"
10991   if (! immediate_operand (operands[2], QImode))
10992     {
10993       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10994       DONE;
10995     }
10996   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
10997   DONE;
11000 (define_insn "ashrti3_1"
11001   [(set (match_operand:TI 0 "register_operand" "=r")
11002         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11003                      (match_operand:QI 2 "register_operand" "c")))
11004    (clobber (match_scratch:DI 3 "=&r"))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "TARGET_64BIT"
11007   "#"
11008   [(set_attr "type" "multi")])
11010 (define_insn "*ashrti3_2"
11011   [(set (match_operand:TI 0 "register_operand" "=r")
11012         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11013                      (match_operand:QI 2 "immediate_operand" "O")))
11014    (clobber (reg:CC FLAGS_REG))]
11015   "TARGET_64BIT"
11016   "#"
11017   [(set_attr "type" "multi")])
11019 (define_split
11020   [(set (match_operand:TI 0 "register_operand" "")
11021         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11022                      (match_operand:QI 2 "register_operand" "")))
11023    (clobber (match_scratch:DI 3 ""))
11024    (clobber (reg:CC FLAGS_REG))]
11025   "TARGET_64BIT && reload_completed"
11026   [(const_int 0)]
11027   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11029 (define_split
11030   [(set (match_operand:TI 0 "register_operand" "")
11031         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11032                      (match_operand:QI 2 "immediate_operand" "")))
11033    (clobber (reg:CC FLAGS_REG))]
11034   "TARGET_64BIT && reload_completed"
11035   [(const_int 0)]
11036   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11038 (define_insn "x86_64_shrd"
11039   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11040         (ior:DI (ashiftrt:DI (match_dup 0)
11041                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11042                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11043                   (minus:QI (const_int 64) (match_dup 2)))))
11044    (clobber (reg:CC FLAGS_REG))]
11045   "TARGET_64BIT"
11046   "@
11047    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11048    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11049   [(set_attr "type" "ishift")
11050    (set_attr "prefix_0f" "1")
11051    (set_attr "mode" "DI")
11052    (set_attr "athlon_decode" "vector")])
11054 (define_expand "ashrdi3"
11055   [(set (match_operand:DI 0 "shiftdi_operand" "")
11056         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11057                      (match_operand:QI 2 "nonmemory_operand" "")))]
11058   ""
11059   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11061 (define_insn "*ashrdi3_63_rex64"
11062   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11063         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11064                      (match_operand:DI 2 "const_int_operand" "i,i")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "TARGET_64BIT && INTVAL (operands[2]) == 63
11067    && (TARGET_USE_CLTD || optimize_size)
11068    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11069   "@
11070    {cqto|cqo}
11071    sar{q}\t{%2, %0|%0, %2}"
11072   [(set_attr "type" "imovx,ishift")
11073    (set_attr "prefix_0f" "0,*")
11074    (set_attr "length_immediate" "0,*")
11075    (set_attr "modrm" "0,1")
11076    (set_attr "mode" "DI")])
11078 (define_insn "*ashrdi3_1_one_bit_rex64"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11080         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11081                      (match_operand:QI 2 "const1_operand" "")))
11082    (clobber (reg:CC FLAGS_REG))]
11083   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11084    && (TARGET_SHIFT1 || optimize_size)"
11085   "sar{q}\t%0"
11086   [(set_attr "type" "ishift")
11087    (set (attr "length") 
11088      (if_then_else (match_operand:DI 0 "register_operand" "") 
11089         (const_string "2")
11090         (const_string "*")))])
11092 (define_insn "*ashrdi3_1_rex64"
11093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11094         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11095                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11098   "@
11099    sar{q}\t{%2, %0|%0, %2}
11100    sar{q}\t{%b2, %0|%0, %b2}"
11101   [(set_attr "type" "ishift")
11102    (set_attr "mode" "DI")])
11104 ;; This pattern can't accept a variable shift count, since shifts by
11105 ;; zero don't affect the flags.  We assume that shifts by constant
11106 ;; zero are optimized away.
11107 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11108   [(set (reg FLAGS_REG)
11109         (compare
11110           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11111                        (match_operand:QI 2 "const1_operand" ""))
11112           (const_int 0)))
11113    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11114         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11115   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11116    && (TARGET_SHIFT1 || optimize_size)
11117    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11118   "sar{q}\t%0"
11119   [(set_attr "type" "ishift")
11120    (set (attr "length") 
11121      (if_then_else (match_operand:DI 0 "register_operand" "") 
11122         (const_string "2")
11123         (const_string "*")))])
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags.  We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashrdi3_cmp_rex64"
11129   [(set (reg FLAGS_REG)
11130         (compare
11131           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11132                        (match_operand:QI 2 "const_int_operand" "n"))
11133           (const_int 0)))
11134    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11135         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11136   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11137    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "sar{q}\t{%2, %0|%0, %2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "mode" "DI")])
11142 (define_insn "*ashrdi3_1"
11143   [(set (match_operand:DI 0 "register_operand" "=r")
11144         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11145                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11146    (clobber (reg:CC FLAGS_REG))]
11147   "!TARGET_64BIT"
11148   "#"
11149   [(set_attr "type" "multi")])
11151 ;; By default we don't ask for a scratch register, because when DImode
11152 ;; values are manipulated, registers are already at a premium.  But if
11153 ;; we have one handy, we won't turn it away.
11154 (define_peephole2
11155   [(match_scratch:SI 3 "r")
11156    (parallel [(set (match_operand:DI 0 "register_operand" "")
11157                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11158                                 (match_operand:QI 2 "nonmemory_operand" "")))
11159               (clobber (reg:CC FLAGS_REG))])
11160    (match_dup 3)]
11161   "!TARGET_64BIT && TARGET_CMOVE"
11162   [(const_int 0)]
11163   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11165 (define_split
11166   [(set (match_operand:DI 0 "register_operand" "")
11167         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11168                      (match_operand:QI 2 "nonmemory_operand" "")))
11169    (clobber (reg:CC FLAGS_REG))]
11170   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11171   [(const_int 0)]
11172   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11174 (define_insn "x86_shrd_1"
11175   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176         (ior:SI (ashiftrt:SI (match_dup 0)
11177                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11179                   (minus:QI (const_int 32) (match_dup 2)))))
11180    (clobber (reg:CC FLAGS_REG))]
11181   ""
11182   "@
11183    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11184    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11185   [(set_attr "type" "ishift")
11186    (set_attr "prefix_0f" "1")
11187    (set_attr "pent_pair" "np")
11188    (set_attr "mode" "SI")])
11190 (define_expand "x86_shift_adj_3"
11191   [(use (match_operand:SI 0 "register_operand" ""))
11192    (use (match_operand:SI 1 "register_operand" ""))
11193    (use (match_operand:QI 2 "register_operand" ""))]
11194   ""
11196   rtx label = gen_label_rtx ();
11197   rtx tmp;
11199   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11201   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11202   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11203   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11204                               gen_rtx_LABEL_REF (VOIDmode, label),
11205                               pc_rtx);
11206   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11207   JUMP_LABEL (tmp) = label;
11209   emit_move_insn (operands[0], operands[1]);
11210   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11212   emit_label (label);
11213   LABEL_NUSES (label) = 1;
11215   DONE;
11218 (define_insn "ashrsi3_31"
11219   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11220         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11221                      (match_operand:SI 2 "const_int_operand" "i,i")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11224    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11225   "@
11226    {cltd|cdq}
11227    sar{l}\t{%2, %0|%0, %2}"
11228   [(set_attr "type" "imovx,ishift")
11229    (set_attr "prefix_0f" "0,*")
11230    (set_attr "length_immediate" "0,*")
11231    (set_attr "modrm" "0,1")
11232    (set_attr "mode" "SI")])
11234 (define_insn "*ashrsi3_31_zext"
11235   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11236         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11237                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11240    && INTVAL (operands[2]) == 31
11241    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11242   "@
11243    {cltd|cdq}
11244    sar{l}\t{%2, %k0|%k0, %2}"
11245   [(set_attr "type" "imovx,ishift")
11246    (set_attr "prefix_0f" "0,*")
11247    (set_attr "length_immediate" "0,*")
11248    (set_attr "modrm" "0,1")
11249    (set_attr "mode" "SI")])
11251 (define_expand "ashrsi3"
11252   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11253         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11254                      (match_operand:QI 2 "nonmemory_operand" "")))
11255    (clobber (reg:CC FLAGS_REG))]
11256   ""
11257   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11259 (define_insn "*ashrsi3_1_one_bit"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11262                      (match_operand:QI 2 "const1_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11265    && (TARGET_SHIFT1 || optimize_size)"
11266   "sar{l}\t%0"
11267   [(set_attr "type" "ishift")
11268    (set (attr "length") 
11269      (if_then_else (match_operand:SI 0 "register_operand" "") 
11270         (const_string "2")
11271         (const_string "*")))])
11273 (define_insn "*ashrsi3_1_one_bit_zext"
11274   [(set (match_operand:DI 0 "register_operand" "=r")
11275         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11276                                      (match_operand:QI 2 "const1_operand" ""))))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11279    && (TARGET_SHIFT1 || optimize_size)"
11280   "sar{l}\t%k0"
11281   [(set_attr "type" "ishift")
11282    (set_attr "length" "2")])
11284 (define_insn "*ashrsi3_1"
11285   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11286         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11287                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11290   "@
11291    sar{l}\t{%2, %0|%0, %2}
11292    sar{l}\t{%b2, %0|%0, %b2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "mode" "SI")])
11296 (define_insn "*ashrsi3_1_zext"
11297   [(set (match_operand:DI 0 "register_operand" "=r,r")
11298         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11299                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11302   "@
11303    sar{l}\t{%2, %k0|%k0, %2}
11304    sar{l}\t{%b2, %k0|%k0, %b2}"
11305   [(set_attr "type" "ishift")
11306    (set_attr "mode" "SI")])
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags.  We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*ashrsi3_one_bit_cmp"
11312   [(set (reg FLAGS_REG)
11313         (compare
11314           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11315                        (match_operand:QI 2 "const1_operand" ""))
11316           (const_int 0)))
11317    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11318         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11319   "ix86_match_ccmode (insn, CCGOCmode)
11320    && (TARGET_SHIFT1 || optimize_size)
11321    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11322   "sar{l}\t%0"
11323   [(set_attr "type" "ishift")
11324    (set (attr "length") 
11325      (if_then_else (match_operand:SI 0 "register_operand" "") 
11326         (const_string "2")
11327         (const_string "*")))])
11329 (define_insn "*ashrsi3_one_bit_cmp_zext"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11333                        (match_operand:QI 2 "const1_operand" ""))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "register_operand" "=r")
11336         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11338    && (TARGET_SHIFT1 || optimize_size)
11339    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11340   "sar{l}\t%k0"
11341   [(set_attr "type" "ishift")
11342    (set_attr "length" "2")])
11344 ;; This pattern can't accept a variable shift count, since shifts by
11345 ;; zero don't affect the flags.  We assume that shifts by constant
11346 ;; zero are optimized away.
11347 (define_insn "*ashrsi3_cmp"
11348   [(set (reg FLAGS_REG)
11349         (compare
11350           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11351                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11352           (const_int 0)))
11353    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11354         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11355   "ix86_match_ccmode (insn, CCGOCmode)
11356    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357   "sar{l}\t{%2, %0|%0, %2}"
11358   [(set_attr "type" "ishift")
11359    (set_attr "mode" "SI")])
11361 (define_insn "*ashrsi3_cmp_zext"
11362   [(set (reg FLAGS_REG)
11363         (compare
11364           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11365                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11366           (const_int 0)))
11367    (set (match_operand:DI 0 "register_operand" "=r")
11368         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11369   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11370    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371   "sar{l}\t{%2, %k0|%k0, %2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "SI")])
11375 (define_expand "ashrhi3"
11376   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11377         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_HIMODE_MATH"
11381   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11383 (define_insn "*ashrhi3_1_one_bit"
11384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "sar{w}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11397 (define_insn "*ashrhi3_1"
11398   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11399         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11400                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11403   "@
11404    sar{w}\t{%2, %0|%0, %2}
11405    sar{w}\t{%b2, %0|%0, %b2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "HI")])
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags.  We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrhi3_one_bit_cmp"
11413   [(set (reg FLAGS_REG)
11414         (compare
11415           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11416                        (match_operand:QI 2 "const1_operand" ""))
11417           (const_int 0)))
11418    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11419         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11420   "ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11423   "sar{w}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set (attr "length") 
11426      (if_then_else (match_operand 0 "register_operand" "") 
11427         (const_string "2")
11428         (const_string "*")))])
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags.  We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrhi3_cmp"
11434   [(set (reg FLAGS_REG)
11435         (compare
11436           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11437                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11438           (const_int 0)))
11439    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11440         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11441   "ix86_match_ccmode (insn, CCGOCmode)
11442    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443   "sar{w}\t{%2, %0|%0, %2}"
11444   [(set_attr "type" "ishift")
11445    (set_attr "mode" "HI")])
11447 (define_expand "ashrqi3"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11449         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11450                      (match_operand:QI 2 "nonmemory_operand" "")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_QIMODE_MATH"
11453   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11455 (define_insn "*ashrqi3_1_one_bit"
11456   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11457         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11458                      (match_operand:QI 2 "const1_operand" "")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11461    && (TARGET_SHIFT1 || optimize_size)"
11462   "sar{b}\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 (define_insn "*ashrqi3_1_one_bit_slp"
11470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11471         (ashiftrt:QI (match_dup 0)
11472                      (match_operand:QI 1 "const1_operand" "")))
11473    (clobber (reg:CC FLAGS_REG))]
11474   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11475    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11476    && (TARGET_SHIFT1 || optimize_size)"
11477   "sar{b}\t%0"
11478   [(set_attr "type" "ishift1")
11479    (set (attr "length") 
11480      (if_then_else (match_operand 0 "register_operand" "") 
11481         (const_string "2")
11482         (const_string "*")))])
11484 (define_insn "*ashrqi3_1"
11485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11486         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11487                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11490   "@
11491    sar{b}\t{%2, %0|%0, %2}
11492    sar{b}\t{%b2, %0|%0, %b2}"
11493   [(set_attr "type" "ishift")
11494    (set_attr "mode" "QI")])
11496 (define_insn "*ashrqi3_1_slp"
11497   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11498         (ashiftrt:QI (match_dup 0)
11499                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11502    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11503   "@
11504    sar{b}\t{%1, %0|%0, %1}
11505    sar{b}\t{%b1, %0|%0, %b1}"
11506   [(set_attr "type" "ishift1")
11507    (set_attr "mode" "QI")])
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags.  We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*ashrqi3_one_bit_cmp"
11513   [(set (reg FLAGS_REG)
11514         (compare
11515           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11516                        (match_operand:QI 2 "const1_operand" "I"))
11517           (const_int 0)))
11518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11519         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11520   "ix86_match_ccmode (insn, CCGOCmode)
11521    && (TARGET_SHIFT1 || optimize_size)
11522    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11523   "sar{b}\t%0"
11524   [(set_attr "type" "ishift")
11525    (set (attr "length") 
11526      (if_then_else (match_operand 0 "register_operand" "") 
11527         (const_string "2")
11528         (const_string "*")))])
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags.  We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*ashrqi3_cmp"
11534   [(set (reg FLAGS_REG)
11535         (compare
11536           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11537                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11538           (const_int 0)))
11539    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11540         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11541   "ix86_match_ccmode (insn, CCGOCmode)
11542    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11543   "sar{b}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "ishift")
11545    (set_attr "mode" "QI")])
11547 ;; Logical shift instructions
11549 ;; See comment above `ashldi3' about how this works.
11551 (define_expand "lshrti3"
11552   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11553                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11554                                 (match_operand:QI 2 "nonmemory_operand" "")))
11555               (clobber (reg:CC FLAGS_REG))])]
11556   "TARGET_64BIT"
11558   if (! immediate_operand (operands[2], QImode))
11559     {
11560       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11561       DONE;
11562     }
11563   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11564   DONE;
11567 (define_insn "lshrti3_1"
11568   [(set (match_operand:TI 0 "register_operand" "=r")
11569         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11570                      (match_operand:QI 2 "register_operand" "c")))
11571    (clobber (match_scratch:DI 3 "=&r"))
11572    (clobber (reg:CC FLAGS_REG))]
11573   "TARGET_64BIT"
11574   "#"
11575   [(set_attr "type" "multi")])
11577 (define_insn "*lshrti3_2"
11578   [(set (match_operand:TI 0 "register_operand" "=r")
11579         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580                      (match_operand:QI 2 "immediate_operand" "O")))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11586 (define_split 
11587   [(set (match_operand:TI 0 "register_operand" "")
11588         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11589                      (match_operand:QI 2 "register_operand" "")))
11590    (clobber (match_scratch:DI 3 ""))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && reload_completed"
11593   [(const_int 0)]
11594   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11596 (define_split 
11597   [(set (match_operand:TI 0 "register_operand" "")
11598         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599                      (match_operand:QI 2 "immediate_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11605 (define_expand "lshrdi3"
11606   [(set (match_operand:DI 0 "shiftdi_operand" "")
11607         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11608                      (match_operand:QI 2 "nonmemory_operand" "")))]
11609   ""
11610   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11612 (define_insn "*lshrdi3_1_one_bit_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11614         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11615                      (match_operand:QI 2 "const1_operand" "")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11618    && (TARGET_SHIFT1 || optimize_size)"
11619   "shr{q}\t%0"
11620   [(set_attr "type" "ishift")
11621    (set (attr "length") 
11622      (if_then_else (match_operand:DI 0 "register_operand" "") 
11623         (const_string "2")
11624         (const_string "*")))])
11626 (define_insn "*lshrdi3_1_rex64"
11627   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11628         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11629                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11632   "@
11633    shr{q}\t{%2, %0|%0, %2}
11634    shr{q}\t{%b2, %0|%0, %b2}"
11635   [(set_attr "type" "ishift")
11636    (set_attr "mode" "DI")])
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags.  We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11648         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11652   "shr{q}\t%0"
11653   [(set_attr "type" "ishift")
11654    (set (attr "length") 
11655      (if_then_else (match_operand:DI 0 "register_operand" "") 
11656         (const_string "2")
11657         (const_string "*")))])
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*lshrdi3_cmp_rex64"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_operand" "e"))
11667           (const_int 0)))
11668    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672   "shr{q}\t{%2, %0|%0, %2}"
11673   [(set_attr "type" "ishift")
11674    (set_attr "mode" "DI")])
11676 (define_insn "*lshrdi3_1"
11677   [(set (match_operand:DI 0 "register_operand" "=r")
11678         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11679                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11680    (clobber (reg:CC FLAGS_REG))]
11681   "!TARGET_64BIT"
11682   "#"
11683   [(set_attr "type" "multi")])
11685 ;; By default we don't ask for a scratch register, because when DImode
11686 ;; values are manipulated, registers are already at a premium.  But if
11687 ;; we have one handy, we won't turn it away.
11688 (define_peephole2
11689   [(match_scratch:SI 3 "r")
11690    (parallel [(set (match_operand:DI 0 "register_operand" "")
11691                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11692                                 (match_operand:QI 2 "nonmemory_operand" "")))
11693               (clobber (reg:CC FLAGS_REG))])
11694    (match_dup 3)]
11695   "!TARGET_64BIT && TARGET_CMOVE"
11696   [(const_int 0)]
11697   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11699 (define_split 
11700   [(set (match_operand:DI 0 "register_operand" "")
11701         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702                      (match_operand:QI 2 "nonmemory_operand" "")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11705   [(const_int 0)]
11706   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11708 (define_expand "lshrsi3"
11709   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11710         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11711                      (match_operand:QI 2 "nonmemory_operand" "")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   ""
11714   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11716 (define_insn "*lshrsi3_1_one_bit"
11717   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11718         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11719                      (match_operand:QI 2 "const1_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11722    && (TARGET_SHIFT1 || optimize_size)"
11723   "shr{l}\t%0"
11724   [(set_attr "type" "ishift")
11725    (set (attr "length") 
11726      (if_then_else (match_operand:SI 0 "register_operand" "") 
11727         (const_string "2")
11728         (const_string "*")))])
11730 (define_insn "*lshrsi3_1_one_bit_zext"
11731   [(set (match_operand:DI 0 "register_operand" "=r")
11732         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11733                      (match_operand:QI 2 "const1_operand" "")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "shr{l}\t%k0"
11738   [(set_attr "type" "ishift")
11739    (set_attr "length" "2")])
11741 (define_insn "*lshrsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11747   "@
11748    shr{l}\t{%2, %0|%0, %2}
11749    shr{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "ishift")
11751    (set_attr "mode" "SI")])
11753 (define_insn "*lshrsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11760   "@
11761    shr{l}\t{%2, %k0|%k0, %2}
11762    shr{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "ishift")
11764    (set_attr "mode" "SI")])
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags.  We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*lshrsi3_one_bit_cmp"
11770   [(set (reg FLAGS_REG)
11771         (compare
11772           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11773                        (match_operand:QI 2 "const1_operand" ""))
11774           (const_int 0)))
11775    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11776         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11777   "ix86_match_ccmode (insn, CCGOCmode)
11778    && (TARGET_SHIFT1 || optimize_size)
11779    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11780   "shr{l}\t%0"
11781   [(set_attr "type" "ishift")
11782    (set (attr "length") 
11783      (if_then_else (match_operand:SI 0 "register_operand" "") 
11784         (const_string "2")
11785         (const_string "*")))])
11787 (define_insn "*lshrsi3_cmp_one_bit_zext"
11788   [(set (reg FLAGS_REG)
11789         (compare
11790           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11791                        (match_operand:QI 2 "const1_operand" ""))
11792           (const_int 0)))
11793    (set (match_operand:DI 0 "register_operand" "=r")
11794         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11795   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11796    && (TARGET_SHIFT1 || optimize_size)
11797    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11798   "shr{l}\t%k0"
11799   [(set_attr "type" "ishift")
11800    (set_attr "length" "2")])
11802 ;; This pattern can't accept a variable shift count, since shifts by
11803 ;; zero don't affect the flags.  We assume that shifts by constant
11804 ;; zero are optimized away.
11805 (define_insn "*lshrsi3_cmp"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810           (const_int 0)))
11811    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11812         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11813   "ix86_match_ccmode (insn, CCGOCmode)
11814    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11815   "shr{l}\t{%2, %0|%0, %2}"
11816   [(set_attr "type" "ishift")
11817    (set_attr "mode" "SI")])
11819 (define_insn "*lshrsi3_cmp_zext"
11820   [(set (reg FLAGS_REG)
11821         (compare
11822           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11823                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11824           (const_int 0)))
11825    (set (match_operand:DI 0 "register_operand" "=r")
11826         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11827   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11828    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11829   "shr{l}\t{%2, %k0|%k0, %2}"
11830   [(set_attr "type" "ishift")
11831    (set_attr "mode" "SI")])
11833 (define_expand "lshrhi3"
11834   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11835         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11836                      (match_operand:QI 2 "nonmemory_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "TARGET_HIMODE_MATH"
11839   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11841 (define_insn "*lshrhi3_1_one_bit"
11842   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11843         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11844                      (match_operand:QI 2 "const1_operand" "")))
11845    (clobber (reg:CC FLAGS_REG))]
11846   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11847    && (TARGET_SHIFT1 || optimize_size)"
11848   "shr{w}\t%0"
11849   [(set_attr "type" "ishift")
11850    (set (attr "length") 
11851      (if_then_else (match_operand 0 "register_operand" "") 
11852         (const_string "2")
11853         (const_string "*")))])
11855 (define_insn "*lshrhi3_1"
11856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11857         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11858                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11861   "@
11862    shr{w}\t{%2, %0|%0, %2}
11863    shr{w}\t{%b2, %0|%0, %b2}"
11864   [(set_attr "type" "ishift")
11865    (set_attr "mode" "HI")])
11867 ;; This pattern can't accept a variable shift count, since shifts by
11868 ;; zero don't affect the flags.  We assume that shifts by constant
11869 ;; zero are optimized away.
11870 (define_insn "*lshrhi3_one_bit_cmp"
11871   [(set (reg FLAGS_REG)
11872         (compare
11873           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const1_operand" ""))
11875           (const_int 0)))
11876    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11877         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11878   "ix86_match_ccmode (insn, CCGOCmode)
11879    && (TARGET_SHIFT1 || optimize_size)
11880    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11881   "shr{w}\t%0"
11882   [(set_attr "type" "ishift")
11883    (set (attr "length") 
11884      (if_then_else (match_operand:SI 0 "register_operand" "") 
11885         (const_string "2")
11886         (const_string "*")))])
11888 ;; This pattern can't accept a variable shift count, since shifts by
11889 ;; zero don't affect the flags.  We assume that shifts by constant
11890 ;; zero are optimized away.
11891 (define_insn "*lshrhi3_cmp"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11895                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11896           (const_int 0)))
11897    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11899   "ix86_match_ccmode (insn, CCGOCmode)
11900    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11901   "shr{w}\t{%2, %0|%0, %2}"
11902   [(set_attr "type" "ishift")
11903    (set_attr "mode" "HI")])
11905 (define_expand "lshrqi3"
11906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11907         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11908                      (match_operand:QI 2 "nonmemory_operand" "")))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_QIMODE_MATH"
11911   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11913 (define_insn "*lshrqi3_1_one_bit"
11914   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11915         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11916                      (match_operand:QI 2 "const1_operand" "")))
11917    (clobber (reg:CC FLAGS_REG))]
11918   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11919    && (TARGET_SHIFT1 || optimize_size)"
11920   "shr{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set (attr "length") 
11923      (if_then_else (match_operand 0 "register_operand" "") 
11924         (const_string "2")
11925         (const_string "*")))])
11927 (define_insn "*lshrqi3_1_one_bit_slp"
11928   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11929         (lshiftrt:QI (match_dup 0)
11930                      (match_operand:QI 1 "const1_operand" "")))
11931    (clobber (reg:CC FLAGS_REG))]
11932   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11933    && (TARGET_SHIFT1 || optimize_size)"
11934   "shr{b}\t%0"
11935   [(set_attr "type" "ishift1")
11936    (set (attr "length") 
11937      (if_then_else (match_operand 0 "register_operand" "") 
11938         (const_string "2")
11939         (const_string "*")))])
11941 (define_insn "*lshrqi3_1"
11942   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11943         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11944                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11947   "@
11948    shr{b}\t{%2, %0|%0, %2}
11949    shr{b}\t{%b2, %0|%0, %b2}"
11950   [(set_attr "type" "ishift")
11951    (set_attr "mode" "QI")])
11953 (define_insn "*lshrqi3_1_slp"
11954   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11955         (lshiftrt:QI (match_dup 0)
11956                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11957    (clobber (reg:CC FLAGS_REG))]
11958   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11959    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11960   "@
11961    shr{b}\t{%1, %0|%0, %1}
11962    shr{b}\t{%b1, %0|%0, %b1}"
11963   [(set_attr "type" "ishift1")
11964    (set_attr "mode" "QI")])
11966 ;; This pattern can't accept a variable shift count, since shifts by
11967 ;; zero don't affect the flags.  We assume that shifts by constant
11968 ;; zero are optimized away.
11969 (define_insn "*lshrqi2_one_bit_cmp"
11970   [(set (reg FLAGS_REG)
11971         (compare
11972           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11973                        (match_operand:QI 2 "const1_operand" ""))
11974           (const_int 0)))
11975    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11976         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11977   "ix86_match_ccmode (insn, CCGOCmode)
11978    && (TARGET_SHIFT1 || optimize_size)
11979    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11980   "shr{b}\t%0"
11981   [(set_attr "type" "ishift")
11982    (set (attr "length") 
11983      (if_then_else (match_operand:SI 0 "register_operand" "") 
11984         (const_string "2")
11985         (const_string "*")))])
11987 ;; This pattern can't accept a variable shift count, since shifts by
11988 ;; zero don't affect the flags.  We assume that shifts by constant
11989 ;; zero are optimized away.
11990 (define_insn "*lshrqi2_cmp"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995           (const_int 0)))
11996    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11997         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11998   "ix86_match_ccmode (insn, CCGOCmode)
11999    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12000   "shr{b}\t{%2, %0|%0, %2}"
12001   [(set_attr "type" "ishift")
12002    (set_attr "mode" "QI")])
12004 ;; Rotate instructions
12006 (define_expand "rotldi3"
12007   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12008         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12009                    (match_operand:QI 2 "nonmemory_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT"
12012   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12014 (define_insn "*rotlsi3_1_one_bit_rex64"
12015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12016         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017                    (match_operand:QI 2 "const1_operand" "")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12020    && (TARGET_SHIFT1 || optimize_size)"
12021   "rol{q}\t%0"
12022   [(set_attr "type" "rotate")
12023    (set (attr "length") 
12024      (if_then_else (match_operand:DI 0 "register_operand" "") 
12025         (const_string "2")
12026         (const_string "*")))])
12028 (define_insn "*rotldi3_1_rex64"
12029   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12030         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12031                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12034   "@
12035    rol{q}\t{%2, %0|%0, %2}
12036    rol{q}\t{%b2, %0|%0, %b2}"
12037   [(set_attr "type" "rotate")
12038    (set_attr "mode" "DI")])
12040 (define_expand "rotlsi3"
12041   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12042         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12043                    (match_operand:QI 2 "nonmemory_operand" "")))
12044    (clobber (reg:CC FLAGS_REG))]
12045   ""
12046   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12048 (define_insn "*rotlsi3_1_one_bit"
12049   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12050         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12051                    (match_operand:QI 2 "const1_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12054    && (TARGET_SHIFT1 || optimize_size)"
12055   "rol{l}\t%0"
12056   [(set_attr "type" "rotate")
12057    (set (attr "length") 
12058      (if_then_else (match_operand:SI 0 "register_operand" "") 
12059         (const_string "2")
12060         (const_string "*")))])
12062 (define_insn "*rotlsi3_1_one_bit_zext"
12063   [(set (match_operand:DI 0 "register_operand" "=r")
12064         (zero_extend:DI
12065           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12066                      (match_operand:QI 2 "const1_operand" ""))))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12069    && (TARGET_SHIFT1 || optimize_size)"
12070   "rol{l}\t%k0"
12071   [(set_attr "type" "rotate")
12072    (set_attr "length" "2")])
12074 (define_insn "*rotlsi3_1"
12075   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12076         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12077                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12080   "@
12081    rol{l}\t{%2, %0|%0, %2}
12082    rol{l}\t{%b2, %0|%0, %b2}"
12083   [(set_attr "type" "rotate")
12084    (set_attr "mode" "SI")])
12086 (define_insn "*rotlsi3_1_zext"
12087   [(set (match_operand:DI 0 "register_operand" "=r,r")
12088         (zero_extend:DI
12089           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12090                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12091    (clobber (reg:CC FLAGS_REG))]
12092   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12093   "@
12094    rol{l}\t{%2, %k0|%k0, %2}
12095    rol{l}\t{%b2, %k0|%k0, %b2}"
12096   [(set_attr "type" "rotate")
12097    (set_attr "mode" "SI")])
12099 (define_expand "rotlhi3"
12100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12101         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12102                    (match_operand:QI 2 "nonmemory_operand" "")))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_HIMODE_MATH"
12105   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12107 (define_insn "*rotlhi3_1_one_bit"
12108   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12109         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12110                    (match_operand:QI 2 "const1_operand" "")))
12111    (clobber (reg:CC FLAGS_REG))]
12112   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12113    && (TARGET_SHIFT1 || optimize_size)"
12114   "rol{w}\t%0"
12115   [(set_attr "type" "rotate")
12116    (set (attr "length") 
12117      (if_then_else (match_operand 0 "register_operand" "") 
12118         (const_string "2")
12119         (const_string "*")))])
12121 (define_insn "*rotlhi3_1"
12122   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12123         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12124                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12127   "@
12128    rol{w}\t{%2, %0|%0, %2}
12129    rol{w}\t{%b2, %0|%0, %b2}"
12130   [(set_attr "type" "rotate")
12131    (set_attr "mode" "HI")])
12133 (define_expand "rotlqi3"
12134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12135         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12136                    (match_operand:QI 2 "nonmemory_operand" "")))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_QIMODE_MATH"
12139   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12141 (define_insn "*rotlqi3_1_one_bit_slp"
12142   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12143         (rotate:QI (match_dup 0)
12144                    (match_operand:QI 1 "const1_operand" "")))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "rol{b}\t%0"
12149   [(set_attr "type" "rotate1")
12150    (set (attr "length") 
12151      (if_then_else (match_operand 0 "register_operand" "") 
12152         (const_string "2")
12153         (const_string "*")))])
12155 (define_insn "*rotlqi3_1_one_bit"
12156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158                    (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "rol{b}\t%0"
12163   [(set_attr "type" "rotate")
12164    (set (attr "length") 
12165      (if_then_else (match_operand 0 "register_operand" "") 
12166         (const_string "2")
12167         (const_string "*")))])
12169 (define_insn "*rotlqi3_1_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171         (rotate:QI (match_dup 0)
12172                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12176   "@
12177    rol{b}\t{%1, %0|%0, %1}
12178    rol{b}\t{%b1, %0|%0, %b1}"
12179   [(set_attr "type" "rotate1")
12180    (set_attr "mode" "QI")])
12182 (define_insn "*rotlqi3_1"
12183   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12184         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12185                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12188   "@
12189    rol{b}\t{%2, %0|%0, %2}
12190    rol{b}\t{%b2, %0|%0, %b2}"
12191   [(set_attr "type" "rotate")
12192    (set_attr "mode" "QI")])
12194 (define_expand "rotrdi3"
12195   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12196         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12197                      (match_operand:QI 2 "nonmemory_operand" "")))
12198    (clobber (reg:CC FLAGS_REG))]
12199   "TARGET_64BIT"
12200   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12202 (define_insn "*rotrdi3_1_one_bit_rex64"
12203   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12204         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12205                      (match_operand:QI 2 "const1_operand" "")))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12208    && (TARGET_SHIFT1 || optimize_size)"
12209   "ror{q}\t%0"
12210   [(set_attr "type" "rotate")
12211    (set (attr "length") 
12212      (if_then_else (match_operand:DI 0 "register_operand" "") 
12213         (const_string "2")
12214         (const_string "*")))])
12216 (define_insn "*rotrdi3_1_rex64"
12217   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12218         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12219                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12222   "@
12223    ror{q}\t{%2, %0|%0, %2}
12224    ror{q}\t{%b2, %0|%0, %b2}"
12225   [(set_attr "type" "rotate")
12226    (set_attr "mode" "DI")])
12228 (define_expand "rotrsi3"
12229   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12230         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12231                      (match_operand:QI 2 "nonmemory_operand" "")))
12232    (clobber (reg:CC FLAGS_REG))]
12233   ""
12234   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12236 (define_insn "*rotrsi3_1_one_bit"
12237   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12238         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12239                      (match_operand:QI 2 "const1_operand" "")))
12240    (clobber (reg:CC FLAGS_REG))]
12241   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12242    && (TARGET_SHIFT1 || optimize_size)"
12243   "ror{l}\t%0"
12244   [(set_attr "type" "rotate")
12245    (set (attr "length") 
12246      (if_then_else (match_operand:SI 0 "register_operand" "") 
12247         (const_string "2")
12248         (const_string "*")))])
12250 (define_insn "*rotrsi3_1_one_bit_zext"
12251   [(set (match_operand:DI 0 "register_operand" "=r")
12252         (zero_extend:DI
12253           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12254                        (match_operand:QI 2 "const1_operand" ""))))
12255    (clobber (reg:CC FLAGS_REG))]
12256   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12257    && (TARGET_SHIFT1 || optimize_size)"
12258   "ror{l}\t%k0"
12259   [(set_attr "type" "rotate")
12260    (set (attr "length") 
12261      (if_then_else (match_operand:SI 0 "register_operand" "") 
12262         (const_string "2")
12263         (const_string "*")))])
12265 (define_insn "*rotrsi3_1"
12266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12267         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12268                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12271   "@
12272    ror{l}\t{%2, %0|%0, %2}
12273    ror{l}\t{%b2, %0|%0, %b2}"
12274   [(set_attr "type" "rotate")
12275    (set_attr "mode" "SI")])
12277 (define_insn "*rotrsi3_1_zext"
12278   [(set (match_operand:DI 0 "register_operand" "=r,r")
12279         (zero_extend:DI
12280           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12281                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12284   "@
12285    ror{l}\t{%2, %k0|%k0, %2}
12286    ror{l}\t{%b2, %k0|%k0, %b2}"
12287   [(set_attr "type" "rotate")
12288    (set_attr "mode" "SI")])
12290 (define_expand "rotrhi3"
12291   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12292         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12293                      (match_operand:QI 2 "nonmemory_operand" "")))
12294    (clobber (reg:CC FLAGS_REG))]
12295   "TARGET_HIMODE_MATH"
12296   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12298 (define_insn "*rotrhi3_one_bit"
12299   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12300         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12301                      (match_operand:QI 2 "const1_operand" "")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12304    && (TARGET_SHIFT1 || optimize_size)"
12305   "ror{w}\t%0"
12306   [(set_attr "type" "rotate")
12307    (set (attr "length") 
12308      (if_then_else (match_operand 0 "register_operand" "") 
12309         (const_string "2")
12310         (const_string "*")))])
12312 (define_insn "*rotrhi3"
12313   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12314         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12315                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12318   "@
12319    ror{w}\t{%2, %0|%0, %2}
12320    ror{w}\t{%b2, %0|%0, %b2}"
12321   [(set_attr "type" "rotate")
12322    (set_attr "mode" "HI")])
12324 (define_expand "rotrqi3"
12325   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12326         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12327                      (match_operand:QI 2 "nonmemory_operand" "")))
12328    (clobber (reg:CC FLAGS_REG))]
12329   "TARGET_QIMODE_MATH"
12330   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12332 (define_insn "*rotrqi3_1_one_bit"
12333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12334         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12335                      (match_operand:QI 2 "const1_operand" "")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12338    && (TARGET_SHIFT1 || optimize_size)"
12339   "ror{b}\t%0"
12340   [(set_attr "type" "rotate")
12341    (set (attr "length") 
12342      (if_then_else (match_operand 0 "register_operand" "") 
12343         (const_string "2")
12344         (const_string "*")))])
12346 (define_insn "*rotrqi3_1_one_bit_slp"
12347   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12348         (rotatert:QI (match_dup 0)
12349                      (match_operand:QI 1 "const1_operand" "")))
12350    (clobber (reg:CC FLAGS_REG))]
12351   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12352    && (TARGET_SHIFT1 || optimize_size)"
12353   "ror{b}\t%0"
12354   [(set_attr "type" "rotate1")
12355    (set (attr "length") 
12356      (if_then_else (match_operand 0 "register_operand" "") 
12357         (const_string "2")
12358         (const_string "*")))])
12360 (define_insn "*rotrqi3_1"
12361   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12362         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12363                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12366   "@
12367    ror{b}\t{%2, %0|%0, %2}
12368    ror{b}\t{%b2, %0|%0, %b2}"
12369   [(set_attr "type" "rotate")
12370    (set_attr "mode" "QI")])
12372 (define_insn "*rotrqi3_1_slp"
12373   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12374         (rotatert:QI (match_dup 0)
12375                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12378    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12379   "@
12380    ror{b}\t{%1, %0|%0, %1}
12381    ror{b}\t{%b1, %0|%0, %b1}"
12382   [(set_attr "type" "rotate1")
12383    (set_attr "mode" "QI")])
12385 ;; Bit set / bit test instructions
12387 (define_expand "extv"
12388   [(set (match_operand:SI 0 "register_operand" "")
12389         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12390                          (match_operand:SI 2 "immediate_operand" "")
12391                          (match_operand:SI 3 "immediate_operand" "")))]
12392   ""
12394   /* Handle extractions from %ah et al.  */
12395   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12396     FAIL;
12398   /* From mips.md: extract_bit_field doesn't verify that our source
12399      matches the predicate, so check it again here.  */
12400   if (! ext_register_operand (operands[1], VOIDmode))
12401     FAIL;
12404 (define_expand "extzv"
12405   [(set (match_operand:SI 0 "register_operand" "")
12406         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12407                          (match_operand:SI 2 "immediate_operand" "")
12408                          (match_operand:SI 3 "immediate_operand" "")))]
12409   ""
12411   /* Handle extractions from %ah et al.  */
12412   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12413     FAIL;
12415   /* From mips.md: extract_bit_field doesn't verify that our source
12416      matches the predicate, so check it again here.  */
12417   if (! ext_register_operand (operands[1], VOIDmode))
12418     FAIL;
12421 (define_expand "insv"
12422   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12423                       (match_operand 1 "immediate_operand" "")
12424                       (match_operand 2 "immediate_operand" ""))
12425         (match_operand 3 "register_operand" ""))]
12426   ""
12428   /* Handle extractions from %ah et al.  */
12429   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12430     FAIL;
12432   /* From mips.md: insert_bit_field doesn't verify that our source
12433      matches the predicate, so check it again here.  */
12434   if (! ext_register_operand (operands[0], VOIDmode))
12435     FAIL;
12437   if (TARGET_64BIT)
12438     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12439   else
12440     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12442   DONE;
12445 ;; %%% bts, btr, btc, bt.
12446 ;; In general these instructions are *slow* when applied to memory,
12447 ;; since they enforce atomic operation.  When applied to registers,
12448 ;; it depends on the cpu implementation.  They're never faster than
12449 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12450 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12451 ;; within the instruction itself, so operating on bits in the high
12452 ;; 32-bits of a register becomes easier.
12454 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12455 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12456 ;; negdf respectively, so they can never be disabled entirely.
12458 (define_insn "*btsq"
12459   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12460                          (const_int 1)
12461                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12462         (const_int 1))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12465   "bts{q} %1,%0"
12466   [(set_attr "type" "alu1")])
12468 (define_insn "*btrq"
12469   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12470                          (const_int 1)
12471                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12472         (const_int 0))
12473    (clobber (reg:CC FLAGS_REG))]
12474   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12475   "btr{q} %1,%0"
12476   [(set_attr "type" "alu1")])
12478 (define_insn "*btcq"
12479   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12480                          (const_int 1)
12481                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12482         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12485   "btc{q} %1,%0"
12486   [(set_attr "type" "alu1")])
12488 ;; Allow Nocona to avoid these instructions if a register is available.
12490 (define_peephole2
12491   [(match_scratch:DI 2 "r")
12492    (parallel [(set (zero_extract:DI
12493                      (match_operand:DI 0 "register_operand" "")
12494                      (const_int 1)
12495                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12496                    (const_int 1))
12497               (clobber (reg:CC FLAGS_REG))])]
12498   "TARGET_64BIT && !TARGET_USE_BT"
12499   [(const_int 0)]
12501   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12502   rtx op1;
12504   if (HOST_BITS_PER_WIDE_INT >= 64)
12505     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12506   else if (i < HOST_BITS_PER_WIDE_INT)
12507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12508   else
12509     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12511   op1 = immed_double_const (lo, hi, DImode);
12512   if (i >= 31)
12513     {
12514       emit_move_insn (operands[2], op1);
12515       op1 = operands[2];
12516     }
12518   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12519   DONE;
12522 (define_peephole2
12523   [(match_scratch:DI 2 "r")
12524    (parallel [(set (zero_extract:DI
12525                      (match_operand:DI 0 "register_operand" "")
12526                      (const_int 1)
12527                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12528                    (const_int 0))
12529               (clobber (reg:CC FLAGS_REG))])]
12530   "TARGET_64BIT && !TARGET_USE_BT"
12531   [(const_int 0)]
12533   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12534   rtx op1;
12536   if (HOST_BITS_PER_WIDE_INT >= 64)
12537     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12538   else if (i < HOST_BITS_PER_WIDE_INT)
12539     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12540   else
12541     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12543   op1 = immed_double_const (~lo, ~hi, DImode);
12544   if (i >= 32)
12545     {
12546       emit_move_insn (operands[2], op1);
12547       op1 = operands[2];
12548     }
12550   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12551   DONE;
12554 (define_peephole2
12555   [(match_scratch:DI 2 "r")
12556    (parallel [(set (zero_extract:DI
12557                      (match_operand:DI 0 "register_operand" "")
12558                      (const_int 1)
12559                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12560               (not:DI (zero_extract:DI
12561                         (match_dup 0) (const_int 1) (match_dup 1))))
12562               (clobber (reg:CC FLAGS_REG))])]
12563   "TARGET_64BIT && !TARGET_USE_BT"
12564   [(const_int 0)]
12566   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12567   rtx op1;
12569   if (HOST_BITS_PER_WIDE_INT >= 64)
12570     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12571   else if (i < HOST_BITS_PER_WIDE_INT)
12572     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12573   else
12574     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12576   op1 = immed_double_const (lo, hi, DImode);
12577   if (i >= 31)
12578     {
12579       emit_move_insn (operands[2], op1);
12580       op1 = operands[2];
12581     }
12583   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12584   DONE;
12587 ;; Store-flag instructions.
12589 ;; For all sCOND expanders, also expand the compare or test insn that
12590 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12592 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12593 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12594 ;; way, which can later delete the movzx if only QImode is needed.
12596 (define_expand "seq"
12597   [(set (match_operand:QI 0 "register_operand" "")
12598         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12599   ""
12600   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12602 (define_expand "sne"
12603   [(set (match_operand:QI 0 "register_operand" "")
12604         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12605   ""
12606   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12608 (define_expand "sgt"
12609   [(set (match_operand:QI 0 "register_operand" "")
12610         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12611   ""
12612   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12614 (define_expand "sgtu"
12615   [(set (match_operand:QI 0 "register_operand" "")
12616         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12617   ""
12618   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12620 (define_expand "slt"
12621   [(set (match_operand:QI 0 "register_operand" "")
12622         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12623   ""
12624   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12626 (define_expand "sltu"
12627   [(set (match_operand:QI 0 "register_operand" "")
12628         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12629   ""
12630   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12632 (define_expand "sge"
12633   [(set (match_operand:QI 0 "register_operand" "")
12634         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12635   ""
12636   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12638 (define_expand "sgeu"
12639   [(set (match_operand:QI 0 "register_operand" "")
12640         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12641   ""
12642   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12644 (define_expand "sle"
12645   [(set (match_operand:QI 0 "register_operand" "")
12646         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12647   ""
12648   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12650 (define_expand "sleu"
12651   [(set (match_operand:QI 0 "register_operand" "")
12652         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12653   ""
12654   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12656 (define_expand "sunordered"
12657   [(set (match_operand:QI 0 "register_operand" "")
12658         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12659   "TARGET_80387 || TARGET_SSE"
12660   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12662 (define_expand "sordered"
12663   [(set (match_operand:QI 0 "register_operand" "")
12664         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12665   "TARGET_80387"
12666   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12668 (define_expand "suneq"
12669   [(set (match_operand:QI 0 "register_operand" "")
12670         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12671   "TARGET_80387 || TARGET_SSE"
12672   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12674 (define_expand "sunge"
12675   [(set (match_operand:QI 0 "register_operand" "")
12676         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12677   "TARGET_80387 || TARGET_SSE"
12678   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12680 (define_expand "sungt"
12681   [(set (match_operand:QI 0 "register_operand" "")
12682         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683   "TARGET_80387 || TARGET_SSE"
12684   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12686 (define_expand "sunle"
12687   [(set (match_operand:QI 0 "register_operand" "")
12688         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689   "TARGET_80387 || TARGET_SSE"
12690   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12692 (define_expand "sunlt"
12693   [(set (match_operand:QI 0 "register_operand" "")
12694         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695   "TARGET_80387 || TARGET_SSE"
12696   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12698 (define_expand "sltgt"
12699   [(set (match_operand:QI 0 "register_operand" "")
12700         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701   "TARGET_80387 || TARGET_SSE"
12702   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12704 (define_insn "*setcc_1"
12705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12706         (match_operator:QI 1 "ix86_comparison_operator"
12707           [(reg FLAGS_REG) (const_int 0)]))]
12708   ""
12709   "set%C1\t%0"
12710   [(set_attr "type" "setcc")
12711    (set_attr "mode" "QI")])
12713 (define_insn "*setcc_2"
12714   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12715         (match_operator:QI 1 "ix86_comparison_operator"
12716           [(reg FLAGS_REG) (const_int 0)]))]
12717   ""
12718   "set%C1\t%0"
12719   [(set_attr "type" "setcc")
12720    (set_attr "mode" "QI")])
12722 ;; In general it is not safe to assume too much about CCmode registers,
12723 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12724 ;; conditions this is safe on x86, so help combine not create
12726 ;;      seta    %al
12727 ;;      testb   %al, %al
12728 ;;      sete    %al
12730 (define_split 
12731   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12732         (ne:QI (match_operator 1 "ix86_comparison_operator"
12733                  [(reg FLAGS_REG) (const_int 0)])
12734             (const_int 0)))]
12735   ""
12736   [(set (match_dup 0) (match_dup 1))]
12738   PUT_MODE (operands[1], QImode);
12741 (define_split 
12742   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12743         (ne:QI (match_operator 1 "ix86_comparison_operator"
12744                  [(reg FLAGS_REG) (const_int 0)])
12745             (const_int 0)))]
12746   ""
12747   [(set (match_dup 0) (match_dup 1))]
12749   PUT_MODE (operands[1], QImode);
12752 (define_split 
12753   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12754         (eq:QI (match_operator 1 "ix86_comparison_operator"
12755                  [(reg FLAGS_REG) (const_int 0)])
12756             (const_int 0)))]
12757   ""
12758   [(set (match_dup 0) (match_dup 1))]
12760   rtx new_op1 = copy_rtx (operands[1]);
12761   operands[1] = new_op1;
12762   PUT_MODE (new_op1, QImode);
12763   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12764                                              GET_MODE (XEXP (new_op1, 0))));
12766   /* Make sure that (a) the CCmode we have for the flags is strong
12767      enough for the reversed compare or (b) we have a valid FP compare.  */
12768   if (! ix86_comparison_operator (new_op1, VOIDmode))
12769     FAIL;
12772 (define_split 
12773   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12774         (eq:QI (match_operator 1 "ix86_comparison_operator"
12775                  [(reg FLAGS_REG) (const_int 0)])
12776             (const_int 0)))]
12777   ""
12778   [(set (match_dup 0) (match_dup 1))]
12780   rtx new_op1 = copy_rtx (operands[1]);
12781   operands[1] = new_op1;
12782   PUT_MODE (new_op1, QImode);
12783   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12784                                              GET_MODE (XEXP (new_op1, 0))));
12786   /* Make sure that (a) the CCmode we have for the flags is strong
12787      enough for the reversed compare or (b) we have a valid FP compare.  */
12788   if (! ix86_comparison_operator (new_op1, VOIDmode))
12789     FAIL;
12792 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12793 ;; subsequent logical operations are used to imitate conditional moves.
12794 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12795 ;; it directly.
12797 (define_insn "*sse_setccsf"
12798   [(set (match_operand:SF 0 "register_operand" "=x")
12799         (match_operator:SF 1 "sse_comparison_operator"
12800           [(match_operand:SF 2 "register_operand" "0")
12801            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12802   "TARGET_SSE"
12803   "cmp%D1ss\t{%3, %0|%0, %3}"
12804   [(set_attr "type" "ssecmp")
12805    (set_attr "mode" "SF")])
12807 (define_insn "*sse_setccdf"
12808   [(set (match_operand:DF 0 "register_operand" "=Y")
12809         (match_operator:DF 1 "sse_comparison_operator"
12810           [(match_operand:DF 2 "register_operand" "0")
12811            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12812   "TARGET_SSE2"
12813   "cmp%D1sd\t{%3, %0|%0, %3}"
12814   [(set_attr "type" "ssecmp")
12815    (set_attr "mode" "DF")])
12817 ;; Basic conditional jump instructions.
12818 ;; We ignore the overflow flag for signed branch instructions.
12820 ;; For all bCOND expanders, also expand the compare or test insn that
12821 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12823 (define_expand "beq"
12824   [(set (pc)
12825         (if_then_else (match_dup 1)
12826                       (label_ref (match_operand 0 "" ""))
12827                       (pc)))]
12828   ""
12829   "ix86_expand_branch (EQ, operands[0]); DONE;")
12831 (define_expand "bne"
12832   [(set (pc)
12833         (if_then_else (match_dup 1)
12834                       (label_ref (match_operand 0 "" ""))
12835                       (pc)))]
12836   ""
12837   "ix86_expand_branch (NE, operands[0]); DONE;")
12839 (define_expand "bgt"
12840   [(set (pc)
12841         (if_then_else (match_dup 1)
12842                       (label_ref (match_operand 0 "" ""))
12843                       (pc)))]
12844   ""
12845   "ix86_expand_branch (GT, operands[0]); DONE;")
12847 (define_expand "bgtu"
12848   [(set (pc)
12849         (if_then_else (match_dup 1)
12850                       (label_ref (match_operand 0 "" ""))
12851                       (pc)))]
12852   ""
12853   "ix86_expand_branch (GTU, operands[0]); DONE;")
12855 (define_expand "blt"
12856   [(set (pc)
12857         (if_then_else (match_dup 1)
12858                       (label_ref (match_operand 0 "" ""))
12859                       (pc)))]
12860   ""
12861   "ix86_expand_branch (LT, operands[0]); DONE;")
12863 (define_expand "bltu"
12864   [(set (pc)
12865         (if_then_else (match_dup 1)
12866                       (label_ref (match_operand 0 "" ""))
12867                       (pc)))]
12868   ""
12869   "ix86_expand_branch (LTU, operands[0]); DONE;")
12871 (define_expand "bge"
12872   [(set (pc)
12873         (if_then_else (match_dup 1)
12874                       (label_ref (match_operand 0 "" ""))
12875                       (pc)))]
12876   ""
12877   "ix86_expand_branch (GE, operands[0]); DONE;")
12879 (define_expand "bgeu"
12880   [(set (pc)
12881         (if_then_else (match_dup 1)
12882                       (label_ref (match_operand 0 "" ""))
12883                       (pc)))]
12884   ""
12885   "ix86_expand_branch (GEU, operands[0]); DONE;")
12887 (define_expand "ble"
12888   [(set (pc)
12889         (if_then_else (match_dup 1)
12890                       (label_ref (match_operand 0 "" ""))
12891                       (pc)))]
12892   ""
12893   "ix86_expand_branch (LE, operands[0]); DONE;")
12895 (define_expand "bleu"
12896   [(set (pc)
12897         (if_then_else (match_dup 1)
12898                       (label_ref (match_operand 0 "" ""))
12899                       (pc)))]
12900   ""
12901   "ix86_expand_branch (LEU, operands[0]); DONE;")
12903 (define_expand "bunordered"
12904   [(set (pc)
12905         (if_then_else (match_dup 1)
12906                       (label_ref (match_operand 0 "" ""))
12907                       (pc)))]
12908   "TARGET_80387 || TARGET_SSE_MATH"
12909   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12911 (define_expand "bordered"
12912   [(set (pc)
12913         (if_then_else (match_dup 1)
12914                       (label_ref (match_operand 0 "" ""))
12915                       (pc)))]
12916   "TARGET_80387 || TARGET_SSE_MATH"
12917   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12919 (define_expand "buneq"
12920   [(set (pc)
12921         (if_then_else (match_dup 1)
12922                       (label_ref (match_operand 0 "" ""))
12923                       (pc)))]
12924   "TARGET_80387 || TARGET_SSE_MATH"
12925   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12927 (define_expand "bunge"
12928   [(set (pc)
12929         (if_then_else (match_dup 1)
12930                       (label_ref (match_operand 0 "" ""))
12931                       (pc)))]
12932   "TARGET_80387 || TARGET_SSE_MATH"
12933   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12935 (define_expand "bungt"
12936   [(set (pc)
12937         (if_then_else (match_dup 1)
12938                       (label_ref (match_operand 0 "" ""))
12939                       (pc)))]
12940   "TARGET_80387 || TARGET_SSE_MATH"
12941   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12943 (define_expand "bunle"
12944   [(set (pc)
12945         (if_then_else (match_dup 1)
12946                       (label_ref (match_operand 0 "" ""))
12947                       (pc)))]
12948   "TARGET_80387 || TARGET_SSE_MATH"
12949   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12951 (define_expand "bunlt"
12952   [(set (pc)
12953         (if_then_else (match_dup 1)
12954                       (label_ref (match_operand 0 "" ""))
12955                       (pc)))]
12956   "TARGET_80387 || TARGET_SSE_MATH"
12957   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12959 (define_expand "bltgt"
12960   [(set (pc)
12961         (if_then_else (match_dup 1)
12962                       (label_ref (match_operand 0 "" ""))
12963                       (pc)))]
12964   "TARGET_80387 || TARGET_SSE_MATH"
12965   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12967 (define_insn "*jcc_1"
12968   [(set (pc)
12969         (if_then_else (match_operator 1 "ix86_comparison_operator"
12970                                       [(reg FLAGS_REG) (const_int 0)])
12971                       (label_ref (match_operand 0 "" ""))
12972                       (pc)))]
12973   ""
12974   "%+j%C1\t%l0"
12975   [(set_attr "type" "ibr")
12976    (set_attr "modrm" "0")
12977    (set (attr "length")
12978            (if_then_else (and (ge (minus (match_dup 0) (pc))
12979                                   (const_int -126))
12980                               (lt (minus (match_dup 0) (pc))
12981                                   (const_int 128)))
12982              (const_int 2)
12983              (const_int 6)))])
12985 (define_insn "*jcc_2"
12986   [(set (pc)
12987         (if_then_else (match_operator 1 "ix86_comparison_operator"
12988                                       [(reg FLAGS_REG) (const_int 0)])
12989                       (pc)
12990                       (label_ref (match_operand 0 "" ""))))]
12991   ""
12992   "%+j%c1\t%l0"
12993   [(set_attr "type" "ibr")
12994    (set_attr "modrm" "0")
12995    (set (attr "length")
12996            (if_then_else (and (ge (minus (match_dup 0) (pc))
12997                                   (const_int -126))
12998                               (lt (minus (match_dup 0) (pc))
12999                                   (const_int 128)))
13000              (const_int 2)
13001              (const_int 6)))])
13003 ;; In general it is not safe to assume too much about CCmode registers,
13004 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13005 ;; conditions this is safe on x86, so help combine not create
13007 ;;      seta    %al
13008 ;;      testb   %al, %al
13009 ;;      je      Lfoo
13011 (define_split 
13012   [(set (pc)
13013         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13014                                       [(reg FLAGS_REG) (const_int 0)])
13015                           (const_int 0))
13016                       (label_ref (match_operand 1 "" ""))
13017                       (pc)))]
13018   ""
13019   [(set (pc)
13020         (if_then_else (match_dup 0)
13021                       (label_ref (match_dup 1))
13022                       (pc)))]
13024   PUT_MODE (operands[0], VOIDmode);
13026   
13027 (define_split 
13028   [(set (pc)
13029         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13030                                       [(reg FLAGS_REG) (const_int 0)])
13031                           (const_int 0))
13032                       (label_ref (match_operand 1 "" ""))
13033                       (pc)))]
13034   ""
13035   [(set (pc)
13036         (if_then_else (match_dup 0)
13037                       (label_ref (match_dup 1))
13038                       (pc)))]
13040   rtx new_op0 = copy_rtx (operands[0]);
13041   operands[0] = new_op0;
13042   PUT_MODE (new_op0, VOIDmode);
13043   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13044                                              GET_MODE (XEXP (new_op0, 0))));
13046   /* Make sure that (a) the CCmode we have for the flags is strong
13047      enough for the reversed compare or (b) we have a valid FP compare.  */
13048   if (! ix86_comparison_operator (new_op0, VOIDmode))
13049     FAIL;
13052 ;; Define combination compare-and-branch fp compare instructions to use
13053 ;; during early optimization.  Splitting the operation apart early makes
13054 ;; for bad code when we want to reverse the operation.
13056 (define_insn "*fp_jcc_1_mixed"
13057   [(set (pc)
13058         (if_then_else (match_operator 0 "comparison_operator"
13059                         [(match_operand 1 "register_operand" "f#x,x#f")
13060                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13061           (label_ref (match_operand 3 "" ""))
13062           (pc)))
13063    (clobber (reg:CCFP FPSR_REG))
13064    (clobber (reg:CCFP FLAGS_REG))]
13065   "TARGET_MIX_SSE_I387
13066    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13067    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13068    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13069   "#")
13071 (define_insn "*fp_jcc_1_sse"
13072   [(set (pc)
13073         (if_then_else (match_operator 0 "comparison_operator"
13074                         [(match_operand 1 "register_operand" "x")
13075                          (match_operand 2 "nonimmediate_operand" "xm")])
13076           (label_ref (match_operand 3 "" ""))
13077           (pc)))
13078    (clobber (reg:CCFP FPSR_REG))
13079    (clobber (reg:CCFP FLAGS_REG))]
13080   "TARGET_SSE_MATH
13081    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13082    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13083    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13084   "#")
13086 (define_insn "*fp_jcc_1_387"
13087   [(set (pc)
13088         (if_then_else (match_operator 0 "comparison_operator"
13089                         [(match_operand 1 "register_operand" "f")
13090                          (match_operand 2 "register_operand" "f")])
13091           (label_ref (match_operand 3 "" ""))
13092           (pc)))
13093    (clobber (reg:CCFP FPSR_REG))
13094    (clobber (reg:CCFP FLAGS_REG))]
13095   "TARGET_CMOVE && TARGET_80387
13096    && FLOAT_MODE_P (GET_MODE (operands[1]))
13097    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13098    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13099   "#")
13101 (define_insn "*fp_jcc_2_mixed"
13102   [(set (pc)
13103         (if_then_else (match_operator 0 "comparison_operator"
13104                         [(match_operand 1 "register_operand" "f#x,x#f")
13105                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13106           (pc)
13107           (label_ref (match_operand 3 "" ""))))
13108    (clobber (reg:CCFP FPSR_REG))
13109    (clobber (reg:CCFP FLAGS_REG))]
13110   "TARGET_MIX_SSE_I387
13111    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13112    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13113    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13114   "#")
13116 (define_insn "*fp_jcc_2_sse"
13117   [(set (pc)
13118         (if_then_else (match_operator 0 "comparison_operator"
13119                         [(match_operand 1 "register_operand" "x")
13120                          (match_operand 2 "nonimmediate_operand" "xm")])
13121           (pc)
13122           (label_ref (match_operand 3 "" ""))))
13123    (clobber (reg:CCFP FPSR_REG))
13124    (clobber (reg:CCFP FLAGS_REG))]
13125   "TARGET_SSE_MATH
13126    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13127    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13128    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13129   "#")
13131 (define_insn "*fp_jcc_2_387"
13132   [(set (pc)
13133         (if_then_else (match_operator 0 "comparison_operator"
13134                         [(match_operand 1 "register_operand" "f")
13135                          (match_operand 2 "register_operand" "f")])
13136           (pc)
13137           (label_ref (match_operand 3 "" ""))))
13138    (clobber (reg:CCFP FPSR_REG))
13139    (clobber (reg:CCFP FLAGS_REG))]
13140   "TARGET_CMOVE && TARGET_80387
13141    && FLOAT_MODE_P (GET_MODE (operands[1]))
13142    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13143    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13144   "#")
13146 (define_insn "*fp_jcc_3_387"
13147   [(set (pc)
13148         (if_then_else (match_operator 0 "comparison_operator"
13149                         [(match_operand 1 "register_operand" "f")
13150                          (match_operand 2 "nonimmediate_operand" "fm")])
13151           (label_ref (match_operand 3 "" ""))
13152           (pc)))
13153    (clobber (reg:CCFP FPSR_REG))
13154    (clobber (reg:CCFP FLAGS_REG))
13155    (clobber (match_scratch:HI 4 "=a"))]
13156   "TARGET_80387
13157    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13158    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13159    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13160    && SELECT_CC_MODE (GET_CODE (operands[0]),
13161                       operands[1], operands[2]) == CCFPmode
13162    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13163   "#")
13165 (define_insn "*fp_jcc_4_387"
13166   [(set (pc)
13167         (if_then_else (match_operator 0 "comparison_operator"
13168                         [(match_operand 1 "register_operand" "f")
13169                          (match_operand 2 "nonimmediate_operand" "fm")])
13170           (pc)
13171           (label_ref (match_operand 3 "" ""))))
13172    (clobber (reg:CCFP FPSR_REG))
13173    (clobber (reg:CCFP FLAGS_REG))
13174    (clobber (match_scratch:HI 4 "=a"))]
13175   "TARGET_80387
13176    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13177    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13178    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13179    && SELECT_CC_MODE (GET_CODE (operands[0]),
13180                       operands[1], operands[2]) == CCFPmode
13181    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182   "#")
13184 (define_insn "*fp_jcc_5_387"
13185   [(set (pc)
13186         (if_then_else (match_operator 0 "comparison_operator"
13187                         [(match_operand 1 "register_operand" "f")
13188                          (match_operand 2 "register_operand" "f")])
13189           (label_ref (match_operand 3 "" ""))
13190           (pc)))
13191    (clobber (reg:CCFP FPSR_REG))
13192    (clobber (reg:CCFP FLAGS_REG))
13193    (clobber (match_scratch:HI 4 "=a"))]
13194   "TARGET_80387
13195    && FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13200 (define_insn "*fp_jcc_6_387"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "f")
13204                          (match_operand 2 "register_operand" "f")])
13205           (pc)
13206           (label_ref (match_operand 3 "" ""))))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))
13209    (clobber (match_scratch:HI 4 "=a"))]
13210   "TARGET_80387
13211    && FLOAT_MODE_P (GET_MODE (operands[1]))
13212    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214   "#")
13216 (define_insn "*fp_jcc_7_387"
13217   [(set (pc)
13218         (if_then_else (match_operator 0 "comparison_operator"
13219                         [(match_operand 1 "register_operand" "f")
13220                          (match_operand 2 "const0_operand" "X")])
13221           (label_ref (match_operand 3 "" ""))
13222           (pc)))
13223    (clobber (reg:CCFP FPSR_REG))
13224    (clobber (reg:CCFP FLAGS_REG))
13225    (clobber (match_scratch:HI 4 "=a"))]
13226   "TARGET_80387
13227    && FLOAT_MODE_P (GET_MODE (operands[1]))
13228    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13229    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13230    && SELECT_CC_MODE (GET_CODE (operands[0]),
13231                       operands[1], operands[2]) == CCFPmode
13232    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13233   "#")
13235 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13236 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13237 ;; with a precedence over other operators and is always put in the first
13238 ;; place. Swap condition and operands to match ficom instruction.
13240 (define_insn "*fp_jcc_8<mode>_387"
13241   [(set (pc)
13242         (if_then_else (match_operator 0 "comparison_operator"
13243                         [(match_operator 1 "float_operator"
13244                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13245                            (match_operand 3 "register_operand" "f,f")])
13246           (label_ref (match_operand 4 "" ""))
13247           (pc)))
13248    (clobber (reg:CCFP FPSR_REG))
13249    (clobber (reg:CCFP FLAGS_REG))
13250    (clobber (match_scratch:HI 5 "=a,a"))]
13251   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13252    && FLOAT_MODE_P (GET_MODE (operands[3]))
13253    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13254    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13255    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13256    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13257   "#")
13259 (define_split
13260   [(set (pc)
13261         (if_then_else (match_operator 0 "comparison_operator"
13262                         [(match_operand 1 "register_operand" "")
13263                          (match_operand 2 "nonimmediate_operand" "")])
13264           (match_operand 3 "" "")
13265           (match_operand 4 "" "")))
13266    (clobber (reg:CCFP FPSR_REG))
13267    (clobber (reg:CCFP FLAGS_REG))]
13268   "reload_completed"
13269   [(const_int 0)]
13271   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13272                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13273   DONE;
13276 (define_split
13277   [(set (pc)
13278         (if_then_else (match_operator 0 "comparison_operator"
13279                         [(match_operand 1 "register_operand" "")
13280                          (match_operand 2 "general_operand" "")])
13281           (match_operand 3 "" "")
13282           (match_operand 4 "" "")))
13283    (clobber (reg:CCFP FPSR_REG))
13284    (clobber (reg:CCFP FLAGS_REG))
13285    (clobber (match_scratch:HI 5 "=a"))]
13286   "reload_completed"
13287   [(const_int 0)]
13289   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13290                         operands[3], operands[4], operands[5], NULL_RTX);
13291   DONE;
13294 (define_split
13295   [(set (pc)
13296         (if_then_else (match_operator 0 "comparison_operator"
13297                         [(match_operator 1 "float_operator"
13298                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13299                            (match_operand 3 "register_operand" "")])
13300           (match_operand 4 "" "")
13301           (match_operand 5 "" "")))
13302    (clobber (reg:CCFP FPSR_REG))
13303    (clobber (reg:CCFP FLAGS_REG))
13304    (clobber (match_scratch:HI 6 "=a"))]
13305   "reload_completed"
13306   [(const_int 0)]
13308   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13309   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13310                         operands[3], operands[7],
13311                         operands[4], operands[5], operands[6], NULL_RTX);
13312   DONE;
13315 ;; %%% Kill this when reload knows how to do it.
13316 (define_split
13317   [(set (pc)
13318         (if_then_else (match_operator 0 "comparison_operator"
13319                         [(match_operator 1 "float_operator"
13320                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13321                            (match_operand 3 "register_operand" "")])
13322           (match_operand 4 "" "")
13323           (match_operand 5 "" "")))
13324    (clobber (reg:CCFP FPSR_REG))
13325    (clobber (reg:CCFP FLAGS_REG))
13326    (clobber (match_scratch:HI 6 "=a"))]
13327   "reload_completed"
13328   [(const_int 0)]
13330   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13331   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13332   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13333                         operands[3], operands[7],
13334                         operands[4], operands[5], operands[6], operands[2]);
13335   DONE;
13338 ;; Unconditional and other jump instructions
13340 (define_insn "jump"
13341   [(set (pc)
13342         (label_ref (match_operand 0 "" "")))]
13343   ""
13344   "jmp\t%l0"
13345   [(set_attr "type" "ibr")
13346    (set (attr "length")
13347            (if_then_else (and (ge (minus (match_dup 0) (pc))
13348                                   (const_int -126))
13349                               (lt (minus (match_dup 0) (pc))
13350                                   (const_int 128)))
13351              (const_int 2)
13352              (const_int 5)))
13353    (set_attr "modrm" "0")])
13355 (define_expand "indirect_jump"
13356   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13357   ""
13358   "")
13360 (define_insn "*indirect_jump"
13361   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13362   "!TARGET_64BIT"
13363   "jmp\t%A0"
13364   [(set_attr "type" "ibr")
13365    (set_attr "length_immediate" "0")])
13367 (define_insn "*indirect_jump_rtx64"
13368   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13369   "TARGET_64BIT"
13370   "jmp\t%A0"
13371   [(set_attr "type" "ibr")
13372    (set_attr "length_immediate" "0")])
13374 (define_expand "tablejump"
13375   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13376               (use (label_ref (match_operand 1 "" "")))])]
13377   ""
13379   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13380      relative.  Convert the relative address to an absolute address.  */
13381   if (flag_pic)
13382     {
13383       rtx op0, op1;
13384       enum rtx_code code;
13386       if (TARGET_64BIT)
13387         {
13388           code = PLUS;
13389           op0 = operands[0];
13390           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13391         }
13392       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13393         {
13394           code = PLUS;
13395           op0 = operands[0];
13396           op1 = pic_offset_table_rtx;
13397         }
13398       else
13399         {
13400           code = MINUS;
13401           op0 = pic_offset_table_rtx;
13402           op1 = operands[0];
13403         }
13405       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13406                                          OPTAB_DIRECT);
13407     }
13410 (define_insn "*tablejump_1"
13411   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13412    (use (label_ref (match_operand 1 "" "")))]
13413   "!TARGET_64BIT"
13414   "jmp\t%A0"
13415   [(set_attr "type" "ibr")
13416    (set_attr "length_immediate" "0")])
13418 (define_insn "*tablejump_1_rtx64"
13419   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13420    (use (label_ref (match_operand 1 "" "")))]
13421   "TARGET_64BIT"
13422   "jmp\t%A0"
13423   [(set_attr "type" "ibr")
13424    (set_attr "length_immediate" "0")])
13426 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13428 (define_peephole2
13429   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13430    (set (match_operand:QI 1 "register_operand" "")
13431         (match_operator:QI 2 "ix86_comparison_operator"
13432           [(reg FLAGS_REG) (const_int 0)]))
13433    (set (match_operand 3 "q_regs_operand" "")
13434         (zero_extend (match_dup 1)))]
13435   "(peep2_reg_dead_p (3, operands[1])
13436     || operands_match_p (operands[1], operands[3]))
13437    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13438   [(set (match_dup 4) (match_dup 0))
13439    (set (strict_low_part (match_dup 5))
13440         (match_dup 2))]
13442   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13443   operands[5] = gen_lowpart (QImode, operands[3]);
13444   ix86_expand_clear (operands[3]);
13447 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13449 (define_peephole2
13450   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13451    (set (match_operand:QI 1 "register_operand" "")
13452         (match_operator:QI 2 "ix86_comparison_operator"
13453           [(reg FLAGS_REG) (const_int 0)]))
13454    (parallel [(set (match_operand 3 "q_regs_operand" "")
13455                    (zero_extend (match_dup 1)))
13456               (clobber (reg:CC FLAGS_REG))])]
13457   "(peep2_reg_dead_p (3, operands[1])
13458     || operands_match_p (operands[1], operands[3]))
13459    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13460   [(set (match_dup 4) (match_dup 0))
13461    (set (strict_low_part (match_dup 5))
13462         (match_dup 2))]
13464   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13465   operands[5] = gen_lowpart (QImode, operands[3]);
13466   ix86_expand_clear (operands[3]);
13469 ;; Call instructions.
13471 ;; The predicates normally associated with named expanders are not properly
13472 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13473 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13475 ;; Call subroutine returning no value.
13477 (define_expand "call_pop"
13478   [(parallel [(call (match_operand:QI 0 "" "")
13479                     (match_operand:SI 1 "" ""))
13480               (set (reg:SI SP_REG)
13481                    (plus:SI (reg:SI SP_REG)
13482                             (match_operand:SI 3 "" "")))])]
13483   "!TARGET_64BIT"
13485   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13486   DONE;
13489 (define_insn "*call_pop_0"
13490   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13491          (match_operand:SI 1 "" ""))
13492    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13493                             (match_operand:SI 2 "immediate_operand" "")))]
13494   "!TARGET_64BIT"
13496   if (SIBLING_CALL_P (insn))
13497     return "jmp\t%P0";
13498   else
13499     return "call\t%P0";
13501   [(set_attr "type" "call")])
13502   
13503 (define_insn "*call_pop_1"
13504   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13505          (match_operand:SI 1 "" ""))
13506    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13507                             (match_operand:SI 2 "immediate_operand" "i")))]
13508   "!TARGET_64BIT"
13510   if (constant_call_address_operand (operands[0], Pmode))
13511     {
13512       if (SIBLING_CALL_P (insn))
13513         return "jmp\t%P0";
13514       else
13515         return "call\t%P0";
13516     }
13517   if (SIBLING_CALL_P (insn))
13518     return "jmp\t%A0";
13519   else
13520     return "call\t%A0";
13522   [(set_attr "type" "call")])
13524 (define_expand "call"
13525   [(call (match_operand:QI 0 "" "")
13526          (match_operand 1 "" ""))
13527    (use (match_operand 2 "" ""))]
13528   ""
13530   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13531   DONE;
13534 (define_expand "sibcall"
13535   [(call (match_operand:QI 0 "" "")
13536          (match_operand 1 "" ""))
13537    (use (match_operand 2 "" ""))]
13538   ""
13540   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13541   DONE;
13544 (define_insn "*call_0"
13545   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13546          (match_operand 1 "" ""))]
13547   ""
13549   if (SIBLING_CALL_P (insn))
13550     return "jmp\t%P0";
13551   else
13552     return "call\t%P0";
13554   [(set_attr "type" "call")])
13556 (define_insn "*call_1"
13557   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13558          (match_operand 1 "" ""))]
13559   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13561   if (constant_call_address_operand (operands[0], Pmode))
13562     return "call\t%P0";
13563   return "call\t%A0";
13565   [(set_attr "type" "call")])
13567 (define_insn "*sibcall_1"
13568   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13569          (match_operand 1 "" ""))]
13570   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13572   if (constant_call_address_operand (operands[0], Pmode))
13573     return "jmp\t%P0";
13574   return "jmp\t%A0";
13576   [(set_attr "type" "call")])
13578 (define_insn "*call_1_rex64"
13579   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13580          (match_operand 1 "" ""))]
13581   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13583   if (constant_call_address_operand (operands[0], Pmode))
13584     return "call\t%P0";
13585   return "call\t%A0";
13587   [(set_attr "type" "call")])
13589 (define_insn "*sibcall_1_rex64"
13590   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13591          (match_operand 1 "" ""))]
13592   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13593   "jmp\t%P0"
13594   [(set_attr "type" "call")])
13596 (define_insn "*sibcall_1_rex64_v"
13597   [(call (mem:QI (reg:DI 40))
13598          (match_operand 0 "" ""))]
13599   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13600   "jmp\t*%%r11"
13601   [(set_attr "type" "call")])
13604 ;; Call subroutine, returning value in operand 0
13606 (define_expand "call_value_pop"
13607   [(parallel [(set (match_operand 0 "" "")
13608                    (call (match_operand:QI 1 "" "")
13609                          (match_operand:SI 2 "" "")))
13610               (set (reg:SI SP_REG)
13611                    (plus:SI (reg:SI SP_REG)
13612                             (match_operand:SI 4 "" "")))])]
13613   "!TARGET_64BIT"
13615   ix86_expand_call (operands[0], operands[1], operands[2],
13616                     operands[3], operands[4], 0);
13617   DONE;
13620 (define_expand "call_value"
13621   [(set (match_operand 0 "" "")
13622         (call (match_operand:QI 1 "" "")
13623               (match_operand:SI 2 "" "")))
13624    (use (match_operand:SI 3 "" ""))]
13625   ;; Operand 2 not used on the i386.
13626   ""
13628   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13629   DONE;
13632 (define_expand "sibcall_value"
13633   [(set (match_operand 0 "" "")
13634         (call (match_operand:QI 1 "" "")
13635               (match_operand:SI 2 "" "")))
13636    (use (match_operand:SI 3 "" ""))]
13637   ;; Operand 2 not used on the i386.
13638   ""
13640   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13641   DONE;
13644 ;; Call subroutine returning any type.
13646 (define_expand "untyped_call"
13647   [(parallel [(call (match_operand 0 "" "")
13648                     (const_int 0))
13649               (match_operand 1 "" "")
13650               (match_operand 2 "" "")])]
13651   ""
13653   int i;
13655   /* In order to give reg-stack an easier job in validating two
13656      coprocessor registers as containing a possible return value,
13657      simply pretend the untyped call returns a complex long double
13658      value.  */
13660   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13661                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13662                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13663                     NULL, 0);
13665   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13666     {
13667       rtx set = XVECEXP (operands[2], 0, i);
13668       emit_move_insn (SET_DEST (set), SET_SRC (set));
13669     }
13671   /* The optimizer does not know that the call sets the function value
13672      registers we stored in the result block.  We avoid problems by
13673      claiming that all hard registers are used and clobbered at this
13674      point.  */
13675   emit_insn (gen_blockage (const0_rtx));
13677   DONE;
13680 ;; Prologue and epilogue instructions
13682 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13683 ;; all of memory.  This blocks insns from being moved across this point.
13685 (define_insn "blockage"
13686   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13687   ""
13688   ""
13689   [(set_attr "length" "0")])
13691 ;; Insn emitted into the body of a function to return from a function.
13692 ;; This is only done if the function's epilogue is known to be simple.
13693 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13695 (define_expand "return"
13696   [(return)]
13697   "ix86_can_use_return_insn_p ()"
13699   if (current_function_pops_args)
13700     {
13701       rtx popc = GEN_INT (current_function_pops_args);
13702       emit_jump_insn (gen_return_pop_internal (popc));
13703       DONE;
13704     }
13707 (define_insn "return_internal"
13708   [(return)]
13709   "reload_completed"
13710   "ret"
13711   [(set_attr "length" "1")
13712    (set_attr "length_immediate" "0")
13713    (set_attr "modrm" "0")])
13715 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13716 ;; instruction Athlon and K8 have.
13718 (define_insn "return_internal_long"
13719   [(return)
13720    (unspec [(const_int 0)] UNSPEC_REP)]
13721   "reload_completed"
13722   "rep {;} ret"
13723   [(set_attr "length" "1")
13724    (set_attr "length_immediate" "0")
13725    (set_attr "prefix_rep" "1")
13726    (set_attr "modrm" "0")])
13728 (define_insn "return_pop_internal"
13729   [(return)
13730    (use (match_operand:SI 0 "const_int_operand" ""))]
13731   "reload_completed"
13732   "ret\t%0"
13733   [(set_attr "length" "3")
13734    (set_attr "length_immediate" "2")
13735    (set_attr "modrm" "0")])
13737 (define_insn "return_indirect_internal"
13738   [(return)
13739    (use (match_operand:SI 0 "register_operand" "r"))]
13740   "reload_completed"
13741   "jmp\t%A0"
13742   [(set_attr "type" "ibr")
13743    (set_attr "length_immediate" "0")])
13745 (define_insn "nop"
13746   [(const_int 0)]
13747   ""
13748   "nop"
13749   [(set_attr "length" "1")
13750    (set_attr "length_immediate" "0")
13751    (set_attr "modrm" "0")])
13753 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13754 ;; branch prediction penalty for the third jump in a 16-byte
13755 ;; block on K8.
13757 (define_insn "align"
13758   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13759   ""
13761 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13762   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13763 #else
13764   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13765      The align insn is used to avoid 3 jump instructions in the row to improve
13766      branch prediction and the benefits hardly outweight the cost of extra 8
13767      nops on the average inserted by full alignment pseudo operation.  */
13768 #endif
13769   return "";
13771   [(set_attr "length" "16")])
13773 (define_expand "prologue"
13774   [(const_int 1)]
13775   ""
13776   "ix86_expand_prologue (); DONE;")
13778 (define_insn "set_got"
13779   [(set (match_operand:SI 0 "register_operand" "=r")
13780         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13781    (clobber (reg:CC FLAGS_REG))]
13782   "!TARGET_64BIT"
13783   { return output_set_got (operands[0]); }
13784   [(set_attr "type" "multi")
13785    (set_attr "length" "12")])
13787 (define_insn "set_got_rex64"
13788   [(set (match_operand:DI 0 "register_operand" "=r")
13789         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13790   "TARGET_64BIT"
13791   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13792   [(set_attr "type" "lea")
13793    (set_attr "length" "6")])
13795 (define_expand "epilogue"
13796   [(const_int 1)]
13797   ""
13798   "ix86_expand_epilogue (1); DONE;")
13800 (define_expand "sibcall_epilogue"
13801   [(const_int 1)]
13802   ""
13803   "ix86_expand_epilogue (0); DONE;")
13805 (define_expand "eh_return"
13806   [(use (match_operand 0 "register_operand" ""))]
13807   ""
13809   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13811   /* Tricky bit: we write the address of the handler to which we will
13812      be returning into someone else's stack frame, one word below the
13813      stack address we wish to restore.  */
13814   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13815   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13816   tmp = gen_rtx_MEM (Pmode, tmp);
13817   emit_move_insn (tmp, ra);
13819   if (Pmode == SImode)
13820     emit_jump_insn (gen_eh_return_si (sa));
13821   else
13822     emit_jump_insn (gen_eh_return_di (sa));
13823   emit_barrier ();
13824   DONE;
13827 (define_insn_and_split "eh_return_si"
13828   [(set (pc) 
13829         (unspec [(match_operand:SI 0 "register_operand" "c")]
13830                  UNSPEC_EH_RETURN))]
13831   "!TARGET_64BIT"
13832   "#"
13833   "reload_completed"
13834   [(const_int 1)]
13835   "ix86_expand_epilogue (2); DONE;")
13837 (define_insn_and_split "eh_return_di"
13838   [(set (pc) 
13839         (unspec [(match_operand:DI 0 "register_operand" "c")]
13840                  UNSPEC_EH_RETURN))]
13841   "TARGET_64BIT"
13842   "#"
13843   "reload_completed"
13844   [(const_int 1)]
13845   "ix86_expand_epilogue (2); DONE;")
13847 (define_insn "leave"
13848   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13849    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13850    (clobber (mem:BLK (scratch)))]
13851   "!TARGET_64BIT"
13852   "leave"
13853   [(set_attr "type" "leave")])
13855 (define_insn "leave_rex64"
13856   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13857    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13858    (clobber (mem:BLK (scratch)))]
13859   "TARGET_64BIT"
13860   "leave"
13861   [(set_attr "type" "leave")])
13863 (define_expand "ffssi2"
13864   [(parallel
13865      [(set (match_operand:SI 0 "register_operand" "") 
13866            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13867       (clobber (match_scratch:SI 2 ""))
13868       (clobber (reg:CC FLAGS_REG))])]
13869   ""
13870   "")
13872 (define_insn_and_split "*ffs_cmove"
13873   [(set (match_operand:SI 0 "register_operand" "=r") 
13874         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13875    (clobber (match_scratch:SI 2 "=&r"))
13876    (clobber (reg:CC FLAGS_REG))]
13877   "TARGET_CMOVE"
13878   "#"
13879   "&& reload_completed"
13880   [(set (match_dup 2) (const_int -1))
13881    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13882               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13883    (set (match_dup 0) (if_then_else:SI
13884                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13885                         (match_dup 2)
13886                         (match_dup 0)))
13887    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13888               (clobber (reg:CC FLAGS_REG))])]
13889   "")
13891 (define_insn_and_split "*ffs_no_cmove"
13892   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13893         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13894    (clobber (match_scratch:SI 2 "=&q"))
13895    (clobber (reg:CC FLAGS_REG))]
13896   ""
13897   "#"
13898   "reload_completed"
13899   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13900               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13901    (set (strict_low_part (match_dup 3))
13902         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13903    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13904               (clobber (reg:CC FLAGS_REG))])
13905    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13906               (clobber (reg:CC FLAGS_REG))])
13907    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13908               (clobber (reg:CC FLAGS_REG))])]
13910   operands[3] = gen_lowpart (QImode, operands[2]);
13911   ix86_expand_clear (operands[2]);
13914 (define_insn "*ffssi_1"
13915   [(set (reg:CCZ FLAGS_REG)
13916         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13917                      (const_int 0)))
13918    (set (match_operand:SI 0 "register_operand" "=r")
13919         (ctz:SI (match_dup 1)))]
13920   ""
13921   "bsf{l}\t{%1, %0|%0, %1}"
13922   [(set_attr "prefix_0f" "1")])
13924 (define_expand "ffsdi2"
13925   [(parallel
13926      [(set (match_operand:DI 0 "register_operand" "") 
13927            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13928       (clobber (match_scratch:DI 2 ""))
13929       (clobber (reg:CC FLAGS_REG))])]
13930   "TARGET_64BIT && TARGET_CMOVE"
13931   "")
13933 (define_insn_and_split "*ffs_rex64"
13934   [(set (match_operand:DI 0 "register_operand" "=r") 
13935         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13936    (clobber (match_scratch:DI 2 "=&r"))
13937    (clobber (reg:CC FLAGS_REG))]
13938   "TARGET_64BIT && TARGET_CMOVE"
13939   "#"
13940   "&& reload_completed"
13941   [(set (match_dup 2) (const_int -1))
13942    (parallel [(set (reg:CCZ FLAGS_REG)
13943                    (compare:CCZ (match_dup 1) (const_int 0)))
13944               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13945    (set (match_dup 0) (if_then_else:DI
13946                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13947                         (match_dup 2)
13948                         (match_dup 0)))
13949    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13950               (clobber (reg:CC FLAGS_REG))])]
13951   "")
13953 (define_insn "*ffsdi_1"
13954   [(set (reg:CCZ FLAGS_REG)
13955         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13956                      (const_int 0)))
13957    (set (match_operand:DI 0 "register_operand" "=r")
13958         (ctz:DI (match_dup 1)))]
13959   "TARGET_64BIT"
13960   "bsf{q}\t{%1, %0|%0, %1}"
13961   [(set_attr "prefix_0f" "1")])
13963 (define_insn "ctzsi2"
13964   [(set (match_operand:SI 0 "register_operand" "=r")
13965         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13966    (clobber (reg:CC FLAGS_REG))]
13967   ""
13968   "bsf{l}\t{%1, %0|%0, %1}"
13969   [(set_attr "prefix_0f" "1")])
13971 (define_insn "ctzdi2"
13972   [(set (match_operand:DI 0 "register_operand" "=r")
13973         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13974    (clobber (reg:CC FLAGS_REG))]
13975   "TARGET_64BIT"
13976   "bsf{q}\t{%1, %0|%0, %1}"
13977   [(set_attr "prefix_0f" "1")])
13979 (define_expand "clzsi2"
13980   [(parallel
13981      [(set (match_operand:SI 0 "register_operand" "")
13982            (minus:SI (const_int 31)
13983                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13984       (clobber (reg:CC FLAGS_REG))])
13985    (parallel
13986      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13987       (clobber (reg:CC FLAGS_REG))])]
13988   ""
13989   "")
13991 (define_insn "*bsr"
13992   [(set (match_operand:SI 0 "register_operand" "=r")
13993         (minus:SI (const_int 31)
13994                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13995    (clobber (reg:CC FLAGS_REG))]
13996   ""
13997   "bsr{l}\t{%1, %0|%0, %1}"
13998   [(set_attr "prefix_0f" "1")])
14000 (define_expand "clzdi2"
14001   [(parallel
14002      [(set (match_operand:DI 0 "register_operand" "")
14003            (minus:DI (const_int 63)
14004                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14005       (clobber (reg:CC FLAGS_REG))])
14006    (parallel
14007      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14008       (clobber (reg:CC FLAGS_REG))])]
14009   "TARGET_64BIT"
14010   "")
14012 (define_insn "*bsr_rex64"
14013   [(set (match_operand:DI 0 "register_operand" "=r")
14014         (minus:DI (const_int 63)
14015                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14016    (clobber (reg:CC FLAGS_REG))]
14017   "TARGET_64BIT"
14018   "bsr{q}\t{%1, %0|%0, %1}"
14019   [(set_attr "prefix_0f" "1")])
14021 ;; Thread-local storage patterns for ELF.
14023 ;; Note that these code sequences must appear exactly as shown
14024 ;; in order to allow linker relaxation.
14026 (define_insn "*tls_global_dynamic_32_gnu"
14027   [(set (match_operand:SI 0 "register_operand" "=a")
14028         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14029                     (match_operand:SI 2 "tls_symbolic_operand" "")
14030                     (match_operand:SI 3 "call_insn_operand" "")]
14031                     UNSPEC_TLS_GD))
14032    (clobber (match_scratch:SI 4 "=d"))
14033    (clobber (match_scratch:SI 5 "=c"))
14034    (clobber (reg:CC FLAGS_REG))]
14035   "!TARGET_64BIT && TARGET_GNU_TLS"
14036   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14037   [(set_attr "type" "multi")
14038    (set_attr "length" "12")])
14040 (define_insn "*tls_global_dynamic_32_sun"
14041   [(set (match_operand:SI 0 "register_operand" "=a")
14042         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14043                     (match_operand:SI 2 "tls_symbolic_operand" "")
14044                     (match_operand:SI 3 "call_insn_operand" "")]
14045                     UNSPEC_TLS_GD))
14046    (clobber (match_scratch:SI 4 "=d"))
14047    (clobber (match_scratch:SI 5 "=c"))
14048    (clobber (reg:CC FLAGS_REG))]
14049   "!TARGET_64BIT && TARGET_SUN_TLS"
14050   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14051         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14052   [(set_attr "type" "multi")
14053    (set_attr "length" "14")])
14055 (define_expand "tls_global_dynamic_32"
14056   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14057                    (unspec:SI
14058                     [(match_dup 2)
14059                      (match_operand:SI 1 "tls_symbolic_operand" "")
14060                      (match_dup 3)]
14061                     UNSPEC_TLS_GD))
14062               (clobber (match_scratch:SI 4 ""))
14063               (clobber (match_scratch:SI 5 ""))
14064               (clobber (reg:CC FLAGS_REG))])]
14065   ""
14067   if (flag_pic)
14068     operands[2] = pic_offset_table_rtx;
14069   else
14070     {
14071       operands[2] = gen_reg_rtx (Pmode);
14072       emit_insn (gen_set_got (operands[2]));
14073     }
14074   operands[3] = ix86_tls_get_addr ();
14077 (define_insn "*tls_global_dynamic_64"
14078   [(set (match_operand:DI 0 "register_operand" "=a")
14079         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14080                  (match_operand:DI 3 "" "")))
14081    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14082               UNSPEC_TLS_GD)]
14083   "TARGET_64BIT"
14084   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14085   [(set_attr "type" "multi")
14086    (set_attr "length" "16")])
14088 (define_expand "tls_global_dynamic_64"
14089   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14090                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14091               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14092                          UNSPEC_TLS_GD)])]
14093   ""
14095   operands[2] = ix86_tls_get_addr ();
14098 (define_insn "*tls_local_dynamic_base_32_gnu"
14099   [(set (match_operand:SI 0 "register_operand" "=a")
14100         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14101                     (match_operand:SI 2 "call_insn_operand" "")]
14102                    UNSPEC_TLS_LD_BASE))
14103    (clobber (match_scratch:SI 3 "=d"))
14104    (clobber (match_scratch:SI 4 "=c"))
14105    (clobber (reg:CC FLAGS_REG))]
14106   "!TARGET_64BIT && TARGET_GNU_TLS"
14107   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14108   [(set_attr "type" "multi")
14109    (set_attr "length" "11")])
14111 (define_insn "*tls_local_dynamic_base_32_sun"
14112   [(set (match_operand:SI 0 "register_operand" "=a")
14113         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14114                     (match_operand:SI 2 "call_insn_operand" "")]
14115                    UNSPEC_TLS_LD_BASE))
14116    (clobber (match_scratch:SI 3 "=d"))
14117    (clobber (match_scratch:SI 4 "=c"))
14118    (clobber (reg:CC FLAGS_REG))]
14119   "!TARGET_64BIT && TARGET_SUN_TLS"
14120   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14121         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14122   [(set_attr "type" "multi")
14123    (set_attr "length" "13")])
14125 (define_expand "tls_local_dynamic_base_32"
14126   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14127                    (unspec:SI [(match_dup 1) (match_dup 2)]
14128                               UNSPEC_TLS_LD_BASE))
14129               (clobber (match_scratch:SI 3 ""))
14130               (clobber (match_scratch:SI 4 ""))
14131               (clobber (reg:CC FLAGS_REG))])]
14132   ""
14134   if (flag_pic)
14135     operands[1] = pic_offset_table_rtx;
14136   else
14137     {
14138       operands[1] = gen_reg_rtx (Pmode);
14139       emit_insn (gen_set_got (operands[1]));
14140     }
14141   operands[2] = ix86_tls_get_addr ();
14144 (define_insn "*tls_local_dynamic_base_64"
14145   [(set (match_operand:DI 0 "register_operand" "=a")
14146         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14147                  (match_operand:DI 2 "" "")))
14148    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14149   "TARGET_64BIT"
14150   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14151   [(set_attr "type" "multi")
14152    (set_attr "length" "12")])
14154 (define_expand "tls_local_dynamic_base_64"
14155   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14156                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14157               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14158   ""
14160   operands[1] = ix86_tls_get_addr ();
14163 ;; Local dynamic of a single variable is a lose.  Show combine how
14164 ;; to convert that back to global dynamic.
14166 (define_insn_and_split "*tls_local_dynamic_32_once"
14167   [(set (match_operand:SI 0 "register_operand" "=a")
14168         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14169                              (match_operand:SI 2 "call_insn_operand" "")]
14170                             UNSPEC_TLS_LD_BASE)
14171                  (const:SI (unspec:SI
14172                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14173                             UNSPEC_DTPOFF))))
14174    (clobber (match_scratch:SI 4 "=d"))
14175    (clobber (match_scratch:SI 5 "=c"))
14176    (clobber (reg:CC FLAGS_REG))]
14177   ""
14178   "#"
14179   ""
14180   [(parallel [(set (match_dup 0)
14181                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14182                               UNSPEC_TLS_GD))
14183               (clobber (match_dup 4))
14184               (clobber (match_dup 5))
14185               (clobber (reg:CC FLAGS_REG))])]
14186   "")
14188 ;; Load and add the thread base pointer from %gs:0.
14190 (define_insn "*load_tp_si"
14191   [(set (match_operand:SI 0 "register_operand" "=r")
14192         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14193   "!TARGET_64BIT"
14194   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14195   [(set_attr "type" "imov")
14196    (set_attr "modrm" "0")
14197    (set_attr "length" "7")
14198    (set_attr "memory" "load")
14199    (set_attr "imm_disp" "false")])
14201 (define_insn "*add_tp_si"
14202   [(set (match_operand:SI 0 "register_operand" "=r")
14203         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14204                  (match_operand:SI 1 "register_operand" "0")))
14205    (clobber (reg:CC FLAGS_REG))]
14206   "!TARGET_64BIT"
14207   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14208   [(set_attr "type" "alu")
14209    (set_attr "modrm" "0")
14210    (set_attr "length" "7")
14211    (set_attr "memory" "load")
14212    (set_attr "imm_disp" "false")])
14214 (define_insn "*load_tp_di"
14215   [(set (match_operand:DI 0 "register_operand" "=r")
14216         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14217   "TARGET_64BIT"
14218   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14219   [(set_attr "type" "imov")
14220    (set_attr "modrm" "0")
14221    (set_attr "length" "7")
14222    (set_attr "memory" "load")
14223    (set_attr "imm_disp" "false")])
14225 (define_insn "*add_tp_di"
14226   [(set (match_operand:DI 0 "register_operand" "=r")
14227         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14228                  (match_operand:DI 1 "register_operand" "0")))
14229    (clobber (reg:CC FLAGS_REG))]
14230   "TARGET_64BIT"
14231   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14232   [(set_attr "type" "alu")
14233    (set_attr "modrm" "0")
14234    (set_attr "length" "7")
14235    (set_attr "memory" "load")
14236    (set_attr "imm_disp" "false")])
14238 ;; These patterns match the binary 387 instructions for addM3, subM3,
14239 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14240 ;; SFmode.  The first is the normal insn, the second the same insn but
14241 ;; with one operand a conversion, and the third the same insn but with
14242 ;; the other operand a conversion.  The conversion may be SFmode or
14243 ;; SImode if the target mode DFmode, but only SImode if the target mode
14244 ;; is SFmode.
14246 ;; Gcc is slightly more smart about handling normal two address instructions
14247 ;; so use special patterns for add and mull.
14249 (define_insn "*fop_sf_comm_mixed"
14250   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14251         (match_operator:SF 3 "binary_fp_operator"
14252                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14253                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14254   "TARGET_MIX_SSE_I387
14255    && COMMUTATIVE_ARITH_P (operands[3])
14256    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14257   "* return output_387_binary_op (insn, operands);"
14258   [(set (attr "type") 
14259         (if_then_else (eq_attr "alternative" "1")
14260            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14261               (const_string "ssemul")
14262               (const_string "sseadd"))
14263            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14264               (const_string "fmul")
14265               (const_string "fop"))))
14266    (set_attr "mode" "SF")])
14268 (define_insn "*fop_sf_comm_sse"
14269   [(set (match_operand:SF 0 "register_operand" "=x")
14270         (match_operator:SF 3 "binary_fp_operator"
14271                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14272                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14273   "TARGET_SSE_MATH
14274    && COMMUTATIVE_ARITH_P (operands[3])
14275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14276   "* return output_387_binary_op (insn, operands);"
14277   [(set (attr "type") 
14278         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14279            (const_string "ssemul")
14280            (const_string "sseadd")))
14281    (set_attr "mode" "SF")])
14283 (define_insn "*fop_sf_comm_i387"
14284   [(set (match_operand:SF 0 "register_operand" "=f")
14285         (match_operator:SF 3 "binary_fp_operator"
14286                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14287                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14288   "TARGET_80387
14289    && COMMUTATIVE_ARITH_P (operands[3])
14290    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14291   "* return output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14294            (const_string "fmul")
14295            (const_string "fop")))
14296    (set_attr "mode" "SF")])
14298 (define_insn "*fop_sf_1_mixed"
14299   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14300         (match_operator:SF 3 "binary_fp_operator"
14301                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14302                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14303   "TARGET_MIX_SSE_I387
14304    && !COMMUTATIVE_ARITH_P (operands[3])
14305    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14306   "* return output_387_binary_op (insn, operands);"
14307   [(set (attr "type") 
14308         (cond [(and (eq_attr "alternative" "2")
14309                     (match_operand:SF 3 "mult_operator" ""))
14310                  (const_string "ssemul")
14311                (and (eq_attr "alternative" "2")
14312                     (match_operand:SF 3 "div_operator" ""))
14313                  (const_string "ssediv")
14314                (eq_attr "alternative" "2")
14315                  (const_string "sseadd")
14316                (match_operand:SF 3 "mult_operator" "") 
14317                  (const_string "fmul")
14318                (match_operand:SF 3 "div_operator" "") 
14319                  (const_string "fdiv")
14320               ]
14321               (const_string "fop")))
14322    (set_attr "mode" "SF")])
14324 (define_insn "*fop_sf_1_sse"
14325   [(set (match_operand:SF 0 "register_operand" "=x")
14326         (match_operator:SF 3 "binary_fp_operator"
14327                         [(match_operand:SF 1 "register_operand" "0")
14328                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14329   "TARGET_SSE_MATH
14330    && !COMMUTATIVE_ARITH_P (operands[3])"
14331   "* return output_387_binary_op (insn, operands);"
14332   [(set (attr "type") 
14333         (cond [(match_operand:SF 3 "mult_operator" "")
14334                  (const_string "ssemul")
14335                (match_operand:SF 3 "div_operator" "")
14336                  (const_string "ssediv")
14337               ]
14338               (const_string "sseadd")))
14339    (set_attr "mode" "SF")])
14341 ;; This pattern is not fully shadowed by the pattern above.
14342 (define_insn "*fop_sf_1_i387"
14343   [(set (match_operand:SF 0 "register_operand" "=f,f")
14344         (match_operator:SF 3 "binary_fp_operator"
14345                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14346                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14347   "TARGET_80387 && !TARGET_SSE_MATH
14348    && !COMMUTATIVE_ARITH_P (operands[3])
14349    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14350   "* return output_387_binary_op (insn, operands);"
14351   [(set (attr "type") 
14352         (cond [(match_operand:SF 3 "mult_operator" "") 
14353                  (const_string "fmul")
14354                (match_operand:SF 3 "div_operator" "") 
14355                  (const_string "fdiv")
14356               ]
14357               (const_string "fop")))
14358    (set_attr "mode" "SF")])
14360 ;; ??? Add SSE splitters for these!
14361 (define_insn "*fop_sf_2<mode>_i387"
14362   [(set (match_operand:SF 0 "register_operand" "=f,f")
14363         (match_operator:SF 3 "binary_fp_operator"
14364           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14365            (match_operand:SF 2 "register_operand" "0,0")]))]
14366   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14367   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14368   [(set (attr "type") 
14369         (cond [(match_operand:SF 3 "mult_operator" "") 
14370                  (const_string "fmul")
14371                (match_operand:SF 3 "div_operator" "") 
14372                  (const_string "fdiv")
14373               ]
14374               (const_string "fop")))
14375    (set_attr "fp_int_src" "true")
14376    (set_attr "mode" "<MODE>")])
14378 (define_insn "*fop_sf_3<mode>_i387"
14379   [(set (match_operand:SF 0 "register_operand" "=f,f")
14380         (match_operator:SF 3 "binary_fp_operator"
14381           [(match_operand:SF 1 "register_operand" "0,0")
14382            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14383   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14384   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14385   [(set (attr "type") 
14386         (cond [(match_operand:SF 3 "mult_operator" "") 
14387                  (const_string "fmul")
14388                (match_operand:SF 3 "div_operator" "") 
14389                  (const_string "fdiv")
14390               ]
14391               (const_string "fop")))
14392    (set_attr "fp_int_src" "true")
14393    (set_attr "mode" "<MODE>")])
14395 (define_insn "*fop_df_comm_mixed"
14396   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14397         (match_operator:DF 3 "binary_fp_operator"
14398                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14399                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14400   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14401    && COMMUTATIVE_ARITH_P (operands[3])
14402    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14403   "* return output_387_binary_op (insn, operands);"
14404   [(set (attr "type") 
14405         (if_then_else (eq_attr "alternative" "1")
14406            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14407               (const_string "ssemul")
14408               (const_string "sseadd"))
14409            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14410               (const_string "fmul")
14411               (const_string "fop"))))
14412    (set_attr "mode" "DF")])
14414 (define_insn "*fop_df_comm_sse"
14415   [(set (match_operand:DF 0 "register_operand" "=Y")
14416         (match_operator:DF 3 "binary_fp_operator"
14417                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14418                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14419   "TARGET_SSE2 && TARGET_SSE_MATH
14420    && COMMUTATIVE_ARITH_P (operands[3])
14421    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422   "* return output_387_binary_op (insn, operands);"
14423   [(set (attr "type") 
14424         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14425            (const_string "ssemul")
14426            (const_string "sseadd")))
14427    (set_attr "mode" "DF")])
14429 (define_insn "*fop_df_comm_i387"
14430   [(set (match_operand:DF 0 "register_operand" "=f")
14431         (match_operator:DF 3 "binary_fp_operator"
14432                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14433                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14434   "TARGET_80387
14435    && COMMUTATIVE_ARITH_P (operands[3])
14436    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14437   "* return output_387_binary_op (insn, operands);"
14438   [(set (attr "type") 
14439         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14440            (const_string "fmul")
14441            (const_string "fop")))
14442    (set_attr "mode" "DF")])
14444 (define_insn "*fop_df_1_mixed"
14445   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14446         (match_operator:DF 3 "binary_fp_operator"
14447                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14448                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14449   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14450    && !COMMUTATIVE_ARITH_P (operands[3])
14451    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14452   "* return output_387_binary_op (insn, operands);"
14453   [(set (attr "type") 
14454         (cond [(and (eq_attr "alternative" "2")
14455                     (match_operand:SF 3 "mult_operator" ""))
14456                  (const_string "ssemul")
14457                (and (eq_attr "alternative" "2")
14458                     (match_operand:SF 3 "div_operator" ""))
14459                  (const_string "ssediv")
14460                (eq_attr "alternative" "2")
14461                  (const_string "sseadd")
14462                (match_operand:DF 3 "mult_operator" "") 
14463                  (const_string "fmul")
14464                (match_operand:DF 3 "div_operator" "") 
14465                  (const_string "fdiv")
14466               ]
14467               (const_string "fop")))
14468    (set_attr "mode" "DF")])
14470 (define_insn "*fop_df_1_sse"
14471   [(set (match_operand:DF 0 "register_operand" "=Y")
14472         (match_operator:DF 3 "binary_fp_operator"
14473                         [(match_operand:DF 1 "register_operand" "0")
14474                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14475   "TARGET_SSE2 && TARGET_SSE_MATH
14476    && !COMMUTATIVE_ARITH_P (operands[3])"
14477   "* return output_387_binary_op (insn, operands);"
14478   [(set_attr "mode" "DF")
14479    (set (attr "type") 
14480         (cond [(match_operand:SF 3 "mult_operator" "")
14481                  (const_string "ssemul")
14482                (match_operand:SF 3 "div_operator" "")
14483                  (const_string "ssediv")
14484               ]
14485               (const_string "sseadd")))])
14487 ;; This pattern is not fully shadowed by the pattern above.
14488 (define_insn "*fop_df_1_i387"
14489   [(set (match_operand:DF 0 "register_operand" "=f,f")
14490         (match_operator:DF 3 "binary_fp_operator"
14491                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14492                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14493   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14494    && !COMMUTATIVE_ARITH_P (operands[3])
14495    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14496   "* return output_387_binary_op (insn, operands);"
14497   [(set (attr "type") 
14498         (cond [(match_operand:DF 3 "mult_operator" "") 
14499                  (const_string "fmul")
14500                (match_operand:DF 3 "div_operator" "")
14501                  (const_string "fdiv")
14502               ]
14503               (const_string "fop")))
14504    (set_attr "mode" "DF")])
14506 ;; ??? Add SSE splitters for these!
14507 (define_insn "*fop_df_2<mode>_i387"
14508   [(set (match_operand:DF 0 "register_operand" "=f,f")
14509         (match_operator:DF 3 "binary_fp_operator"
14510            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14511             (match_operand:DF 2 "register_operand" "0,0")]))]
14512   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14513    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14514   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14515   [(set (attr "type") 
14516         (cond [(match_operand:DF 3 "mult_operator" "") 
14517                  (const_string "fmul")
14518                (match_operand:DF 3 "div_operator" "") 
14519                  (const_string "fdiv")
14520               ]
14521               (const_string "fop")))
14522    (set_attr "fp_int_src" "true")
14523    (set_attr "mode" "<MODE>")])
14525 (define_insn "*fop_df_3<mode>_i387"
14526   [(set (match_operand:DF 0 "register_operand" "=f,f")
14527         (match_operator:DF 3 "binary_fp_operator"
14528            [(match_operand:DF 1 "register_operand" "0,0")
14529             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14530   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14531    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14533   [(set (attr "type") 
14534         (cond [(match_operand:DF 3 "mult_operator" "") 
14535                  (const_string "fmul")
14536                (match_operand:DF 3 "div_operator" "") 
14537                  (const_string "fdiv")
14538               ]
14539               (const_string "fop")))
14540    (set_attr "fp_int_src" "true")
14541    (set_attr "mode" "<MODE>")])
14543 (define_insn "*fop_df_4_i387"
14544   [(set (match_operand:DF 0 "register_operand" "=f,f")
14545         (match_operator:DF 3 "binary_fp_operator"
14546            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14547             (match_operand:DF 2 "register_operand" "0,f")]))]
14548   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14549    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550   "* return output_387_binary_op (insn, operands);"
14551   [(set (attr "type") 
14552         (cond [(match_operand:DF 3 "mult_operator" "") 
14553                  (const_string "fmul")
14554                (match_operand:DF 3 "div_operator" "") 
14555                  (const_string "fdiv")
14556               ]
14557               (const_string "fop")))
14558    (set_attr "mode" "SF")])
14560 (define_insn "*fop_df_5_i387"
14561   [(set (match_operand:DF 0 "register_operand" "=f,f")
14562         (match_operator:DF 3 "binary_fp_operator"
14563           [(match_operand:DF 1 "register_operand" "0,f")
14564            (float_extend:DF
14565             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14566   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14567   "* return output_387_binary_op (insn, operands);"
14568   [(set (attr "type") 
14569         (cond [(match_operand:DF 3 "mult_operator" "") 
14570                  (const_string "fmul")
14571                (match_operand:DF 3 "div_operator" "") 
14572                  (const_string "fdiv")
14573               ]
14574               (const_string "fop")))
14575    (set_attr "mode" "SF")])
14577 (define_insn "*fop_df_6_i387"
14578   [(set (match_operand:DF 0 "register_operand" "=f,f")
14579         (match_operator:DF 3 "binary_fp_operator"
14580           [(float_extend:DF
14581             (match_operand:SF 1 "register_operand" "0,f"))
14582            (float_extend:DF
14583             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14584   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14585   "* return output_387_binary_op (insn, operands);"
14586   [(set (attr "type") 
14587         (cond [(match_operand:DF 3 "mult_operator" "") 
14588                  (const_string "fmul")
14589                (match_operand:DF 3 "div_operator" "") 
14590                  (const_string "fdiv")
14591               ]
14592               (const_string "fop")))
14593    (set_attr "mode" "SF")])
14595 (define_insn "*fop_xf_comm_i387"
14596   [(set (match_operand:XF 0 "register_operand" "=f")
14597         (match_operator:XF 3 "binary_fp_operator"
14598                         [(match_operand:XF 1 "register_operand" "%0")
14599                          (match_operand:XF 2 "register_operand" "f")]))]
14600   "TARGET_80387
14601    && COMMUTATIVE_ARITH_P (operands[3])"
14602   "* return output_387_binary_op (insn, operands);"
14603   [(set (attr "type") 
14604         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14605            (const_string "fmul")
14606            (const_string "fop")))
14607    (set_attr "mode" "XF")])
14609 (define_insn "*fop_xf_1_i387"
14610   [(set (match_operand:XF 0 "register_operand" "=f,f")
14611         (match_operator:XF 3 "binary_fp_operator"
14612                         [(match_operand:XF 1 "register_operand" "0,f")
14613                          (match_operand:XF 2 "register_operand" "f,0")]))]
14614   "TARGET_80387
14615    && !COMMUTATIVE_ARITH_P (operands[3])"
14616   "* return output_387_binary_op (insn, operands);"
14617   [(set (attr "type") 
14618         (cond [(match_operand:XF 3 "mult_operator" "") 
14619                  (const_string "fmul")
14620                (match_operand:XF 3 "div_operator" "") 
14621                  (const_string "fdiv")
14622               ]
14623               (const_string "fop")))
14624    (set_attr "mode" "XF")])
14626 (define_insn "*fop_xf_2<mode>_i387"
14627   [(set (match_operand:XF 0 "register_operand" "=f,f")
14628         (match_operator:XF 3 "binary_fp_operator"
14629            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14630             (match_operand:XF 2 "register_operand" "0,0")]))]
14631   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14632   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14633   [(set (attr "type") 
14634         (cond [(match_operand:XF 3 "mult_operator" "") 
14635                  (const_string "fmul")
14636                (match_operand:XF 3 "div_operator" "") 
14637                  (const_string "fdiv")
14638               ]
14639               (const_string "fop")))
14640    (set_attr "fp_int_src" "true")
14641    (set_attr "mode" "<MODE>")])
14643 (define_insn "*fop_xf_3<mode>_i387"
14644   [(set (match_operand:XF 0 "register_operand" "=f,f")
14645         (match_operator:XF 3 "binary_fp_operator"
14646           [(match_operand:XF 1 "register_operand" "0,0")
14647            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14648   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14649   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14650   [(set (attr "type") 
14651         (cond [(match_operand:XF 3 "mult_operator" "") 
14652                  (const_string "fmul")
14653                (match_operand:XF 3 "div_operator" "") 
14654                  (const_string "fdiv")
14655               ]
14656               (const_string "fop")))
14657    (set_attr "fp_int_src" "true")
14658    (set_attr "mode" "<MODE>")])
14660 (define_insn "*fop_xf_4_i387"
14661   [(set (match_operand:XF 0 "register_operand" "=f,f")
14662         (match_operator:XF 3 "binary_fp_operator"
14663            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14664             (match_operand:XF 2 "register_operand" "0,f")]))]
14665   "TARGET_80387"
14666   "* return output_387_binary_op (insn, operands);"
14667   [(set (attr "type") 
14668         (cond [(match_operand:XF 3 "mult_operator" "") 
14669                  (const_string "fmul")
14670                (match_operand:XF 3 "div_operator" "") 
14671                  (const_string "fdiv")
14672               ]
14673               (const_string "fop")))
14674    (set_attr "mode" "SF")])
14676 (define_insn "*fop_xf_5_i387"
14677   [(set (match_operand:XF 0 "register_operand" "=f,f")
14678         (match_operator:XF 3 "binary_fp_operator"
14679           [(match_operand:XF 1 "register_operand" "0,f")
14680            (float_extend:XF
14681             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14682   "TARGET_80387"
14683   "* return output_387_binary_op (insn, operands);"
14684   [(set (attr "type") 
14685         (cond [(match_operand:XF 3 "mult_operator" "") 
14686                  (const_string "fmul")
14687                (match_operand:XF 3 "div_operator" "") 
14688                  (const_string "fdiv")
14689               ]
14690               (const_string "fop")))
14691    (set_attr "mode" "SF")])
14693 (define_insn "*fop_xf_6_i387"
14694   [(set (match_operand:XF 0 "register_operand" "=f,f")
14695         (match_operator:XF 3 "binary_fp_operator"
14696           [(float_extend:XF
14697             (match_operand 1 "register_operand" "0,f"))
14698            (float_extend:XF
14699             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14700   "TARGET_80387"
14701   "* return output_387_binary_op (insn, operands);"
14702   [(set (attr "type") 
14703         (cond [(match_operand:XF 3 "mult_operator" "") 
14704                  (const_string "fmul")
14705                (match_operand:XF 3 "div_operator" "") 
14706                  (const_string "fdiv")
14707               ]
14708               (const_string "fop")))
14709    (set_attr "mode" "SF")])
14711 (define_split
14712   [(set (match_operand 0 "register_operand" "")
14713         (match_operator 3 "binary_fp_operator"
14714            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14715             (match_operand 2 "register_operand" "")]))]
14716   "TARGET_80387 && reload_completed
14717    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14718   [(const_int 0)]
14720   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14721   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14722   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14723                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14724                                           GET_MODE (operands[3]),
14725                                           operands[4],
14726                                           operands[2])));
14727   ix86_free_from_memory (GET_MODE (operands[1]));
14728   DONE;
14731 (define_split
14732   [(set (match_operand 0 "register_operand" "")
14733         (match_operator 3 "binary_fp_operator"
14734            [(match_operand 1 "register_operand" "")
14735             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14736   "TARGET_80387 && reload_completed
14737    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14738   [(const_int 0)]
14740   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14741   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14742   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14743                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14744                                           GET_MODE (operands[3]),
14745                                           operands[1],
14746                                           operands[4])));
14747   ix86_free_from_memory (GET_MODE (operands[2]));
14748   DONE;
14751 ;; FPU special functions.
14753 (define_expand "sqrtsf2"
14754   [(set (match_operand:SF 0 "register_operand" "")
14755         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14756   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14758   if (!TARGET_SSE_MATH)
14759     operands[1] = force_reg (SFmode, operands[1]);
14762 (define_insn "*sqrtsf2_mixed"
14763   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14764         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14765   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14766   "@
14767    fsqrt
14768    sqrtss\t{%1, %0|%0, %1}"
14769   [(set_attr "type" "fpspc,sse")
14770    (set_attr "mode" "SF,SF")
14771    (set_attr "athlon_decode" "direct,*")])
14773 (define_insn "*sqrtsf2_sse"
14774   [(set (match_operand:SF 0 "register_operand" "=x")
14775         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14776   "TARGET_SSE_MATH"
14777   "sqrtss\t{%1, %0|%0, %1}"
14778   [(set_attr "type" "sse")
14779    (set_attr "mode" "SF")
14780    (set_attr "athlon_decode" "*")])
14782 (define_insn "*sqrtsf2_i387"
14783   [(set (match_operand:SF 0 "register_operand" "=f")
14784         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14785   "TARGET_USE_FANCY_MATH_387"
14786   "fsqrt"
14787   [(set_attr "type" "fpspc")
14788    (set_attr "mode" "SF")
14789    (set_attr "athlon_decode" "direct")])
14791 (define_expand "sqrtdf2"
14792   [(set (match_operand:DF 0 "register_operand" "")
14793         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14794   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14796   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14797     operands[1] = force_reg (DFmode, operands[1]);
14800 (define_insn "*sqrtdf2_mixed"
14801   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14802         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14803   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14804   "@
14805    fsqrt
14806    sqrtsd\t{%1, %0|%0, %1}"
14807   [(set_attr "type" "fpspc,sse")
14808    (set_attr "mode" "DF,DF")
14809    (set_attr "athlon_decode" "direct,*")])
14811 (define_insn "*sqrtdf2_sse"
14812   [(set (match_operand:DF 0 "register_operand" "=Y")
14813         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14814   "TARGET_SSE2 && TARGET_SSE_MATH"
14815   "sqrtsd\t{%1, %0|%0, %1}"
14816   [(set_attr "type" "sse")
14817    (set_attr "mode" "DF")
14818    (set_attr "athlon_decode" "*")])
14820 (define_insn "*sqrtdf2_i387"
14821   [(set (match_operand:DF 0 "register_operand" "=f")
14822         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14823   "TARGET_USE_FANCY_MATH_387"
14824   "fsqrt"
14825   [(set_attr "type" "fpspc")
14826    (set_attr "mode" "DF")
14827    (set_attr "athlon_decode" "direct")])
14829 (define_insn "*sqrtextendsfdf2_i387"
14830   [(set (match_operand:DF 0 "register_operand" "=f")
14831         (sqrt:DF (float_extend:DF
14832                   (match_operand:SF 1 "register_operand" "0"))))]
14833   "TARGET_USE_FANCY_MATH_387
14834    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14835   "fsqrt"
14836   [(set_attr "type" "fpspc")
14837    (set_attr "mode" "DF")
14838    (set_attr "athlon_decode" "direct")])
14840 (define_insn "sqrtxf2"
14841   [(set (match_operand:XF 0 "register_operand" "=f")
14842         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14843   "TARGET_USE_FANCY_MATH_387 
14844    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14845   "fsqrt"
14846   [(set_attr "type" "fpspc")
14847    (set_attr "mode" "XF")
14848    (set_attr "athlon_decode" "direct")])
14850 (define_insn "*sqrtextendsfxf2_i387"
14851   [(set (match_operand:XF 0 "register_operand" "=f")
14852         (sqrt:XF (float_extend:XF
14853                   (match_operand:SF 1 "register_operand" "0"))))]
14854   "TARGET_USE_FANCY_MATH_387"
14855   "fsqrt"
14856   [(set_attr "type" "fpspc")
14857    (set_attr "mode" "XF")
14858    (set_attr "athlon_decode" "direct")])
14860 (define_insn "*sqrtextenddfxf2_i387"
14861   [(set (match_operand:XF 0 "register_operand" "=f")
14862         (sqrt:XF (float_extend:XF
14863                   (match_operand:DF 1 "register_operand" "0"))))]
14864   "TARGET_USE_FANCY_MATH_387"
14865   "fsqrt"
14866   [(set_attr "type" "fpspc")
14867    (set_attr "mode" "XF")
14868    (set_attr "athlon_decode" "direct")])
14870 (define_insn "fpremxf4"
14871   [(set (match_operand:XF 0 "register_operand" "=f")
14872         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14873                     (match_operand:XF 3 "register_operand" "1")]
14874                    UNSPEC_FPREM_F))
14875    (set (match_operand:XF 1 "register_operand" "=u")
14876         (unspec:XF [(match_dup 2) (match_dup 3)]
14877                    UNSPEC_FPREM_U))
14878    (set (reg:CCFP FPSR_REG)
14879         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && flag_unsafe_math_optimizations"
14882   "fprem"
14883   [(set_attr "type" "fpspc")
14884    (set_attr "mode" "XF")])
14886 (define_expand "fmodsf3"
14887   [(use (match_operand:SF 0 "register_operand" ""))
14888    (use (match_operand:SF 1 "register_operand" ""))
14889    (use (match_operand:SF 2 "register_operand" ""))]
14890   "TARGET_USE_FANCY_MATH_387
14891    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14892    && flag_unsafe_math_optimizations"
14894   rtx label = gen_label_rtx ();
14896   rtx op1 = gen_reg_rtx (XFmode);
14897   rtx op2 = gen_reg_rtx (XFmode);
14899   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14900   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14902   emit_label (label);
14904   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14905   ix86_emit_fp_unordered_jump (label);
14907   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14908   DONE;
14911 (define_expand "fmoddf3"
14912   [(use (match_operand:DF 0 "register_operand" ""))
14913    (use (match_operand:DF 1 "register_operand" ""))
14914    (use (match_operand:DF 2 "register_operand" ""))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14917    && flag_unsafe_math_optimizations"
14919   rtx label = gen_label_rtx ();
14921   rtx op1 = gen_reg_rtx (XFmode);
14922   rtx op2 = gen_reg_rtx (XFmode);
14924   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14925   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14927   emit_label (label);
14929   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14930   ix86_emit_fp_unordered_jump (label);
14932   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14933   DONE;
14936 (define_expand "fmodxf3"
14937   [(use (match_operand:XF 0 "register_operand" ""))
14938    (use (match_operand:XF 1 "register_operand" ""))
14939    (use (match_operand:XF 2 "register_operand" ""))]
14940   "TARGET_USE_FANCY_MATH_387
14941    && flag_unsafe_math_optimizations"
14943   rtx label = gen_label_rtx ();
14945   emit_label (label);
14947   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14948                            operands[1], operands[2]));
14949   ix86_emit_fp_unordered_jump (label);
14951   emit_move_insn (operands[0], operands[1]);
14952   DONE;
14955 (define_insn "fprem1xf4"
14956   [(set (match_operand:XF 0 "register_operand" "=f")
14957         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14958                     (match_operand:XF 3 "register_operand" "1")]
14959                    UNSPEC_FPREM1_F))
14960    (set (match_operand:XF 1 "register_operand" "=u")
14961         (unspec:XF [(match_dup 2) (match_dup 3)]
14962                    UNSPEC_FPREM1_U))
14963    (set (reg:CCFP FPSR_REG)
14964         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14965   "TARGET_USE_FANCY_MATH_387
14966    && flag_unsafe_math_optimizations"
14967   "fprem1"
14968   [(set_attr "type" "fpspc")
14969    (set_attr "mode" "XF")])
14971 (define_expand "dremsf3"
14972   [(use (match_operand:SF 0 "register_operand" ""))
14973    (use (match_operand:SF 1 "register_operand" ""))
14974    (use (match_operand:SF 2 "register_operand" ""))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14977    && flag_unsafe_math_optimizations"
14979   rtx label = gen_label_rtx ();
14981   rtx op1 = gen_reg_rtx (XFmode);
14982   rtx op2 = gen_reg_rtx (XFmode);
14984   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14985   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14987   emit_label (label);
14989   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14990   ix86_emit_fp_unordered_jump (label);
14992   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14993   DONE;
14996 (define_expand "dremdf3"
14997   [(use (match_operand:DF 0 "register_operand" ""))
14998    (use (match_operand:DF 1 "register_operand" ""))
14999    (use (match_operand:DF 2 "register_operand" ""))]
15000   "TARGET_USE_FANCY_MATH_387
15001    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15002    && flag_unsafe_math_optimizations"
15004   rtx label = gen_label_rtx ();
15006   rtx op1 = gen_reg_rtx (XFmode);
15007   rtx op2 = gen_reg_rtx (XFmode);
15009   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15010   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15012   emit_label (label);
15014   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15015   ix86_emit_fp_unordered_jump (label);
15017   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15018   DONE;
15021 (define_expand "dremxf3"
15022   [(use (match_operand:XF 0 "register_operand" ""))
15023    (use (match_operand:XF 1 "register_operand" ""))
15024    (use (match_operand:XF 2 "register_operand" ""))]
15025   "TARGET_USE_FANCY_MATH_387
15026    && flag_unsafe_math_optimizations"
15028   rtx label = gen_label_rtx ();
15030   emit_label (label);
15032   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15033                             operands[1], operands[2]));
15034   ix86_emit_fp_unordered_jump (label);
15036   emit_move_insn (operands[0], operands[1]);
15037   DONE;
15040 (define_insn "*sindf2"
15041   [(set (match_operand:DF 0 "register_operand" "=f")
15042         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15043   "TARGET_USE_FANCY_MATH_387
15044    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15045    && flag_unsafe_math_optimizations"
15046   "fsin"
15047   [(set_attr "type" "fpspc")
15048    (set_attr "mode" "DF")])
15050 (define_insn "*sinsf2"
15051   [(set (match_operand:SF 0 "register_operand" "=f")
15052         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15055    && flag_unsafe_math_optimizations"
15056   "fsin"
15057   [(set_attr "type" "fpspc")
15058    (set_attr "mode" "SF")])
15060 (define_insn "*sinextendsfdf2"
15061   [(set (match_operand:DF 0 "register_operand" "=f")
15062         (unspec:DF [(float_extend:DF
15063                      (match_operand:SF 1 "register_operand" "0"))]
15064                    UNSPEC_SIN))]
15065   "TARGET_USE_FANCY_MATH_387
15066    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15067    && flag_unsafe_math_optimizations"
15068   "fsin"
15069   [(set_attr "type" "fpspc")
15070    (set_attr "mode" "DF")])
15072 (define_insn "*sinxf2"
15073   [(set (match_operand:XF 0 "register_operand" "=f")
15074         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15075   "TARGET_USE_FANCY_MATH_387
15076    && flag_unsafe_math_optimizations"
15077   "fsin"
15078   [(set_attr "type" "fpspc")
15079    (set_attr "mode" "XF")])
15081 (define_insn "*cosdf2"
15082   [(set (match_operand:DF 0 "register_operand" "=f")
15083         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15086    && flag_unsafe_math_optimizations"
15087   "fcos"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "DF")])
15091 (define_insn "*cossf2"
15092   [(set (match_operand:SF 0 "register_operand" "=f")
15093         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15094   "TARGET_USE_FANCY_MATH_387
15095    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15096    && flag_unsafe_math_optimizations"
15097   "fcos"
15098   [(set_attr "type" "fpspc")
15099    (set_attr "mode" "SF")])
15101 (define_insn "*cosextendsfdf2"
15102   [(set (match_operand:DF 0 "register_operand" "=f")
15103         (unspec:DF [(float_extend:DF
15104                      (match_operand:SF 1 "register_operand" "0"))]
15105                    UNSPEC_COS))]
15106   "TARGET_USE_FANCY_MATH_387
15107    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15108    && flag_unsafe_math_optimizations"
15109   "fcos"
15110   [(set_attr "type" "fpspc")
15111    (set_attr "mode" "DF")])
15113 (define_insn "*cosxf2"
15114   [(set (match_operand:XF 0 "register_operand" "=f")
15115         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15116   "TARGET_USE_FANCY_MATH_387
15117    && flag_unsafe_math_optimizations"
15118   "fcos"
15119   [(set_attr "type" "fpspc")
15120    (set_attr "mode" "XF")])
15122 ;; With sincos pattern defined, sin and cos builtin function will be
15123 ;; expanded to sincos pattern with one of its outputs left unused. 
15124 ;; Cse pass  will detected, if two sincos patterns can be combined,
15125 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15126 ;; depending on the unused output.
15128 (define_insn "sincosdf3"
15129   [(set (match_operand:DF 0 "register_operand" "=f")
15130         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15131                    UNSPEC_SINCOS_COS))
15132    (set (match_operand:DF 1 "register_operand" "=u")
15133         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15136    && flag_unsafe_math_optimizations"
15137   "fsincos"
15138   [(set_attr "type" "fpspc")
15139    (set_attr "mode" "DF")])
15141 (define_split
15142   [(set (match_operand:DF 0 "register_operand" "")
15143         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15144                    UNSPEC_SINCOS_COS))
15145    (set (match_operand:DF 1 "register_operand" "")
15146         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15147   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15148    && !reload_completed && !reload_in_progress"
15149   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15150   "")
15152 (define_split
15153   [(set (match_operand:DF 0 "register_operand" "")
15154         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15155                    UNSPEC_SINCOS_COS))
15156    (set (match_operand:DF 1 "register_operand" "")
15157         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15158   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15159    && !reload_completed && !reload_in_progress"
15160   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15161   "")
15163 (define_insn "sincossf3"
15164   [(set (match_operand:SF 0 "register_operand" "=f")
15165         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15166                    UNSPEC_SINCOS_COS))
15167    (set (match_operand:SF 1 "register_operand" "=u")
15168         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15169   "TARGET_USE_FANCY_MATH_387
15170    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15171    && flag_unsafe_math_optimizations"
15172   "fsincos"
15173   [(set_attr "type" "fpspc")
15174    (set_attr "mode" "SF")])
15176 (define_split
15177   [(set (match_operand:SF 0 "register_operand" "")
15178         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15179                    UNSPEC_SINCOS_COS))
15180    (set (match_operand:SF 1 "register_operand" "")
15181         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15182   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15183    && !reload_completed && !reload_in_progress"
15184   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15185   "")
15187 (define_split
15188   [(set (match_operand:SF 0 "register_operand" "")
15189         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15190                    UNSPEC_SINCOS_COS))
15191    (set (match_operand:SF 1 "register_operand" "")
15192         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15193   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15194    && !reload_completed && !reload_in_progress"
15195   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15196   "")
15198 (define_insn "*sincosextendsfdf3"
15199   [(set (match_operand:DF 0 "register_operand" "=f")
15200         (unspec:DF [(float_extend:DF
15201                      (match_operand:SF 2 "register_operand" "0"))]
15202                    UNSPEC_SINCOS_COS))
15203    (set (match_operand:DF 1 "register_operand" "=u")
15204         (unspec:DF [(float_extend:DF
15205                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15206   "TARGET_USE_FANCY_MATH_387
15207    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15208    && flag_unsafe_math_optimizations"
15209   "fsincos"
15210   [(set_attr "type" "fpspc")
15211    (set_attr "mode" "DF")])
15213 (define_split
15214   [(set (match_operand:DF 0 "register_operand" "")
15215         (unspec:DF [(float_extend:DF
15216                      (match_operand:SF 2 "register_operand" ""))]
15217                    UNSPEC_SINCOS_COS))
15218    (set (match_operand:DF 1 "register_operand" "")
15219         (unspec:DF [(float_extend:DF
15220                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15221   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15222    && !reload_completed && !reload_in_progress"
15223   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15224                                    (match_dup 2))] UNSPEC_SIN))]
15225   "")
15227 (define_split
15228   [(set (match_operand:DF 0 "register_operand" "")
15229         (unspec:DF [(float_extend:DF
15230                      (match_operand:SF 2 "register_operand" ""))]
15231                    UNSPEC_SINCOS_COS))
15232    (set (match_operand:DF 1 "register_operand" "")
15233         (unspec:DF [(float_extend:DF
15234                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15235   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15236    && !reload_completed && !reload_in_progress"
15237   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15238                                    (match_dup 2))] UNSPEC_COS))]
15239   "")
15241 (define_insn "sincosxf3"
15242   [(set (match_operand:XF 0 "register_operand" "=f")
15243         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15244                    UNSPEC_SINCOS_COS))
15245    (set (match_operand:XF 1 "register_operand" "=u")
15246         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15247   "TARGET_USE_FANCY_MATH_387
15248    && flag_unsafe_math_optimizations"
15249   "fsincos"
15250   [(set_attr "type" "fpspc")
15251    (set_attr "mode" "XF")])
15253 (define_split
15254   [(set (match_operand:XF 0 "register_operand" "")
15255         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15256                    UNSPEC_SINCOS_COS))
15257    (set (match_operand:XF 1 "register_operand" "")
15258         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15259   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15260    && !reload_completed && !reload_in_progress"
15261   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15262   "")
15264 (define_split
15265   [(set (match_operand:XF 0 "register_operand" "")
15266         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15267                    UNSPEC_SINCOS_COS))
15268    (set (match_operand:XF 1 "register_operand" "")
15269         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15270   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15271    && !reload_completed && !reload_in_progress"
15272   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15273   "")
15275 (define_insn "*tandf3_1"
15276   [(set (match_operand:DF 0 "register_operand" "=f")
15277         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15278                    UNSPEC_TAN_ONE))
15279    (set (match_operand:DF 1 "register_operand" "=u")
15280         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15281   "TARGET_USE_FANCY_MATH_387
15282    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15283    && flag_unsafe_math_optimizations"
15284   "fptan"
15285   [(set_attr "type" "fpspc")
15286    (set_attr "mode" "DF")])
15288 ;; optimize sequence: fptan
15289 ;;                    fstp    %st(0)
15290 ;;                    fld1
15291 ;; into fptan insn.
15293 (define_peephole2
15294   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15295                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15296                              UNSPEC_TAN_ONE))
15297              (set (match_operand:DF 1 "register_operand" "")
15298                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15299    (set (match_dup 0)
15300         (match_operand:DF 3 "immediate_operand" ""))]
15301   "standard_80387_constant_p (operands[3]) == 2"
15302   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15303              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15304   "")
15306 (define_expand "tandf2"
15307   [(parallel [(set (match_dup 2)
15308                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15309                               UNSPEC_TAN_ONE))
15310               (set (match_operand:DF 0 "register_operand" "")
15311                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15312   "TARGET_USE_FANCY_MATH_387
15313    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15314    && flag_unsafe_math_optimizations"
15316   operands[2] = gen_reg_rtx (DFmode);
15319 (define_insn "*tansf3_1"
15320   [(set (match_operand:SF 0 "register_operand" "=f")
15321         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15322                    UNSPEC_TAN_ONE))
15323    (set (match_operand:SF 1 "register_operand" "=u")
15324         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15327    && flag_unsafe_math_optimizations"
15328   "fptan"
15329   [(set_attr "type" "fpspc")
15330    (set_attr "mode" "SF")])
15332 ;; optimize sequence: fptan
15333 ;;                    fstp    %st(0)
15334 ;;                    fld1
15335 ;; into fptan insn.
15337 (define_peephole2
15338   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15339                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15340                              UNSPEC_TAN_ONE))
15341              (set (match_operand:SF 1 "register_operand" "")
15342                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15343    (set (match_dup 0)
15344         (match_operand:SF 3 "immediate_operand" ""))]
15345   "standard_80387_constant_p (operands[3]) == 2"
15346   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15347              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15348   "")
15350 (define_expand "tansf2"
15351   [(parallel [(set (match_dup 2)
15352                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15353                               UNSPEC_TAN_ONE))
15354               (set (match_operand:SF 0 "register_operand" "")
15355                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15356   "TARGET_USE_FANCY_MATH_387
15357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15358    && flag_unsafe_math_optimizations"
15360   operands[2] = gen_reg_rtx (SFmode);
15363 (define_insn "*tanxf3_1"
15364   [(set (match_operand:XF 0 "register_operand" "=f")
15365         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15366                    UNSPEC_TAN_ONE))
15367    (set (match_operand:XF 1 "register_operand" "=u")
15368         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15369   "TARGET_USE_FANCY_MATH_387
15370    && flag_unsafe_math_optimizations"
15371   "fptan"
15372   [(set_attr "type" "fpspc")
15373    (set_attr "mode" "XF")])
15375 ;; optimize sequence: fptan
15376 ;;                    fstp    %st(0)
15377 ;;                    fld1
15378 ;; into fptan insn.
15380 (define_peephole2
15381   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15382                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15383                              UNSPEC_TAN_ONE))
15384              (set (match_operand:XF 1 "register_operand" "")
15385                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15386    (set (match_dup 0)
15387         (match_operand:XF 3 "immediate_operand" ""))]
15388   "standard_80387_constant_p (operands[3]) == 2"
15389   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15390              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15391   "")
15393 (define_expand "tanxf2"
15394   [(parallel [(set (match_dup 2)
15395                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15396                               UNSPEC_TAN_ONE))
15397               (set (match_operand:XF 0 "register_operand" "")
15398                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15399   "TARGET_USE_FANCY_MATH_387
15400    && flag_unsafe_math_optimizations"
15402   operands[2] = gen_reg_rtx (XFmode);
15405 (define_insn "atan2df3_1"
15406   [(set (match_operand:DF 0 "register_operand" "=f")
15407         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15408                     (match_operand:DF 1 "register_operand" "u")]
15409                    UNSPEC_FPATAN))
15410    (clobber (match_scratch:DF 3 "=1"))]
15411   "TARGET_USE_FANCY_MATH_387
15412    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15413    && flag_unsafe_math_optimizations"
15414   "fpatan"
15415   [(set_attr "type" "fpspc")
15416    (set_attr "mode" "DF")])
15418 (define_expand "atan2df3"
15419   [(use (match_operand:DF 0 "register_operand" ""))
15420    (use (match_operand:DF 2 "register_operand" ""))
15421    (use (match_operand:DF 1 "register_operand" ""))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424    && flag_unsafe_math_optimizations"
15426   rtx copy = gen_reg_rtx (DFmode);
15427   emit_move_insn (copy, operands[1]);
15428   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15429   DONE;
15432 (define_expand "atandf2"
15433   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15434                    (unspec:DF [(match_dup 2)
15435                                (match_operand:DF 1 "register_operand" "")]
15436                     UNSPEC_FPATAN))
15437               (clobber (match_scratch:DF 3 ""))])]
15438   "TARGET_USE_FANCY_MATH_387
15439    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15440    && flag_unsafe_math_optimizations"
15442   operands[2] = gen_reg_rtx (DFmode);
15443   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15446 (define_insn "atan2sf3_1"
15447   [(set (match_operand:SF 0 "register_operand" "=f")
15448         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15449                     (match_operand:SF 1 "register_operand" "u")]
15450                    UNSPEC_FPATAN))
15451    (clobber (match_scratch:SF 3 "=1"))]
15452   "TARGET_USE_FANCY_MATH_387
15453    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15454    && flag_unsafe_math_optimizations"
15455   "fpatan"
15456   [(set_attr "type" "fpspc")
15457    (set_attr "mode" "SF")])
15459 (define_expand "atan2sf3"
15460   [(use (match_operand:SF 0 "register_operand" ""))
15461    (use (match_operand:SF 2 "register_operand" ""))
15462    (use (match_operand:SF 1 "register_operand" ""))]
15463   "TARGET_USE_FANCY_MATH_387
15464    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15465    && flag_unsafe_math_optimizations"
15467   rtx copy = gen_reg_rtx (SFmode);
15468   emit_move_insn (copy, operands[1]);
15469   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15470   DONE;
15473 (define_expand "atansf2"
15474   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15475                    (unspec:SF [(match_dup 2)
15476                                (match_operand:SF 1 "register_operand" "")]
15477                     UNSPEC_FPATAN))
15478               (clobber (match_scratch:SF 3 ""))])]
15479   "TARGET_USE_FANCY_MATH_387
15480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15481    && flag_unsafe_math_optimizations"
15483   operands[2] = gen_reg_rtx (SFmode);
15484   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15487 (define_insn "atan2xf3_1"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490                     (match_operand:XF 1 "register_operand" "u")]
15491                    UNSPEC_FPATAN))
15492    (clobber (match_scratch:XF 3 "=1"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && flag_unsafe_math_optimizations"
15495   "fpatan"
15496   [(set_attr "type" "fpspc")
15497    (set_attr "mode" "XF")])
15499 (define_expand "atan2xf3"
15500   [(use (match_operand:XF 0 "register_operand" ""))
15501    (use (match_operand:XF 2 "register_operand" ""))
15502    (use (match_operand:XF 1 "register_operand" ""))]
15503   "TARGET_USE_FANCY_MATH_387
15504    && flag_unsafe_math_optimizations"
15506   rtx copy = gen_reg_rtx (XFmode);
15507   emit_move_insn (copy, operands[1]);
15508   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15509   DONE;
15512 (define_expand "atanxf2"
15513   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15514                    (unspec:XF [(match_dup 2)
15515                                (match_operand:XF 1 "register_operand" "")]
15516                     UNSPEC_FPATAN))
15517               (clobber (match_scratch:XF 3 ""))])]
15518   "TARGET_USE_FANCY_MATH_387
15519    && flag_unsafe_math_optimizations"
15521   operands[2] = gen_reg_rtx (XFmode);
15522   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15525 (define_expand "asindf2"
15526   [(set (match_dup 2)
15527         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15528    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15529    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15530    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15531    (parallel [(set (match_dup 7)
15532                    (unspec:XF [(match_dup 6) (match_dup 2)]
15533                               UNSPEC_FPATAN))
15534               (clobber (match_scratch:XF 8 ""))])
15535    (set (match_operand:DF 0 "register_operand" "")
15536         (float_truncate:DF (match_dup 7)))]
15537   "TARGET_USE_FANCY_MATH_387
15538    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15539    && flag_unsafe_math_optimizations"
15541   int i;
15543   for (i=2; i<8; i++)
15544     operands[i] = gen_reg_rtx (XFmode);
15546   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15549 (define_expand "asinsf2"
15550   [(set (match_dup 2)
15551         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15552    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15553    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15554    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15555    (parallel [(set (match_dup 7)
15556                    (unspec:XF [(match_dup 6) (match_dup 2)]
15557                               UNSPEC_FPATAN))
15558               (clobber (match_scratch:XF 8 ""))])
15559    (set (match_operand:SF 0 "register_operand" "")
15560         (float_truncate:SF (match_dup 7)))]
15561   "TARGET_USE_FANCY_MATH_387
15562    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15563    && flag_unsafe_math_optimizations"
15565   int i;
15567   for (i=2; i<8; i++)
15568     operands[i] = gen_reg_rtx (XFmode);
15570   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15573 (define_expand "asinxf2"
15574   [(set (match_dup 2)
15575         (mult:XF (match_operand:XF 1 "register_operand" "")
15576                  (match_dup 1)))
15577    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15578    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15579    (parallel [(set (match_operand:XF 0 "register_operand" "")
15580                    (unspec:XF [(match_dup 5) (match_dup 1)]
15581                               UNSPEC_FPATAN))
15582               (clobber (match_scratch:XF 6 ""))])]
15583   "TARGET_USE_FANCY_MATH_387
15584    && flag_unsafe_math_optimizations"
15586   int i;
15588   for (i=2; i<6; i++)
15589     operands[i] = gen_reg_rtx (XFmode);
15591   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15594 (define_expand "acosdf2"
15595   [(set (match_dup 2)
15596         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15597    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15598    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15599    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15600    (parallel [(set (match_dup 7)
15601                    (unspec:XF [(match_dup 2) (match_dup 6)]
15602                               UNSPEC_FPATAN))
15603               (clobber (match_scratch:XF 8 ""))])
15604    (set (match_operand:DF 0 "register_operand" "")
15605         (float_truncate:DF (match_dup 7)))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15608    && flag_unsafe_math_optimizations"
15610   int i;
15612   for (i=2; i<8; i++)
15613     operands[i] = gen_reg_rtx (XFmode);
15615   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15618 (define_expand "acossf2"
15619   [(set (match_dup 2)
15620         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15621    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15622    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15623    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15624    (parallel [(set (match_dup 7)
15625                    (unspec:XF [(match_dup 2) (match_dup 6)]
15626                               UNSPEC_FPATAN))
15627               (clobber (match_scratch:XF 8 ""))])
15628    (set (match_operand:SF 0 "register_operand" "")
15629         (float_truncate:SF (match_dup 7)))]
15630   "TARGET_USE_FANCY_MATH_387
15631    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15632    && flag_unsafe_math_optimizations"
15634   int i;
15636   for (i=2; i<8; i++)
15637     operands[i] = gen_reg_rtx (XFmode);
15639   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15642 (define_expand "acosxf2"
15643   [(set (match_dup 2)
15644         (mult:XF (match_operand:XF 1 "register_operand" "")
15645                  (match_dup 1)))
15646    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15647    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15648    (parallel [(set (match_operand:XF 0 "register_operand" "")
15649                    (unspec:XF [(match_dup 1) (match_dup 5)]
15650                               UNSPEC_FPATAN))
15651               (clobber (match_scratch:XF 6 ""))])]
15652   "TARGET_USE_FANCY_MATH_387
15653    && flag_unsafe_math_optimizations"
15655   int i;
15657   for (i=2; i<6; i++)
15658     operands[i] = gen_reg_rtx (XFmode);
15660   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15663 (define_insn "fyl2x_xf3"
15664   [(set (match_operand:XF 0 "register_operand" "=f")
15665         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15666                     (match_operand:XF 1 "register_operand" "u")]
15667                    UNSPEC_FYL2X))
15668    (clobber (match_scratch:XF 3 "=1"))]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15671   "fyl2x"
15672   [(set_attr "type" "fpspc")
15673    (set_attr "mode" "XF")])
15675 (define_expand "logsf2"
15676   [(set (match_dup 2)
15677         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15678    (parallel [(set (match_dup 4)
15679                    (unspec:XF [(match_dup 2)
15680                                (match_dup 3)] UNSPEC_FYL2X))
15681               (clobber (match_scratch:XF 5 ""))])
15682    (set (match_operand:SF 0 "register_operand" "")
15683         (float_truncate:SF (match_dup 4)))]
15684   "TARGET_USE_FANCY_MATH_387
15685    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15686    && flag_unsafe_math_optimizations"
15688   rtx temp;
15690   operands[2] = gen_reg_rtx (XFmode);
15691   operands[3] = gen_reg_rtx (XFmode);
15692   operands[4] = gen_reg_rtx (XFmode);
15694   temp = standard_80387_constant_rtx (4); /* fldln2 */
15695   emit_move_insn (operands[3], temp);
15698 (define_expand "logdf2"
15699   [(set (match_dup 2)
15700         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15701    (parallel [(set (match_dup 4)
15702                    (unspec:XF [(match_dup 2)
15703                                (match_dup 3)] UNSPEC_FYL2X))
15704               (clobber (match_scratch:XF 5 ""))])
15705    (set (match_operand:DF 0 "register_operand" "")
15706         (float_truncate:DF (match_dup 4)))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15709    && flag_unsafe_math_optimizations"
15711   rtx temp;
15713   operands[2] = gen_reg_rtx (XFmode);
15714   operands[3] = gen_reg_rtx (XFmode);
15715   operands[4] = gen_reg_rtx (XFmode);
15717   temp = standard_80387_constant_rtx (4); /* fldln2 */
15718   emit_move_insn (operands[3], temp);
15721 (define_expand "logxf2"
15722   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15723                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15724                                (match_dup 2)] UNSPEC_FYL2X))
15725               (clobber (match_scratch:XF 3 ""))])]
15726   "TARGET_USE_FANCY_MATH_387
15727    && flag_unsafe_math_optimizations"
15729   rtx temp;
15731   operands[2] = gen_reg_rtx (XFmode);
15732   temp = standard_80387_constant_rtx (4); /* fldln2 */
15733   emit_move_insn (operands[2], temp);
15736 (define_expand "log10sf2"
15737   [(set (match_dup 2)
15738         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15739    (parallel [(set (match_dup 4)
15740                    (unspec:XF [(match_dup 2)
15741                                (match_dup 3)] UNSPEC_FYL2X))
15742               (clobber (match_scratch:XF 5 ""))])
15743    (set (match_operand:SF 0 "register_operand" "")
15744         (float_truncate:SF (match_dup 4)))]
15745   "TARGET_USE_FANCY_MATH_387
15746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15749   rtx temp;
15751   operands[2] = gen_reg_rtx (XFmode);
15752   operands[3] = gen_reg_rtx (XFmode);
15753   operands[4] = gen_reg_rtx (XFmode);
15755   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15756   emit_move_insn (operands[3], temp);
15759 (define_expand "log10df2"
15760   [(set (match_dup 2)
15761         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15762    (parallel [(set (match_dup 4)
15763                    (unspec:XF [(match_dup 2)
15764                                (match_dup 3)] UNSPEC_FYL2X))
15765               (clobber (match_scratch:XF 5 ""))])
15766    (set (match_operand:DF 0 "register_operand" "")
15767         (float_truncate:DF (match_dup 4)))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations"
15772   rtx temp;
15774   operands[2] = gen_reg_rtx (XFmode);
15775   operands[3] = gen_reg_rtx (XFmode);
15776   operands[4] = gen_reg_rtx (XFmode);
15778   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15779   emit_move_insn (operands[3], temp);
15782 (define_expand "log10xf2"
15783   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15784                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15785                                (match_dup 2)] UNSPEC_FYL2X))
15786               (clobber (match_scratch:XF 3 ""))])]
15787   "TARGET_USE_FANCY_MATH_387
15788    && flag_unsafe_math_optimizations"
15790   rtx temp;
15792   operands[2] = gen_reg_rtx (XFmode);
15793   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15794   emit_move_insn (operands[2], temp);
15797 (define_expand "log2sf2"
15798   [(set (match_dup 2)
15799         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15800    (parallel [(set (match_dup 4)
15801                    (unspec:XF [(match_dup 2)
15802                                (match_dup 3)] UNSPEC_FYL2X))
15803               (clobber (match_scratch:XF 5 ""))])
15804    (set (match_operand:SF 0 "register_operand" "")
15805         (float_truncate:SF (match_dup 4)))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15808    && flag_unsafe_math_optimizations"
15810   operands[2] = gen_reg_rtx (XFmode);
15811   operands[3] = gen_reg_rtx (XFmode);
15812   operands[4] = gen_reg_rtx (XFmode);
15814   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15817 (define_expand "log2df2"
15818   [(set (match_dup 2)
15819         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15820    (parallel [(set (match_dup 4)
15821                    (unspec:XF [(match_dup 2)
15822                                (match_dup 3)] UNSPEC_FYL2X))
15823               (clobber (match_scratch:XF 5 ""))])
15824    (set (match_operand:DF 0 "register_operand" "")
15825         (float_truncate:DF (match_dup 4)))]
15826   "TARGET_USE_FANCY_MATH_387
15827    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15828    && flag_unsafe_math_optimizations"
15830   operands[2] = gen_reg_rtx (XFmode);
15831   operands[3] = gen_reg_rtx (XFmode);
15832   operands[4] = gen_reg_rtx (XFmode);
15834   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15837 (define_expand "log2xf2"
15838   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15839                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15840                                (match_dup 2)] UNSPEC_FYL2X))
15841               (clobber (match_scratch:XF 3 ""))])]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15845   operands[2] = gen_reg_rtx (XFmode);
15846   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15849 (define_insn "fyl2xp1_xf3"
15850   [(set (match_operand:XF 0 "register_operand" "=f")
15851         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15852                     (match_operand:XF 1 "register_operand" "u")]
15853                    UNSPEC_FYL2XP1))
15854    (clobber (match_scratch:XF 3 "=1"))]
15855   "TARGET_USE_FANCY_MATH_387
15856    && flag_unsafe_math_optimizations"
15857   "fyl2xp1"
15858   [(set_attr "type" "fpspc")
15859    (set_attr "mode" "XF")])
15861 (define_expand "log1psf2"
15862   [(use (match_operand:SF 0 "register_operand" ""))
15863    (use (match_operand:SF 1 "register_operand" ""))]
15864   "TARGET_USE_FANCY_MATH_387
15865    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15866    && flag_unsafe_math_optimizations"
15868   rtx op0 = gen_reg_rtx (XFmode);
15869   rtx op1 = gen_reg_rtx (XFmode);
15871   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15872   ix86_emit_i387_log1p (op0, op1);
15873   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15874   DONE;
15877 (define_expand "log1pdf2"
15878   [(use (match_operand:DF 0 "register_operand" ""))
15879    (use (match_operand:DF 1 "register_operand" ""))]
15880   "TARGET_USE_FANCY_MATH_387
15881    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15882    && flag_unsafe_math_optimizations"
15884   rtx op0 = gen_reg_rtx (XFmode);
15885   rtx op1 = gen_reg_rtx (XFmode);
15887   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15888   ix86_emit_i387_log1p (op0, op1);
15889   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15890   DONE;
15893 (define_expand "log1pxf2"
15894   [(use (match_operand:XF 0 "register_operand" ""))
15895    (use (match_operand:XF 1 "register_operand" ""))]
15896   "TARGET_USE_FANCY_MATH_387
15897    && flag_unsafe_math_optimizations"
15899   ix86_emit_i387_log1p (operands[0], operands[1]);
15900   DONE;
15903 (define_insn "*fxtractxf3"
15904   [(set (match_operand:XF 0 "register_operand" "=f")
15905         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15906                    UNSPEC_XTRACT_FRACT))
15907    (set (match_operand:XF 1 "register_operand" "=u")
15908         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && flag_unsafe_math_optimizations"
15911   "fxtract"
15912   [(set_attr "type" "fpspc")
15913    (set_attr "mode" "XF")])
15915 (define_expand "logbsf2"
15916   [(set (match_dup 2)
15917         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15918    (parallel [(set (match_dup 3)
15919                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15920               (set (match_dup 4)
15921                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15922    (set (match_operand:SF 0 "register_operand" "")
15923         (float_truncate:SF (match_dup 4)))]
15924   "TARGET_USE_FANCY_MATH_387
15925    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15926    && flag_unsafe_math_optimizations"
15928   operands[2] = gen_reg_rtx (XFmode);
15929   operands[3] = gen_reg_rtx (XFmode);
15930   operands[4] = gen_reg_rtx (XFmode);
15933 (define_expand "logbdf2"
15934   [(set (match_dup 2)
15935         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15936    (parallel [(set (match_dup 3)
15937                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15938               (set (match_dup 4)
15939                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15940    (set (match_operand:DF 0 "register_operand" "")
15941         (float_truncate:DF (match_dup 4)))]
15942   "TARGET_USE_FANCY_MATH_387
15943    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15944    && flag_unsafe_math_optimizations"
15946   operands[2] = gen_reg_rtx (XFmode);
15947   operands[3] = gen_reg_rtx (XFmode);
15948   operands[4] = gen_reg_rtx (XFmode);
15951 (define_expand "logbxf2"
15952   [(parallel [(set (match_dup 2)
15953                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15954                               UNSPEC_XTRACT_FRACT))
15955               (set (match_operand:XF 0 "register_operand" "")
15956                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15957   "TARGET_USE_FANCY_MATH_387
15958    && flag_unsafe_math_optimizations"
15960   operands[2] = gen_reg_rtx (XFmode);
15963 (define_expand "ilogbsi2"
15964   [(parallel [(set (match_dup 2)
15965                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15966                               UNSPEC_XTRACT_FRACT))
15967               (set (match_operand:XF 3 "register_operand" "")
15968                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15969    (parallel [(set (match_operand:SI 0 "register_operand" "")
15970                    (fix:SI (match_dup 3)))
15971               (clobber (reg:CC FLAGS_REG))])]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974    && flag_unsafe_math_optimizations"
15976   operands[2] = gen_reg_rtx (XFmode);
15977   operands[3] = gen_reg_rtx (XFmode);
15980 (define_insn "*f2xm1xf2"
15981   [(set (match_operand:XF 0 "register_operand" "=f")
15982         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15983          UNSPEC_F2XM1))]
15984   "TARGET_USE_FANCY_MATH_387
15985    && flag_unsafe_math_optimizations"
15986   "f2xm1"
15987   [(set_attr "type" "fpspc")
15988    (set_attr "mode" "XF")])
15990 (define_insn "*fscalexf4"
15991   [(set (match_operand:XF 0 "register_operand" "=f")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15993                     (match_operand:XF 3 "register_operand" "1")]
15994                    UNSPEC_FSCALE_FRACT))
15995    (set (match_operand:XF 1 "register_operand" "=u")
15996         (unspec:XF [(match_dup 2) (match_dup 3)]
15997                    UNSPEC_FSCALE_EXP))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16000   "fscale"
16001   [(set_attr "type" "fpspc")
16002    (set_attr "mode" "XF")])
16004 (define_expand "expsf2"
16005   [(set (match_dup 2)
16006         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16007    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16008    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16009    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16010    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16011    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16012    (parallel [(set (match_dup 10)
16013                    (unspec:XF [(match_dup 9) (match_dup 5)]
16014                               UNSPEC_FSCALE_FRACT))
16015               (set (match_dup 11)
16016                    (unspec:XF [(match_dup 9) (match_dup 5)]
16017                               UNSPEC_FSCALE_EXP))])
16018    (set (match_operand:SF 0 "register_operand" "")
16019         (float_truncate:SF (match_dup 10)))]
16020   "TARGET_USE_FANCY_MATH_387
16021    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16022    && flag_unsafe_math_optimizations"
16024   rtx temp;
16025   int i;
16027   for (i=2; i<12; i++)
16028     operands[i] = gen_reg_rtx (XFmode);
16029   temp = standard_80387_constant_rtx (5); /* fldl2e */
16030   emit_move_insn (operands[3], temp);
16031   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16034 (define_expand "expdf2"
16035   [(set (match_dup 2)
16036         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16037    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16038    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16039    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16040    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16041    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16042    (parallel [(set (match_dup 10)
16043                    (unspec:XF [(match_dup 9) (match_dup 5)]
16044                               UNSPEC_FSCALE_FRACT))
16045               (set (match_dup 11)
16046                    (unspec:XF [(match_dup 9) (match_dup 5)]
16047                               UNSPEC_FSCALE_EXP))])
16048    (set (match_operand:DF 0 "register_operand" "")
16049         (float_truncate:DF (match_dup 10)))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052    && flag_unsafe_math_optimizations"
16054   rtx temp;
16055   int i;
16057   for (i=2; i<12; i++)
16058     operands[i] = gen_reg_rtx (XFmode);
16059   temp = standard_80387_constant_rtx (5); /* fldl2e */
16060   emit_move_insn (operands[3], temp);
16061   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16064 (define_expand "expxf2"
16065   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16066                                (match_dup 2)))
16067    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16068    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16069    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16070    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16071    (parallel [(set (match_operand:XF 0 "register_operand" "")
16072                    (unspec:XF [(match_dup 8) (match_dup 4)]
16073                               UNSPEC_FSCALE_FRACT))
16074               (set (match_dup 9)
16075                    (unspec:XF [(match_dup 8) (match_dup 4)]
16076                               UNSPEC_FSCALE_EXP))])]
16077   "TARGET_USE_FANCY_MATH_387
16078    && flag_unsafe_math_optimizations"
16080   rtx temp;
16081   int i;
16083   for (i=2; i<10; i++)
16084     operands[i] = gen_reg_rtx (XFmode);
16085   temp = standard_80387_constant_rtx (5); /* fldl2e */
16086   emit_move_insn (operands[2], temp);
16087   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16090 (define_expand "exp10sf2"
16091   [(set (match_dup 2)
16092         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16093    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16094    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16095    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16096    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16097    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16098    (parallel [(set (match_dup 10)
16099                    (unspec:XF [(match_dup 9) (match_dup 5)]
16100                               UNSPEC_FSCALE_FRACT))
16101               (set (match_dup 11)
16102                    (unspec:XF [(match_dup 9) (match_dup 5)]
16103                               UNSPEC_FSCALE_EXP))])
16104    (set (match_operand:SF 0 "register_operand" "")
16105         (float_truncate:SF (match_dup 10)))]
16106   "TARGET_USE_FANCY_MATH_387
16107    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16108    && flag_unsafe_math_optimizations"
16110   rtx temp;
16111   int i;
16113   for (i=2; i<12; i++)
16114     operands[i] = gen_reg_rtx (XFmode);
16115   temp = standard_80387_constant_rtx (6); /* fldl2t */
16116   emit_move_insn (operands[3], temp);
16117   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16120 (define_expand "exp10df2"
16121   [(set (match_dup 2)
16122         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16123    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16124    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16125    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16126    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16127    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16128    (parallel [(set (match_dup 10)
16129                    (unspec:XF [(match_dup 9) (match_dup 5)]
16130                               UNSPEC_FSCALE_FRACT))
16131               (set (match_dup 11)
16132                    (unspec:XF [(match_dup 9) (match_dup 5)]
16133                               UNSPEC_FSCALE_EXP))])
16134    (set (match_operand:DF 0 "register_operand" "")
16135         (float_truncate:DF (match_dup 10)))]
16136   "TARGET_USE_FANCY_MATH_387
16137    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16140   rtx temp;
16141   int i;
16143   for (i=2; i<12; i++)
16144     operands[i] = gen_reg_rtx (XFmode);
16145   temp = standard_80387_constant_rtx (6); /* fldl2t */
16146   emit_move_insn (operands[3], temp);
16147   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16150 (define_expand "exp10xf2"
16151   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16152                                (match_dup 2)))
16153    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16154    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16155    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16156    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16157    (parallel [(set (match_operand:XF 0 "register_operand" "")
16158                    (unspec:XF [(match_dup 8) (match_dup 4)]
16159                               UNSPEC_FSCALE_FRACT))
16160               (set (match_dup 9)
16161                    (unspec:XF [(match_dup 8) (match_dup 4)]
16162                               UNSPEC_FSCALE_EXP))])]
16163   "TARGET_USE_FANCY_MATH_387
16164    && flag_unsafe_math_optimizations"
16166   rtx temp;
16167   int i;
16169   for (i=2; i<10; i++)
16170     operands[i] = gen_reg_rtx (XFmode);
16171   temp = standard_80387_constant_rtx (6); /* fldl2t */
16172   emit_move_insn (operands[2], temp);
16173   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16176 (define_expand "exp2sf2"
16177   [(set (match_dup 2)
16178         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16179    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16180    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16181    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16182    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16183    (parallel [(set (match_dup 8)
16184                    (unspec:XF [(match_dup 7) (match_dup 3)]
16185                               UNSPEC_FSCALE_FRACT))
16186               (set (match_dup 9)
16187                    (unspec:XF [(match_dup 7) (match_dup 3)]
16188                               UNSPEC_FSCALE_EXP))])
16189    (set (match_operand:SF 0 "register_operand" "")
16190         (float_truncate:SF (match_dup 8)))]
16191   "TARGET_USE_FANCY_MATH_387
16192    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16193    && flag_unsafe_math_optimizations"
16195   int i;
16197   for (i=2; i<10; i++)
16198     operands[i] = gen_reg_rtx (XFmode);
16199   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16202 (define_expand "exp2df2"
16203   [(set (match_dup 2)
16204         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16205    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16206    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16207    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16208    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16209    (parallel [(set (match_dup 8)
16210                    (unspec:XF [(match_dup 7) (match_dup 3)]
16211                               UNSPEC_FSCALE_FRACT))
16212               (set (match_dup 9)
16213                    (unspec:XF [(match_dup 7) (match_dup 3)]
16214                               UNSPEC_FSCALE_EXP))])
16215    (set (match_operand:DF 0 "register_operand" "")
16216         (float_truncate:DF (match_dup 8)))]
16217   "TARGET_USE_FANCY_MATH_387
16218    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16219    && flag_unsafe_math_optimizations"
16221   int i;
16223   for (i=2; i<10; i++)
16224     operands[i] = gen_reg_rtx (XFmode);
16225   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16228 (define_expand "exp2xf2"
16229   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16230    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16231    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16232    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16233    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16234    (parallel [(set (match_operand:XF 0 "register_operand" "")
16235                    (unspec:XF [(match_dup 7) (match_dup 3)]
16236                               UNSPEC_FSCALE_FRACT))
16237               (set (match_dup 8)
16238                    (unspec:XF [(match_dup 7) (match_dup 3)]
16239                               UNSPEC_FSCALE_EXP))])]
16240   "TARGET_USE_FANCY_MATH_387
16241    && flag_unsafe_math_optimizations"
16243   int i;
16245   for (i=2; i<9; i++)
16246     operands[i] = gen_reg_rtx (XFmode);
16247   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16250 (define_expand "expm1df2"
16251   [(set (match_dup 2)
16252         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16254    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16255    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16256    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16257    (parallel [(set (match_dup 8)
16258                    (unspec:XF [(match_dup 7) (match_dup 5)]
16259                               UNSPEC_FSCALE_FRACT))
16260                    (set (match_dup 9)
16261                    (unspec:XF [(match_dup 7) (match_dup 5)]
16262                               UNSPEC_FSCALE_EXP))])
16263    (parallel [(set (match_dup 11)
16264                    (unspec:XF [(match_dup 10) (match_dup 9)]
16265                               UNSPEC_FSCALE_FRACT))
16266               (set (match_dup 12)
16267                    (unspec:XF [(match_dup 10) (match_dup 9)]
16268                               UNSPEC_FSCALE_EXP))])
16269    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16270    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16271    (set (match_operand:DF 0 "register_operand" "")
16272         (float_truncate:DF (match_dup 14)))]
16273   "TARGET_USE_FANCY_MATH_387
16274    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16275    && flag_unsafe_math_optimizations"
16277   rtx temp;
16278   int i;
16280   for (i=2; i<15; i++)
16281     operands[i] = gen_reg_rtx (XFmode);
16282   temp = standard_80387_constant_rtx (5); /* fldl2e */
16283   emit_move_insn (operands[3], temp);
16284   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16287 (define_expand "expm1sf2"
16288   [(set (match_dup 2)
16289         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16290    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16291    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16292    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16293    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16294    (parallel [(set (match_dup 8)
16295                    (unspec:XF [(match_dup 7) (match_dup 5)]
16296                               UNSPEC_FSCALE_FRACT))
16297                    (set (match_dup 9)
16298                    (unspec:XF [(match_dup 7) (match_dup 5)]
16299                               UNSPEC_FSCALE_EXP))])
16300    (parallel [(set (match_dup 11)
16301                    (unspec:XF [(match_dup 10) (match_dup 9)]
16302                               UNSPEC_FSCALE_FRACT))
16303               (set (match_dup 12)
16304                    (unspec:XF [(match_dup 10) (match_dup 9)]
16305                               UNSPEC_FSCALE_EXP))])
16306    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16307    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16308    (set (match_operand:SF 0 "register_operand" "")
16309         (float_truncate:SF (match_dup 14)))]
16310   "TARGET_USE_FANCY_MATH_387
16311    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312    && flag_unsafe_math_optimizations"
16314   rtx temp;
16315   int i;
16317   for (i=2; i<15; i++)
16318     operands[i] = gen_reg_rtx (XFmode);
16319   temp = standard_80387_constant_rtx (5); /* fldl2e */
16320   emit_move_insn (operands[3], temp);
16321   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16324 (define_expand "expm1xf2"
16325   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16326                                (match_dup 2)))
16327    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16328    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16329    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16330    (parallel [(set (match_dup 7)
16331                    (unspec:XF [(match_dup 6) (match_dup 4)]
16332                               UNSPEC_FSCALE_FRACT))
16333                    (set (match_dup 8)
16334                    (unspec:XF [(match_dup 6) (match_dup 4)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (parallel [(set (match_dup 10)
16337                    (unspec:XF [(match_dup 9) (match_dup 8)]
16338                               UNSPEC_FSCALE_FRACT))
16339               (set (match_dup 11)
16340                    (unspec:XF [(match_dup 9) (match_dup 8)]
16341                               UNSPEC_FSCALE_EXP))])
16342    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16343    (set (match_operand:XF 0 "register_operand" "")
16344         (plus:XF (match_dup 12) (match_dup 7)))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && flag_unsafe_math_optimizations"
16348   rtx temp;
16349   int i;
16351   for (i=2; i<13; i++)
16352     operands[i] = gen_reg_rtx (XFmode);
16353   temp = standard_80387_constant_rtx (5); /* fldl2e */
16354   emit_move_insn (operands[2], temp);
16355   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16358 (define_expand "ldexpdf3"
16359   [(set (match_dup 3)
16360         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16361    (set (match_dup 4)
16362         (float:XF (match_operand:SI 2 "register_operand" "")))
16363    (parallel [(set (match_dup 5)
16364                    (unspec:XF [(match_dup 3) (match_dup 4)]
16365                               UNSPEC_FSCALE_FRACT))
16366               (set (match_dup 6)
16367                    (unspec:XF [(match_dup 3) (match_dup 4)]
16368                               UNSPEC_FSCALE_EXP))])
16369    (set (match_operand:DF 0 "register_operand" "")
16370         (float_truncate:DF (match_dup 5)))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16373    && flag_unsafe_math_optimizations"
16375   int i;
16377   for (i=3; i<7; i++)
16378     operands[i] = gen_reg_rtx (XFmode);
16381 (define_expand "ldexpsf3"
16382   [(set (match_dup 3)
16383         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16384    (set (match_dup 4)
16385         (float:XF (match_operand:SI 2 "register_operand" "")))
16386    (parallel [(set (match_dup 5)
16387                    (unspec:XF [(match_dup 3) (match_dup 4)]
16388                               UNSPEC_FSCALE_FRACT))
16389               (set (match_dup 6)
16390                    (unspec:XF [(match_dup 3) (match_dup 4)]
16391                               UNSPEC_FSCALE_EXP))])
16392    (set (match_operand:SF 0 "register_operand" "")
16393         (float_truncate:SF (match_dup 5)))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16398   int i;
16400   for (i=3; i<7; i++)
16401     operands[i] = gen_reg_rtx (XFmode);
16404 (define_expand "ldexpxf3"
16405   [(set (match_dup 3)
16406         (float:XF (match_operand:SI 2 "register_operand" "")))
16407    (parallel [(set (match_operand:XF 0 " register_operand" "")
16408                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16409                                (match_dup 3)]
16410                               UNSPEC_FSCALE_FRACT))
16411               (set (match_dup 4)
16412                    (unspec:XF [(match_dup 1) (match_dup 3)]
16413                               UNSPEC_FSCALE_EXP))])]
16414   "TARGET_USE_FANCY_MATH_387
16415    && flag_unsafe_math_optimizations"
16417   int i;
16419   for (i=3; i<5; i++)
16420     operands[i] = gen_reg_rtx (XFmode);
16424 (define_insn "frndintxf2"
16425   [(set (match_operand:XF 0 "register_operand" "=f")
16426         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16427          UNSPEC_FRNDINT))]
16428   "TARGET_USE_FANCY_MATH_387
16429    && flag_unsafe_math_optimizations"
16430   "frndint"
16431   [(set_attr "type" "fpspc")
16432    (set_attr "mode" "XF")])
16434 (define_expand "rintdf2"
16435   [(use (match_operand:DF 0 "register_operand" ""))
16436    (use (match_operand:DF 1 "register_operand" ""))]
16437   "TARGET_USE_FANCY_MATH_387
16438    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16439    && flag_unsafe_math_optimizations"
16441   rtx op0 = gen_reg_rtx (XFmode);
16442   rtx op1 = gen_reg_rtx (XFmode);
16444   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16445   emit_insn (gen_frndintxf2 (op0, op1));
16447   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16448   DONE;
16451 (define_expand "rintsf2"
16452   [(use (match_operand:SF 0 "register_operand" ""))
16453    (use (match_operand:SF 1 "register_operand" ""))]
16454   "TARGET_USE_FANCY_MATH_387
16455    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16456    && flag_unsafe_math_optimizations"
16458   rtx op0 = gen_reg_rtx (XFmode);
16459   rtx op1 = gen_reg_rtx (XFmode);
16461   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16462   emit_insn (gen_frndintxf2 (op0, op1));
16464   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16465   DONE;
16468 (define_expand "rintxf2"
16469   [(use (match_operand:XF 0 "register_operand" ""))
16470    (use (match_operand:XF 1 "register_operand" ""))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && flag_unsafe_math_optimizations"
16474   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16475   DONE;
16478 (define_insn_and_split "*fistdi2_1"
16479   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16480         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16481          UNSPEC_FIST))]
16482   "TARGET_USE_FANCY_MATH_387
16483    && flag_unsafe_math_optimizations
16484    && !(reload_completed || reload_in_progress)"
16485   "#"
16486   "&& 1"
16487   [(const_int 0)]
16489   if (memory_operand (operands[0], VOIDmode))
16490     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16491   else
16492     {
16493       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16494       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16495                                          operands[2]));
16496     }
16497   DONE;
16499   [(set_attr "type" "fpspc")
16500    (set_attr "mode" "DI")])
16502 (define_insn "fistdi2"
16503   [(set (match_operand:DI 0 "memory_operand" "=m")
16504         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16505          UNSPEC_FIST))
16506    (clobber (match_scratch:XF 2 "=&1f"))]
16507   "TARGET_USE_FANCY_MATH_387
16508    && flag_unsafe_math_optimizations"
16509   "* return output_fix_trunc (insn, operands, 0);"
16510   [(set_attr "type" "fpspc")
16511    (set_attr "mode" "DI")])
16513 (define_insn "fistdi2_with_temp"
16514   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16515         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16516          UNSPEC_FIST))
16517    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16519   "TARGET_USE_FANCY_MATH_387
16520    && flag_unsafe_math_optimizations"
16521   "#"
16522   [(set_attr "type" "fpspc")
16523    (set_attr "mode" "DI")])
16525 (define_split 
16526   [(set (match_operand:DI 0 "register_operand" "")
16527         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16528          UNSPEC_FIST))
16529    (clobber (match_operand:DI 2 "memory_operand" ""))
16530    (clobber (match_scratch 3 ""))]
16531   "reload_completed"
16532   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16533               (clobber (match_dup 3))])
16534    (set (match_dup 0) (match_dup 2))]
16535   "")
16537 (define_split 
16538   [(set (match_operand:DI 0 "memory_operand" "")
16539         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16540          UNSPEC_FIST))
16541    (clobber (match_operand:DI 2 "memory_operand" ""))
16542    (clobber (match_scratch 3 ""))]
16543   "reload_completed"
16544   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16545               (clobber (match_dup 3))])]
16546   "")
16548 (define_insn_and_split "*fist<mode>2_1"
16549   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16550         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16551          UNSPEC_FIST))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && flag_unsafe_math_optimizations
16554    && !(reload_completed || reload_in_progress)"
16555   "#"
16556   "&& 1"
16557   [(const_int 0)]
16559   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16560   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16561                                         operands[2]));
16562   DONE;
16564   [(set_attr "type" "fpspc")
16565    (set_attr "mode" "<MODE>")])
16567 (define_insn "fist<mode>2"
16568   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16569         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16570          UNSPEC_FIST))]
16571   "TARGET_USE_FANCY_MATH_387
16572    && flag_unsafe_math_optimizations"
16573   "* return output_fix_trunc (insn, operands, 0);"
16574   [(set_attr "type" "fpspc")
16575    (set_attr "mode" "<MODE>")])
16577 (define_insn "fist<mode>2_with_temp"
16578   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16579         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16580          UNSPEC_FIST))
16581    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16582   "TARGET_USE_FANCY_MATH_387
16583    && flag_unsafe_math_optimizations"
16584   "#"
16585   [(set_attr "type" "fpspc")
16586    (set_attr "mode" "<MODE>")])
16588 (define_split 
16589   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16590         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16591          UNSPEC_FIST))
16592    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16593   "reload_completed"
16594   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16595                        UNSPEC_FIST))
16596    (set (match_dup 0) (match_dup 2))]
16597   "")
16599 (define_split 
16600   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16601         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16602          UNSPEC_FIST))
16603    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16604   "reload_completed"
16605   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16606                        UNSPEC_FIST))]
16607   "")
16609 (define_expand "lrint<mode>2"
16610   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16611         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16612          UNSPEC_FIST))]
16613   "TARGET_USE_FANCY_MATH_387
16614    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16615    && flag_unsafe_math_optimizations"
16616   "")
16618 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16619 (define_insn_and_split "frndintxf2_floor"
16620   [(set (match_operand:XF 0 "register_operand" "=f")
16621         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16622          UNSPEC_FRNDINT_FLOOR))
16623    (clobber (reg:CC FLAGS_REG))]
16624   "TARGET_USE_FANCY_MATH_387
16625    && flag_unsafe_math_optimizations
16626    && !(reload_completed || reload_in_progress)"
16627   "#"
16628   "&& 1"
16629   [(const_int 0)]
16631   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16633   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16634   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16636   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16637                                         operands[2], operands[3]));
16638   DONE;
16640   [(set_attr "type" "frndint")
16641    (set_attr "i387_cw" "floor")
16642    (set_attr "mode" "XF")])
16644 (define_insn "frndintxf2_floor_i387"
16645   [(set (match_operand:XF 0 "register_operand" "=f")
16646         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16647          UNSPEC_FRNDINT_FLOOR))
16648    (use (match_operand:HI 2 "memory_operand" "m"))
16649    (use (match_operand:HI 3 "memory_operand" "m"))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && flag_unsafe_math_optimizations"
16652   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16653   [(set_attr "type" "frndint")
16654    (set_attr "i387_cw" "floor")
16655    (set_attr "mode" "XF")])
16657 (define_expand "floorxf2"
16658   [(use (match_operand:XF 0 "register_operand" ""))
16659    (use (match_operand:XF 1 "register_operand" ""))]
16660   "TARGET_USE_FANCY_MATH_387
16661    && flag_unsafe_math_optimizations"
16663   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16664   DONE;
16667 (define_expand "floordf2"
16668   [(use (match_operand:DF 0 "register_operand" ""))
16669    (use (match_operand:DF 1 "register_operand" ""))]
16670   "TARGET_USE_FANCY_MATH_387
16671    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations"
16674   rtx op0 = gen_reg_rtx (XFmode);
16675   rtx op1 = gen_reg_rtx (XFmode);
16677   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16678   emit_insn (gen_frndintxf2_floor (op0, op1));
16680   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16681   DONE;
16684 (define_expand "floorsf2"
16685   [(use (match_operand:SF 0 "register_operand" ""))
16686    (use (match_operand:SF 1 "register_operand" ""))]
16687   "TARGET_USE_FANCY_MATH_387
16688    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16689    && flag_unsafe_math_optimizations"
16691   rtx op0 = gen_reg_rtx (XFmode);
16692   rtx op1 = gen_reg_rtx (XFmode);
16694   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16695   emit_insn (gen_frndintxf2_floor (op0, op1));
16697   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16698   DONE;
16701 (define_insn_and_split "*fist<mode>2_floor_1"
16702   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16703         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16704          UNSPEC_FIST_FLOOR))
16705    (clobber (reg:CC FLAGS_REG))]
16706   "TARGET_USE_FANCY_MATH_387
16707    && flag_unsafe_math_optimizations
16708    && !(reload_completed || reload_in_progress)"
16709   "#"
16710   "&& 1"
16711   [(const_int 0)]
16713   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16715   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16716   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16717   if (memory_operand (operands[0], VOIDmode))
16718     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16719                                       operands[2], operands[3]));
16720   else
16721     {
16722       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16723       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16724                                                   operands[2], operands[3],
16725                                                   operands[4]));
16726     }
16727   DONE;
16729   [(set_attr "type" "fistp")
16730    (set_attr "i387_cw" "floor")
16731    (set_attr "mode" "<MODE>")])
16733 (define_insn "fistdi2_floor"
16734   [(set (match_operand:DI 0 "memory_operand" "=m")
16735         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16736          UNSPEC_FIST_FLOOR))
16737    (use (match_operand:HI 2 "memory_operand" "m"))
16738    (use (match_operand:HI 3 "memory_operand" "m"))
16739    (clobber (match_scratch:XF 4 "=&1f"))]
16740   "TARGET_USE_FANCY_MATH_387
16741    && flag_unsafe_math_optimizations"
16742   "* return output_fix_trunc (insn, operands, 0);"
16743   [(set_attr "type" "fistp")
16744    (set_attr "i387_cw" "floor")
16745    (set_attr "mode" "DI")])
16747 (define_insn "fistdi2_floor_with_temp"
16748   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16749         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16750          UNSPEC_FIST_FLOOR))
16751    (use (match_operand:HI 2 "memory_operand" "m,m"))
16752    (use (match_operand:HI 3 "memory_operand" "m,m"))
16753    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16754    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && flag_unsafe_math_optimizations"
16757   "#"
16758   [(set_attr "type" "fistp")
16759    (set_attr "i387_cw" "floor")
16760    (set_attr "mode" "DI")])
16762 (define_split 
16763   [(set (match_operand:DI 0 "register_operand" "")
16764         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16765          UNSPEC_FIST_FLOOR))
16766    (use (match_operand:HI 2 "memory_operand" ""))
16767    (use (match_operand:HI 3 "memory_operand" ""))
16768    (clobber (match_operand:DI 4 "memory_operand" ""))
16769    (clobber (match_scratch 5 ""))]
16770   "reload_completed"
16771   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16772               (use (match_dup 2))
16773               (use (match_dup 3))
16774               (clobber (match_dup 5))])
16775    (set (match_dup 0) (match_dup 4))]
16776   "")
16778 (define_split 
16779   [(set (match_operand:DI 0 "memory_operand" "")
16780         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16781          UNSPEC_FIST_FLOOR))
16782    (use (match_operand:HI 2 "memory_operand" ""))
16783    (use (match_operand:HI 3 "memory_operand" ""))
16784    (clobber (match_operand:DI 4 "memory_operand" ""))
16785    (clobber (match_scratch 5 ""))]
16786   "reload_completed"
16787   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16788               (use (match_dup 2))
16789               (use (match_dup 3))
16790               (clobber (match_dup 5))])]
16791   "")
16793 (define_insn "fist<mode>2_floor"
16794   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16795         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16796          UNSPEC_FIST_FLOOR))
16797    (use (match_operand:HI 2 "memory_operand" "m"))
16798    (use (match_operand:HI 3 "memory_operand" "m"))]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations"
16801   "* return output_fix_trunc (insn, operands, 0);"
16802   [(set_attr "type" "fistp")
16803    (set_attr "i387_cw" "floor")
16804    (set_attr "mode" "<MODE>")])
16806 (define_insn "fist<mode>2_floor_with_temp"
16807   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16808         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16809          UNSPEC_FIST_FLOOR))
16810    (use (match_operand:HI 2 "memory_operand" "m,m"))
16811    (use (match_operand:HI 3 "memory_operand" "m,m"))
16812    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16813   "TARGET_USE_FANCY_MATH_387
16814    && flag_unsafe_math_optimizations"
16815   "#"
16816   [(set_attr "type" "fistp")
16817    (set_attr "i387_cw" "floor")
16818    (set_attr "mode" "<MODE>")])
16820 (define_split 
16821   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16822         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16823          UNSPEC_FIST_FLOOR))
16824    (use (match_operand:HI 2 "memory_operand" ""))
16825    (use (match_operand:HI 3 "memory_operand" ""))
16826    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16827   "reload_completed"
16828   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16829                                   UNSPEC_FIST_FLOOR))
16830               (use (match_dup 2))
16831               (use (match_dup 3))])
16832    (set (match_dup 0) (match_dup 4))]
16833   "")
16835 (define_split 
16836   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16837         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16838          UNSPEC_FIST_FLOOR))
16839    (use (match_operand:HI 2 "memory_operand" ""))
16840    (use (match_operand:HI 3 "memory_operand" ""))
16841    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16842   "reload_completed"
16843   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16844                                   UNSPEC_FIST_FLOOR))
16845               (use (match_dup 2))
16846               (use (match_dup 3))])]
16847   "")
16849 (define_expand "lfloor<mode>2"
16850   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16851                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16852                     UNSPEC_FIST_FLOOR))
16853               (clobber (reg:CC FLAGS_REG))])]
16854   "TARGET_USE_FANCY_MATH_387
16855    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16856    && flag_unsafe_math_optimizations"
16857   "")
16859 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16860 (define_insn_and_split "frndintxf2_ceil"
16861   [(set (match_operand:XF 0 "register_operand" "=f")
16862         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16863          UNSPEC_FRNDINT_CEIL))
16864    (clobber (reg:CC FLAGS_REG))]
16865   "TARGET_USE_FANCY_MATH_387
16866    && flag_unsafe_math_optimizations
16867    && !(reload_completed || reload_in_progress)"
16868   "#"
16869   "&& 1"
16870   [(const_int 0)]
16872   ix86_optimize_mode_switching[I387_CEIL] = 1;
16874   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16875   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16877   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16878                                        operands[2], operands[3]));
16879   DONE;
16881   [(set_attr "type" "frndint")
16882    (set_attr "i387_cw" "ceil")
16883    (set_attr "mode" "XF")])
16885 (define_insn "frndintxf2_ceil_i387"
16886   [(set (match_operand:XF 0 "register_operand" "=f")
16887         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16888          UNSPEC_FRNDINT_CEIL))
16889    (use (match_operand:HI 2 "memory_operand" "m"))
16890    (use (match_operand:HI 3 "memory_operand" "m"))]
16891   "TARGET_USE_FANCY_MATH_387
16892    && flag_unsafe_math_optimizations"
16893   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16894   [(set_attr "type" "frndint")
16895    (set_attr "i387_cw" "ceil")
16896    (set_attr "mode" "XF")])
16898 (define_expand "ceilxf2"
16899   [(use (match_operand:XF 0 "register_operand" ""))
16900    (use (match_operand:XF 1 "register_operand" ""))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && flag_unsafe_math_optimizations"
16904   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16905   DONE;
16908 (define_expand "ceildf2"
16909   [(use (match_operand:DF 0 "register_operand" ""))
16910    (use (match_operand:DF 1 "register_operand" ""))]
16911   "TARGET_USE_FANCY_MATH_387
16912    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16913    && flag_unsafe_math_optimizations"
16915   rtx op0 = gen_reg_rtx (XFmode);
16916   rtx op1 = gen_reg_rtx (XFmode);
16918   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16919   emit_insn (gen_frndintxf2_ceil (op0, op1));
16921   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16922   DONE;
16925 (define_expand "ceilsf2"
16926   [(use (match_operand:SF 0 "register_operand" ""))
16927    (use (match_operand:SF 1 "register_operand" ""))]
16928   "TARGET_USE_FANCY_MATH_387
16929    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16930    && flag_unsafe_math_optimizations"
16932   rtx op0 = gen_reg_rtx (XFmode);
16933   rtx op1 = gen_reg_rtx (XFmode);
16935   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16936   emit_insn (gen_frndintxf2_ceil (op0, op1));
16938   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16939   DONE;
16942 (define_insn_and_split "*fist<mode>2_ceil_1"
16943   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16944         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16945          UNSPEC_FIST_CEIL))
16946    (clobber (reg:CC FLAGS_REG))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && flag_unsafe_math_optimizations
16949    && !(reload_completed || reload_in_progress)"
16950   "#"
16951   "&& 1"
16952   [(const_int 0)]
16954   ix86_optimize_mode_switching[I387_CEIL] = 1;
16956   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16957   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16958   if (memory_operand (operands[0], VOIDmode))
16959     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16960                                      operands[2], operands[3]));
16961   else
16962     {
16963       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16964       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16965                                                  operands[2], operands[3],
16966                                                  operands[4]));
16967     }
16968   DONE;
16970   [(set_attr "type" "fistp")
16971    (set_attr "i387_cw" "ceil")
16972    (set_attr "mode" "<MODE>")])
16974 (define_insn "fistdi2_ceil"
16975   [(set (match_operand:DI 0 "memory_operand" "=m")
16976         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16977          UNSPEC_FIST_CEIL))
16978    (use (match_operand:HI 2 "memory_operand" "m"))
16979    (use (match_operand:HI 3 "memory_operand" "m"))
16980    (clobber (match_scratch:XF 4 "=&1f"))]
16981   "TARGET_USE_FANCY_MATH_387
16982    && flag_unsafe_math_optimizations"
16983   "* return output_fix_trunc (insn, operands, 0);"
16984   [(set_attr "type" "fistp")
16985    (set_attr "i387_cw" "ceil")
16986    (set_attr "mode" "DI")])
16988 (define_insn "fistdi2_ceil_with_temp"
16989   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16990         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16991          UNSPEC_FIST_CEIL))
16992    (use (match_operand:HI 2 "memory_operand" "m,m"))
16993    (use (match_operand:HI 3 "memory_operand" "m,m"))
16994    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16995    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16996   "TARGET_USE_FANCY_MATH_387
16997    && flag_unsafe_math_optimizations"
16998   "#"
16999   [(set_attr "type" "fistp")
17000    (set_attr "i387_cw" "ceil")
17001    (set_attr "mode" "DI")])
17003 (define_split 
17004   [(set (match_operand:DI 0 "register_operand" "")
17005         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17006          UNSPEC_FIST_CEIL))
17007    (use (match_operand:HI 2 "memory_operand" ""))
17008    (use (match_operand:HI 3 "memory_operand" ""))
17009    (clobber (match_operand:DI 4 "memory_operand" ""))
17010    (clobber (match_scratch 5 ""))]
17011   "reload_completed"
17012   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17013               (use (match_dup 2))
17014               (use (match_dup 3))
17015               (clobber (match_dup 5))])
17016    (set (match_dup 0) (match_dup 4))]
17017   "")
17019 (define_split 
17020   [(set (match_operand:DI 0 "memory_operand" "")
17021         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17022          UNSPEC_FIST_CEIL))
17023    (use (match_operand:HI 2 "memory_operand" ""))
17024    (use (match_operand:HI 3 "memory_operand" ""))
17025    (clobber (match_operand:DI 4 "memory_operand" ""))
17026    (clobber (match_scratch 5 ""))]
17027   "reload_completed"
17028   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17029               (use (match_dup 2))
17030               (use (match_dup 3))
17031               (clobber (match_dup 5))])]
17032   "")
17034 (define_insn "fist<mode>2_ceil"
17035   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17036         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17037          UNSPEC_FIST_CEIL))
17038    (use (match_operand:HI 2 "memory_operand" "m"))
17039    (use (match_operand:HI 3 "memory_operand" "m"))]
17040   "TARGET_USE_FANCY_MATH_387
17041    && flag_unsafe_math_optimizations"
17042   "* return output_fix_trunc (insn, operands, 0);"
17043   [(set_attr "type" "fistp")
17044    (set_attr "i387_cw" "ceil")
17045    (set_attr "mode" "<MODE>")])
17047 (define_insn "fist<mode>2_ceil_with_temp"
17048   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17049         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17050          UNSPEC_FIST_CEIL))
17051    (use (match_operand:HI 2 "memory_operand" "m,m"))
17052    (use (match_operand:HI 3 "memory_operand" "m,m"))
17053    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17054   "TARGET_USE_FANCY_MATH_387
17055    && flag_unsafe_math_optimizations"
17056   "#"
17057   [(set_attr "type" "fistp")
17058    (set_attr "i387_cw" "ceil")
17059    (set_attr "mode" "<MODE>")])
17061 (define_split 
17062   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17063         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17064          UNSPEC_FIST_CEIL))
17065    (use (match_operand:HI 2 "memory_operand" ""))
17066    (use (match_operand:HI 3 "memory_operand" ""))
17067    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17068   "reload_completed"
17069   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17070                                   UNSPEC_FIST_CEIL))
17071               (use (match_dup 2))
17072               (use (match_dup 3))])
17073    (set (match_dup 0) (match_dup 4))]
17074   "")
17076 (define_split 
17077   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17078         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17079          UNSPEC_FIST_CEIL))
17080    (use (match_operand:HI 2 "memory_operand" ""))
17081    (use (match_operand:HI 3 "memory_operand" ""))
17082    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17083   "reload_completed"
17084   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17085                                   UNSPEC_FIST_CEIL))
17086               (use (match_dup 2))
17087               (use (match_dup 3))])]
17088   "")
17090 (define_expand "lceil<mode>2"
17091   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17092                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17093                     UNSPEC_FIST_CEIL))
17094               (clobber (reg:CC FLAGS_REG))])]
17095   "TARGET_USE_FANCY_MATH_387
17096    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17097    && flag_unsafe_math_optimizations"
17098   "")
17100 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17101 (define_insn_and_split "frndintxf2_trunc"
17102   [(set (match_operand:XF 0 "register_operand" "=f")
17103         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17104          UNSPEC_FRNDINT_TRUNC))
17105    (clobber (reg:CC FLAGS_REG))]
17106   "TARGET_USE_FANCY_MATH_387
17107    && flag_unsafe_math_optimizations
17108    && !(reload_completed || reload_in_progress)"
17109   "#"
17110   "&& 1"
17111   [(const_int 0)]
17113   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17115   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17116   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17118   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17119                                         operands[2], operands[3]));
17120   DONE;
17122   [(set_attr "type" "frndint")
17123    (set_attr "i387_cw" "trunc")
17124    (set_attr "mode" "XF")])
17126 (define_insn "frndintxf2_trunc_i387"
17127   [(set (match_operand:XF 0 "register_operand" "=f")
17128         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17129          UNSPEC_FRNDINT_TRUNC))
17130    (use (match_operand:HI 2 "memory_operand" "m"))
17131    (use (match_operand:HI 3 "memory_operand" "m"))]
17132   "TARGET_USE_FANCY_MATH_387
17133    && flag_unsafe_math_optimizations"
17134   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17135   [(set_attr "type" "frndint")
17136    (set_attr "i387_cw" "trunc")
17137    (set_attr "mode" "XF")])
17139 (define_expand "btruncxf2"
17140   [(use (match_operand:XF 0 "register_operand" ""))
17141    (use (match_operand:XF 1 "register_operand" ""))]
17142   "TARGET_USE_FANCY_MATH_387
17143    && flag_unsafe_math_optimizations"
17145   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17146   DONE;
17149 (define_expand "btruncdf2"
17150   [(use (match_operand:DF 0 "register_operand" ""))
17151    (use (match_operand:DF 1 "register_operand" ""))]
17152   "TARGET_USE_FANCY_MATH_387
17153    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17154    && flag_unsafe_math_optimizations"
17156   rtx op0 = gen_reg_rtx (XFmode);
17157   rtx op1 = gen_reg_rtx (XFmode);
17159   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17160   emit_insn (gen_frndintxf2_trunc (op0, op1));
17162   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17163   DONE;
17166 (define_expand "btruncsf2"
17167   [(use (match_operand:SF 0 "register_operand" ""))
17168    (use (match_operand:SF 1 "register_operand" ""))]
17169   "TARGET_USE_FANCY_MATH_387
17170    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17171    && flag_unsafe_math_optimizations"
17173   rtx op0 = gen_reg_rtx (XFmode);
17174   rtx op1 = gen_reg_rtx (XFmode);
17176   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17177   emit_insn (gen_frndintxf2_trunc (op0, op1));
17179   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17180   DONE;
17183 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17184 (define_insn_and_split "frndintxf2_mask_pm"
17185   [(set (match_operand:XF 0 "register_operand" "=f")
17186         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17187          UNSPEC_FRNDINT_MASK_PM))
17188    (clobber (reg:CC FLAGS_REG))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations
17191    && !(reload_completed || reload_in_progress)"
17192   "#"
17193   "&& 1"
17194   [(const_int 0)]
17196   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17198   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17199   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17201   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17202                                           operands[2], operands[3]));
17203   DONE;
17205   [(set_attr "type" "frndint")
17206    (set_attr "i387_cw" "mask_pm")
17207    (set_attr "mode" "XF")])
17209 (define_insn "frndintxf2_mask_pm_i387"
17210   [(set (match_operand:XF 0 "register_operand" "=f")
17211         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17212          UNSPEC_FRNDINT_MASK_PM))
17213    (use (match_operand:HI 2 "memory_operand" "m"))
17214    (use (match_operand:HI 3 "memory_operand" "m"))]
17215   "TARGET_USE_FANCY_MATH_387
17216    && flag_unsafe_math_optimizations"
17217   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17218   [(set_attr "type" "frndint")
17219    (set_attr "i387_cw" "mask_pm")
17220    (set_attr "mode" "XF")])
17222 (define_expand "nearbyintxf2"
17223   [(use (match_operand:XF 0 "register_operand" ""))
17224    (use (match_operand:XF 1 "register_operand" ""))]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations"
17228   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17230   DONE;
17233 (define_expand "nearbyintdf2"
17234   [(use (match_operand:DF 0 "register_operand" ""))
17235    (use (match_operand:DF 1 "register_operand" ""))]
17236   "TARGET_USE_FANCY_MATH_387
17237    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17238    && flag_unsafe_math_optimizations"
17240   rtx op0 = gen_reg_rtx (XFmode);
17241   rtx op1 = gen_reg_rtx (XFmode);
17243   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17244   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17246   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17247   DONE;
17250 (define_expand "nearbyintsf2"
17251   [(use (match_operand:SF 0 "register_operand" ""))
17252    (use (match_operand:SF 1 "register_operand" ""))]
17253   "TARGET_USE_FANCY_MATH_387
17254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17255    && flag_unsafe_math_optimizations"
17257   rtx op0 = gen_reg_rtx (XFmode);
17258   rtx op1 = gen_reg_rtx (XFmode);
17260   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17261   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17263   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17264   DONE;
17268 ;; Block operation instructions
17270 (define_insn "cld"
17271  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17272  ""
17273  "cld"
17274   [(set_attr "type" "cld")])
17276 (define_expand "movmemsi"
17277   [(use (match_operand:BLK 0 "memory_operand" ""))
17278    (use (match_operand:BLK 1 "memory_operand" ""))
17279    (use (match_operand:SI 2 "nonmemory_operand" ""))
17280    (use (match_operand:SI 3 "const_int_operand" ""))]
17281   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17283  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17284    DONE;
17285  else
17286    FAIL;
17289 (define_expand "movmemdi"
17290   [(use (match_operand:BLK 0 "memory_operand" ""))
17291    (use (match_operand:BLK 1 "memory_operand" ""))
17292    (use (match_operand:DI 2 "nonmemory_operand" ""))
17293    (use (match_operand:DI 3 "const_int_operand" ""))]
17294   "TARGET_64BIT"
17296  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17297    DONE;
17298  else
17299    FAIL;
17302 ;; Most CPUs don't like single string operations
17303 ;; Handle this case here to simplify previous expander.
17305 (define_expand "strmov"
17306   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17307    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17308    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17309               (clobber (reg:CC FLAGS_REG))])
17310    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17311               (clobber (reg:CC FLAGS_REG))])]
17312   ""
17314   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17316   /* If .md ever supports :P for Pmode, these can be directly
17317      in the pattern above.  */
17318   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17319   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17321   if (TARGET_SINGLE_STRINGOP || optimize_size)
17322     {
17323       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17324                                       operands[2], operands[3],
17325                                       operands[5], operands[6]));
17326       DONE;
17327     }
17329   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17332 (define_expand "strmov_singleop"
17333   [(parallel [(set (match_operand 1 "memory_operand" "")
17334                    (match_operand 3 "memory_operand" ""))
17335               (set (match_operand 0 "register_operand" "")
17336                    (match_operand 4 "" ""))
17337               (set (match_operand 2 "register_operand" "")
17338                    (match_operand 5 "" ""))
17339               (use (reg:SI DIRFLAG_REG))])]
17340   "TARGET_SINGLE_STRINGOP || optimize_size"
17341   "")
17343 (define_insn "*strmovdi_rex_1"
17344   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17345         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17346    (set (match_operand:DI 0 "register_operand" "=D")
17347         (plus:DI (match_dup 2)
17348                  (const_int 8)))
17349    (set (match_operand:DI 1 "register_operand" "=S")
17350         (plus:DI (match_dup 3)
17351                  (const_int 8)))
17352    (use (reg:SI DIRFLAG_REG))]
17353   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17354   "movsq"
17355   [(set_attr "type" "str")
17356    (set_attr "mode" "DI")
17357    (set_attr "memory" "both")])
17359 (define_insn "*strmovsi_1"
17360   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17361         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17362    (set (match_operand:SI 0 "register_operand" "=D")
17363         (plus:SI (match_dup 2)
17364                  (const_int 4)))
17365    (set (match_operand:SI 1 "register_operand" "=S")
17366         (plus:SI (match_dup 3)
17367                  (const_int 4)))
17368    (use (reg:SI DIRFLAG_REG))]
17369   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17370   "{movsl|movsd}"
17371   [(set_attr "type" "str")
17372    (set_attr "mode" "SI")
17373    (set_attr "memory" "both")])
17375 (define_insn "*strmovsi_rex_1"
17376   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17377         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17378    (set (match_operand:DI 0 "register_operand" "=D")
17379         (plus:DI (match_dup 2)
17380                  (const_int 4)))
17381    (set (match_operand:DI 1 "register_operand" "=S")
17382         (plus:DI (match_dup 3)
17383                  (const_int 4)))
17384    (use (reg:SI DIRFLAG_REG))]
17385   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17386   "{movsl|movsd}"
17387   [(set_attr "type" "str")
17388    (set_attr "mode" "SI")
17389    (set_attr "memory" "both")])
17391 (define_insn "*strmovhi_1"
17392   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17393         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17394    (set (match_operand:SI 0 "register_operand" "=D")
17395         (plus:SI (match_dup 2)
17396                  (const_int 2)))
17397    (set (match_operand:SI 1 "register_operand" "=S")
17398         (plus:SI (match_dup 3)
17399                  (const_int 2)))
17400    (use (reg:SI DIRFLAG_REG))]
17401   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17402   "movsw"
17403   [(set_attr "type" "str")
17404    (set_attr "memory" "both")
17405    (set_attr "mode" "HI")])
17407 (define_insn "*strmovhi_rex_1"
17408   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17409         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17410    (set (match_operand:DI 0 "register_operand" "=D")
17411         (plus:DI (match_dup 2)
17412                  (const_int 2)))
17413    (set (match_operand:DI 1 "register_operand" "=S")
17414         (plus:DI (match_dup 3)
17415                  (const_int 2)))
17416    (use (reg:SI DIRFLAG_REG))]
17417   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17418   "movsw"
17419   [(set_attr "type" "str")
17420    (set_attr "memory" "both")
17421    (set_attr "mode" "HI")])
17423 (define_insn "*strmovqi_1"
17424   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17425         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17426    (set (match_operand:SI 0 "register_operand" "=D")
17427         (plus:SI (match_dup 2)
17428                  (const_int 1)))
17429    (set (match_operand:SI 1 "register_operand" "=S")
17430         (plus:SI (match_dup 3)
17431                  (const_int 1)))
17432    (use (reg:SI DIRFLAG_REG))]
17433   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17434   "movsb"
17435   [(set_attr "type" "str")
17436    (set_attr "memory" "both")
17437    (set_attr "mode" "QI")])
17439 (define_insn "*strmovqi_rex_1"
17440   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17441         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17442    (set (match_operand:DI 0 "register_operand" "=D")
17443         (plus:DI (match_dup 2)
17444                  (const_int 1)))
17445    (set (match_operand:DI 1 "register_operand" "=S")
17446         (plus:DI (match_dup 3)
17447                  (const_int 1)))
17448    (use (reg:SI DIRFLAG_REG))]
17449   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17450   "movsb"
17451   [(set_attr "type" "str")
17452    (set_attr "memory" "both")
17453    (set_attr "mode" "QI")])
17455 (define_expand "rep_mov"
17456   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17457               (set (match_operand 0 "register_operand" "")
17458                    (match_operand 5 "" ""))
17459               (set (match_operand 2 "register_operand" "")
17460                    (match_operand 6 "" ""))
17461               (set (match_operand 1 "memory_operand" "")
17462                    (match_operand 3 "memory_operand" ""))
17463               (use (match_dup 4))
17464               (use (reg:SI DIRFLAG_REG))])]
17465   ""
17466   "")
17468 (define_insn "*rep_movdi_rex64"
17469   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17470    (set (match_operand:DI 0 "register_operand" "=D") 
17471         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17472                             (const_int 3))
17473                  (match_operand:DI 3 "register_operand" "0")))
17474    (set (match_operand:DI 1 "register_operand" "=S") 
17475         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17476                  (match_operand:DI 4 "register_operand" "1")))
17477    (set (mem:BLK (match_dup 3))
17478         (mem:BLK (match_dup 4)))
17479    (use (match_dup 5))
17480    (use (reg:SI DIRFLAG_REG))]
17481   "TARGET_64BIT"
17482   "{rep\;movsq|rep movsq}"
17483   [(set_attr "type" "str")
17484    (set_attr "prefix_rep" "1")
17485    (set_attr "memory" "both")
17486    (set_attr "mode" "DI")])
17488 (define_insn "*rep_movsi"
17489   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17490    (set (match_operand:SI 0 "register_operand" "=D") 
17491         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17492                             (const_int 2))
17493                  (match_operand:SI 3 "register_operand" "0")))
17494    (set (match_operand:SI 1 "register_operand" "=S") 
17495         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17496                  (match_operand:SI 4 "register_operand" "1")))
17497    (set (mem:BLK (match_dup 3))
17498         (mem:BLK (match_dup 4)))
17499    (use (match_dup 5))
17500    (use (reg:SI DIRFLAG_REG))]
17501   "!TARGET_64BIT"
17502   "{rep\;movsl|rep movsd}"
17503   [(set_attr "type" "str")
17504    (set_attr "prefix_rep" "1")
17505    (set_attr "memory" "both")
17506    (set_attr "mode" "SI")])
17508 (define_insn "*rep_movsi_rex64"
17509   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17510    (set (match_operand:DI 0 "register_operand" "=D") 
17511         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17512                             (const_int 2))
17513                  (match_operand:DI 3 "register_operand" "0")))
17514    (set (match_operand:DI 1 "register_operand" "=S") 
17515         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17516                  (match_operand:DI 4 "register_operand" "1")))
17517    (set (mem:BLK (match_dup 3))
17518         (mem:BLK (match_dup 4)))
17519    (use (match_dup 5))
17520    (use (reg:SI DIRFLAG_REG))]
17521   "TARGET_64BIT"
17522   "{rep\;movsl|rep movsd}"
17523   [(set_attr "type" "str")
17524    (set_attr "prefix_rep" "1")
17525    (set_attr "memory" "both")
17526    (set_attr "mode" "SI")])
17528 (define_insn "*rep_movqi"
17529   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17530    (set (match_operand:SI 0 "register_operand" "=D") 
17531         (plus:SI (match_operand:SI 3 "register_operand" "0")
17532                  (match_operand:SI 5 "register_operand" "2")))
17533    (set (match_operand:SI 1 "register_operand" "=S") 
17534         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17535    (set (mem:BLK (match_dup 3))
17536         (mem:BLK (match_dup 4)))
17537    (use (match_dup 5))
17538    (use (reg:SI DIRFLAG_REG))]
17539   "!TARGET_64BIT"
17540   "{rep\;movsb|rep movsb}"
17541   [(set_attr "type" "str")
17542    (set_attr "prefix_rep" "1")
17543    (set_attr "memory" "both")
17544    (set_attr "mode" "SI")])
17546 (define_insn "*rep_movqi_rex64"
17547   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17548    (set (match_operand:DI 0 "register_operand" "=D") 
17549         (plus:DI (match_operand:DI 3 "register_operand" "0")
17550                  (match_operand:DI 5 "register_operand" "2")))
17551    (set (match_operand:DI 1 "register_operand" "=S") 
17552         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17553    (set (mem:BLK (match_dup 3))
17554         (mem:BLK (match_dup 4)))
17555    (use (match_dup 5))
17556    (use (reg:SI DIRFLAG_REG))]
17557   "TARGET_64BIT"
17558   "{rep\;movsb|rep movsb}"
17559   [(set_attr "type" "str")
17560    (set_attr "prefix_rep" "1")
17561    (set_attr "memory" "both")
17562    (set_attr "mode" "SI")])
17564 (define_expand "setmemsi"
17565    [(use (match_operand:BLK 0 "memory_operand" ""))
17566     (use (match_operand:SI 1 "nonmemory_operand" ""))
17567     (use (match_operand 2 "const_int_operand" ""))
17568     (use (match_operand 3 "const_int_operand" ""))]
17569   ""
17571  /* If value to set is not zero, use the library routine.  */
17572  if (operands[2] != const0_rtx)
17573    FAIL;
17575  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17576    DONE;
17577  else
17578    FAIL;
17581 (define_expand "setmemdi"
17582    [(use (match_operand:BLK 0 "memory_operand" ""))
17583     (use (match_operand:DI 1 "nonmemory_operand" ""))
17584     (use (match_operand 2 "const_int_operand" ""))
17585     (use (match_operand 3 "const_int_operand" ""))]
17586   "TARGET_64BIT"
17588  /* If value to set is not zero, use the library routine.  */
17589  if (operands[2] != const0_rtx)
17590    FAIL;
17592  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17593    DONE;
17594  else
17595    FAIL;
17598 ;; Most CPUs don't like single string operations
17599 ;; Handle this case here to simplify previous expander.
17601 (define_expand "strset"
17602   [(set (match_operand 1 "memory_operand" "")
17603         (match_operand 2 "register_operand" ""))
17604    (parallel [(set (match_operand 0 "register_operand" "")
17605                    (match_dup 3))
17606               (clobber (reg:CC FLAGS_REG))])]
17607   ""
17609   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17610     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17612   /* If .md ever supports :P for Pmode, this can be directly
17613      in the pattern above.  */
17614   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17615                               GEN_INT (GET_MODE_SIZE (GET_MODE
17616                                                       (operands[2]))));
17617   if (TARGET_SINGLE_STRINGOP || optimize_size)
17618     {
17619       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17620                                       operands[3]));
17621       DONE;
17622     }
17625 (define_expand "strset_singleop"
17626   [(parallel [(set (match_operand 1 "memory_operand" "")
17627                    (match_operand 2 "register_operand" ""))
17628               (set (match_operand 0 "register_operand" "")
17629                    (match_operand 3 "" ""))
17630               (use (reg:SI DIRFLAG_REG))])]
17631   "TARGET_SINGLE_STRINGOP || optimize_size"
17632   "")
17634 (define_insn "*strsetdi_rex_1"
17635   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17636         (match_operand:DI 2 "register_operand" "a"))
17637    (set (match_operand:DI 0 "register_operand" "=D")
17638         (plus:DI (match_dup 1)
17639                  (const_int 8)))
17640    (use (reg:SI DIRFLAG_REG))]
17641   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17642   "stosq"
17643   [(set_attr "type" "str")
17644    (set_attr "memory" "store")
17645    (set_attr "mode" "DI")])
17647 (define_insn "*strsetsi_1"
17648   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17649         (match_operand:SI 2 "register_operand" "a"))
17650    (set (match_operand:SI 0 "register_operand" "=D")
17651         (plus:SI (match_dup 1)
17652                  (const_int 4)))
17653    (use (reg:SI DIRFLAG_REG))]
17654   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17655   "{stosl|stosd}"
17656   [(set_attr "type" "str")
17657    (set_attr "memory" "store")
17658    (set_attr "mode" "SI")])
17660 (define_insn "*strsetsi_rex_1"
17661   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17662         (match_operand:SI 2 "register_operand" "a"))
17663    (set (match_operand:DI 0 "register_operand" "=D")
17664         (plus:DI (match_dup 1)
17665                  (const_int 4)))
17666    (use (reg:SI DIRFLAG_REG))]
17667   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17668   "{stosl|stosd}"
17669   [(set_attr "type" "str")
17670    (set_attr "memory" "store")
17671    (set_attr "mode" "SI")])
17673 (define_insn "*strsethi_1"
17674   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17675         (match_operand:HI 2 "register_operand" "a"))
17676    (set (match_operand:SI 0 "register_operand" "=D")
17677         (plus:SI (match_dup 1)
17678                  (const_int 2)))
17679    (use (reg:SI DIRFLAG_REG))]
17680   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17681   "stosw"
17682   [(set_attr "type" "str")
17683    (set_attr "memory" "store")
17684    (set_attr "mode" "HI")])
17686 (define_insn "*strsethi_rex_1"
17687   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17688         (match_operand:HI 2 "register_operand" "a"))
17689    (set (match_operand:DI 0 "register_operand" "=D")
17690         (plus:DI (match_dup 1)
17691                  (const_int 2)))
17692    (use (reg:SI DIRFLAG_REG))]
17693   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17694   "stosw"
17695   [(set_attr "type" "str")
17696    (set_attr "memory" "store")
17697    (set_attr "mode" "HI")])
17699 (define_insn "*strsetqi_1"
17700   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17701         (match_operand:QI 2 "register_operand" "a"))
17702    (set (match_operand:SI 0 "register_operand" "=D")
17703         (plus:SI (match_dup 1)
17704                  (const_int 1)))
17705    (use (reg:SI DIRFLAG_REG))]
17706   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17707   "stosb"
17708   [(set_attr "type" "str")
17709    (set_attr "memory" "store")
17710    (set_attr "mode" "QI")])
17712 (define_insn "*strsetqi_rex_1"
17713   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17714         (match_operand:QI 2 "register_operand" "a"))
17715    (set (match_operand:DI 0 "register_operand" "=D")
17716         (plus:DI (match_dup 1)
17717                  (const_int 1)))
17718    (use (reg:SI DIRFLAG_REG))]
17719   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17720   "stosb"
17721   [(set_attr "type" "str")
17722    (set_attr "memory" "store")
17723    (set_attr "mode" "QI")])
17725 (define_expand "rep_stos"
17726   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17727               (set (match_operand 0 "register_operand" "")
17728                    (match_operand 4 "" ""))
17729               (set (match_operand 2 "memory_operand" "") (const_int 0))
17730               (use (match_operand 3 "register_operand" ""))
17731               (use (match_dup 1))
17732               (use (reg:SI DIRFLAG_REG))])]
17733   ""
17734   "")
17736 (define_insn "*rep_stosdi_rex64"
17737   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17738    (set (match_operand:DI 0 "register_operand" "=D") 
17739         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17740                             (const_int 3))
17741                  (match_operand:DI 3 "register_operand" "0")))
17742    (set (mem:BLK (match_dup 3))
17743         (const_int 0))
17744    (use (match_operand:DI 2 "register_operand" "a"))
17745    (use (match_dup 4))
17746    (use (reg:SI DIRFLAG_REG))]
17747   "TARGET_64BIT"
17748   "{rep\;stosq|rep stosq}"
17749   [(set_attr "type" "str")
17750    (set_attr "prefix_rep" "1")
17751    (set_attr "memory" "store")
17752    (set_attr "mode" "DI")])
17754 (define_insn "*rep_stossi"
17755   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17756    (set (match_operand:SI 0 "register_operand" "=D") 
17757         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17758                             (const_int 2))
17759                  (match_operand:SI 3 "register_operand" "0")))
17760    (set (mem:BLK (match_dup 3))
17761         (const_int 0))
17762    (use (match_operand:SI 2 "register_operand" "a"))
17763    (use (match_dup 4))
17764    (use (reg:SI DIRFLAG_REG))]
17765   "!TARGET_64BIT"
17766   "{rep\;stosl|rep stosd}"
17767   [(set_attr "type" "str")
17768    (set_attr "prefix_rep" "1")
17769    (set_attr "memory" "store")
17770    (set_attr "mode" "SI")])
17772 (define_insn "*rep_stossi_rex64"
17773   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17774    (set (match_operand:DI 0 "register_operand" "=D") 
17775         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17776                             (const_int 2))
17777                  (match_operand:DI 3 "register_operand" "0")))
17778    (set (mem:BLK (match_dup 3))
17779         (const_int 0))
17780    (use (match_operand:SI 2 "register_operand" "a"))
17781    (use (match_dup 4))
17782    (use (reg:SI DIRFLAG_REG))]
17783   "TARGET_64BIT"
17784   "{rep\;stosl|rep stosd}"
17785   [(set_attr "type" "str")
17786    (set_attr "prefix_rep" "1")
17787    (set_attr "memory" "store")
17788    (set_attr "mode" "SI")])
17790 (define_insn "*rep_stosqi"
17791   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17792    (set (match_operand:SI 0 "register_operand" "=D") 
17793         (plus:SI (match_operand:SI 3 "register_operand" "0")
17794                  (match_operand:SI 4 "register_operand" "1")))
17795    (set (mem:BLK (match_dup 3))
17796         (const_int 0))
17797    (use (match_operand:QI 2 "register_operand" "a"))
17798    (use (match_dup 4))
17799    (use (reg:SI DIRFLAG_REG))]
17800   "!TARGET_64BIT"
17801   "{rep\;stosb|rep stosb}"
17802   [(set_attr "type" "str")
17803    (set_attr "prefix_rep" "1")
17804    (set_attr "memory" "store")
17805    (set_attr "mode" "QI")])
17807 (define_insn "*rep_stosqi_rex64"
17808   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17809    (set (match_operand:DI 0 "register_operand" "=D") 
17810         (plus:DI (match_operand:DI 3 "register_operand" "0")
17811                  (match_operand:DI 4 "register_operand" "1")))
17812    (set (mem:BLK (match_dup 3))
17813         (const_int 0))
17814    (use (match_operand:QI 2 "register_operand" "a"))
17815    (use (match_dup 4))
17816    (use (reg:SI DIRFLAG_REG))]
17817   "TARGET_64BIT"
17818   "{rep\;stosb|rep stosb}"
17819   [(set_attr "type" "str")
17820    (set_attr "prefix_rep" "1")
17821    (set_attr "memory" "store")
17822    (set_attr "mode" "QI")])
17824 (define_expand "cmpstrnsi"
17825   [(set (match_operand:SI 0 "register_operand" "")
17826         (compare:SI (match_operand:BLK 1 "general_operand" "")
17827                     (match_operand:BLK 2 "general_operand" "")))
17828    (use (match_operand 3 "general_operand" ""))
17829    (use (match_operand 4 "immediate_operand" ""))]
17830   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17832   rtx addr1, addr2, out, outlow, count, countreg, align;
17834   /* Can't use this if the user has appropriated esi or edi.  */
17835   if (global_regs[4] || global_regs[5])
17836     FAIL;
17838   out = operands[0];
17839   if (GET_CODE (out) != REG)
17840     out = gen_reg_rtx (SImode);
17842   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17843   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17844   if (addr1 != XEXP (operands[1], 0))
17845     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17846   if (addr2 != XEXP (operands[2], 0))
17847     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17849   count = operands[3];
17850   countreg = ix86_zero_extend_to_Pmode (count);
17852   /* %%% Iff we are testing strict equality, we can use known alignment
17853      to good advantage.  This may be possible with combine, particularly
17854      once cc0 is dead.  */
17855   align = operands[4];
17857   emit_insn (gen_cld ());
17858   if (GET_CODE (count) == CONST_INT)
17859     {
17860       if (INTVAL (count) == 0)
17861         {
17862           emit_move_insn (operands[0], const0_rtx);
17863           DONE;
17864         }
17865       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17866                                      operands[1], operands[2]));
17867     }
17868   else
17869     {
17870       if (TARGET_64BIT)
17871         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17872       else
17873         emit_insn (gen_cmpsi_1 (countreg, countreg));
17874       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17875                                   operands[1], operands[2]));
17876     }
17878   outlow = gen_lowpart (QImode, out);
17879   emit_insn (gen_cmpintqi (outlow));
17880   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17882   if (operands[0] != out)
17883     emit_move_insn (operands[0], out);
17885   DONE;
17888 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17890 (define_expand "cmpintqi"
17891   [(set (match_dup 1)
17892         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17893    (set (match_dup 2)
17894         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17895    (parallel [(set (match_operand:QI 0 "register_operand" "")
17896                    (minus:QI (match_dup 1)
17897                              (match_dup 2)))
17898               (clobber (reg:CC FLAGS_REG))])]
17899   ""
17900   "operands[1] = gen_reg_rtx (QImode);
17901    operands[2] = gen_reg_rtx (QImode);")
17903 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17904 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17906 (define_expand "cmpstrnqi_nz_1"
17907   [(parallel [(set (reg:CC FLAGS_REG)
17908                    (compare:CC (match_operand 4 "memory_operand" "")
17909                                (match_operand 5 "memory_operand" "")))
17910               (use (match_operand 2 "register_operand" ""))
17911               (use (match_operand:SI 3 "immediate_operand" ""))
17912               (use (reg:SI DIRFLAG_REG))
17913               (clobber (match_operand 0 "register_operand" ""))
17914               (clobber (match_operand 1 "register_operand" ""))
17915               (clobber (match_dup 2))])]
17916   ""
17917   "")
17919 (define_insn "*cmpstrnqi_nz_1"
17920   [(set (reg:CC FLAGS_REG)
17921         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17922                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17923    (use (match_operand:SI 6 "register_operand" "2"))
17924    (use (match_operand:SI 3 "immediate_operand" "i"))
17925    (use (reg:SI DIRFLAG_REG))
17926    (clobber (match_operand:SI 0 "register_operand" "=S"))
17927    (clobber (match_operand:SI 1 "register_operand" "=D"))
17928    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17929   "!TARGET_64BIT"
17930   "repz{\;| }cmpsb"
17931   [(set_attr "type" "str")
17932    (set_attr "mode" "QI")
17933    (set_attr "prefix_rep" "1")])
17935 (define_insn "*cmpstrnqi_nz_rex_1"
17936   [(set (reg:CC FLAGS_REG)
17937         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17938                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17939    (use (match_operand:DI 6 "register_operand" "2"))
17940    (use (match_operand:SI 3 "immediate_operand" "i"))
17941    (use (reg:SI DIRFLAG_REG))
17942    (clobber (match_operand:DI 0 "register_operand" "=S"))
17943    (clobber (match_operand:DI 1 "register_operand" "=D"))
17944    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17945   "TARGET_64BIT"
17946   "repz{\;| }cmpsb"
17947   [(set_attr "type" "str")
17948    (set_attr "mode" "QI")
17949    (set_attr "prefix_rep" "1")])
17951 ;; The same, but the count is not known to not be zero.
17953 (define_expand "cmpstrnqi_1"
17954   [(parallel [(set (reg:CC FLAGS_REG)
17955                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17956                                      (const_int 0))
17957                   (compare:CC (match_operand 4 "memory_operand" "")
17958                               (match_operand 5 "memory_operand" ""))
17959                   (const_int 0)))
17960               (use (match_operand:SI 3 "immediate_operand" ""))
17961               (use (reg:CC FLAGS_REG))
17962               (use (reg:SI DIRFLAG_REG))
17963               (clobber (match_operand 0 "register_operand" ""))
17964               (clobber (match_operand 1 "register_operand" ""))
17965               (clobber (match_dup 2))])]
17966   ""
17967   "")
17969 (define_insn "*cmpstrnqi_1"
17970   [(set (reg:CC FLAGS_REG)
17971         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17972                              (const_int 0))
17973           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17974                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17975           (const_int 0)))
17976    (use (match_operand:SI 3 "immediate_operand" "i"))
17977    (use (reg:CC FLAGS_REG))
17978    (use (reg:SI DIRFLAG_REG))
17979    (clobber (match_operand:SI 0 "register_operand" "=S"))
17980    (clobber (match_operand:SI 1 "register_operand" "=D"))
17981    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17982   "!TARGET_64BIT"
17983   "repz{\;| }cmpsb"
17984   [(set_attr "type" "str")
17985    (set_attr "mode" "QI")
17986    (set_attr "prefix_rep" "1")])
17988 (define_insn "*cmpstrnqi_rex_1"
17989   [(set (reg:CC FLAGS_REG)
17990         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17991                              (const_int 0))
17992           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17993                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17994           (const_int 0)))
17995    (use (match_operand:SI 3 "immediate_operand" "i"))
17996    (use (reg:CC FLAGS_REG))
17997    (use (reg:SI DIRFLAG_REG))
17998    (clobber (match_operand:DI 0 "register_operand" "=S"))
17999    (clobber (match_operand:DI 1 "register_operand" "=D"))
18000    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18001   "TARGET_64BIT"
18002   "repz{\;| }cmpsb"
18003   [(set_attr "type" "str")
18004    (set_attr "mode" "QI")
18005    (set_attr "prefix_rep" "1")])
18007 (define_expand "strlensi"
18008   [(set (match_operand:SI 0 "register_operand" "")
18009         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18010                     (match_operand:QI 2 "immediate_operand" "")
18011                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18012   ""
18014  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18015    DONE;
18016  else
18017    FAIL;
18020 (define_expand "strlendi"
18021   [(set (match_operand:DI 0 "register_operand" "")
18022         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18023                     (match_operand:QI 2 "immediate_operand" "")
18024                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18025   ""
18027  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18028    DONE;
18029  else
18030    FAIL;
18033 (define_expand "strlenqi_1"
18034   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18035               (use (reg:SI DIRFLAG_REG))
18036               (clobber (match_operand 1 "register_operand" ""))
18037               (clobber (reg:CC FLAGS_REG))])]
18038   ""
18039   "")
18041 (define_insn "*strlenqi_1"
18042   [(set (match_operand:SI 0 "register_operand" "=&c")
18043         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18044                     (match_operand:QI 2 "register_operand" "a")
18045                     (match_operand:SI 3 "immediate_operand" "i")
18046                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18047    (use (reg:SI DIRFLAG_REG))
18048    (clobber (match_operand:SI 1 "register_operand" "=D"))
18049    (clobber (reg:CC FLAGS_REG))]
18050   "!TARGET_64BIT"
18051   "repnz{\;| }scasb"
18052   [(set_attr "type" "str")
18053    (set_attr "mode" "QI")
18054    (set_attr "prefix_rep" "1")])
18056 (define_insn "*strlenqi_rex_1"
18057   [(set (match_operand:DI 0 "register_operand" "=&c")
18058         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18059                     (match_operand:QI 2 "register_operand" "a")
18060                     (match_operand:DI 3 "immediate_operand" "i")
18061                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18062    (use (reg:SI DIRFLAG_REG))
18063    (clobber (match_operand:DI 1 "register_operand" "=D"))
18064    (clobber (reg:CC FLAGS_REG))]
18065   "TARGET_64BIT"
18066   "repnz{\;| }scasb"
18067   [(set_attr "type" "str")
18068    (set_attr "mode" "QI")
18069    (set_attr "prefix_rep" "1")])
18071 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18072 ;; handled in combine, but it is not currently up to the task.
18073 ;; When used for their truth value, the cmpstrn* expanders generate
18074 ;; code like this:
18076 ;;   repz cmpsb
18077 ;;   seta       %al
18078 ;;   setb       %dl
18079 ;;   cmpb       %al, %dl
18080 ;;   jcc        label
18082 ;; The intermediate three instructions are unnecessary.
18084 ;; This one handles cmpstrn*_nz_1...
18085 (define_peephole2
18086   [(parallel[
18087      (set (reg:CC FLAGS_REG)
18088           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18089                       (mem:BLK (match_operand 5 "register_operand" ""))))
18090      (use (match_operand 6 "register_operand" ""))
18091      (use (match_operand:SI 3 "immediate_operand" ""))
18092      (use (reg:SI DIRFLAG_REG))
18093      (clobber (match_operand 0 "register_operand" ""))
18094      (clobber (match_operand 1 "register_operand" ""))
18095      (clobber (match_operand 2 "register_operand" ""))])
18096    (set (match_operand:QI 7 "register_operand" "")
18097         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18098    (set (match_operand:QI 8 "register_operand" "")
18099         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18100    (set (reg FLAGS_REG)
18101         (compare (match_dup 7) (match_dup 8)))
18102   ]
18103   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18104   [(parallel[
18105      (set (reg:CC FLAGS_REG)
18106           (compare:CC (mem:BLK (match_dup 4))
18107                       (mem:BLK (match_dup 5))))
18108      (use (match_dup 6))
18109      (use (match_dup 3))
18110      (use (reg:SI DIRFLAG_REG))
18111      (clobber (match_dup 0))
18112      (clobber (match_dup 1))
18113      (clobber (match_dup 2))])]
18114   "")
18116 ;; ...and this one handles cmpstrn*_1.
18117 (define_peephole2
18118   [(parallel[
18119      (set (reg:CC FLAGS_REG)
18120           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18121                                (const_int 0))
18122             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18123                         (mem:BLK (match_operand 5 "register_operand" "")))
18124             (const_int 0)))
18125      (use (match_operand:SI 3 "immediate_operand" ""))
18126      (use (reg:CC FLAGS_REG))
18127      (use (reg:SI DIRFLAG_REG))
18128      (clobber (match_operand 0 "register_operand" ""))
18129      (clobber (match_operand 1 "register_operand" ""))
18130      (clobber (match_operand 2 "register_operand" ""))])
18131    (set (match_operand:QI 7 "register_operand" "")
18132         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18133    (set (match_operand:QI 8 "register_operand" "")
18134         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18135    (set (reg FLAGS_REG)
18136         (compare (match_dup 7) (match_dup 8)))
18137   ]
18138   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18139   [(parallel[
18140      (set (reg:CC FLAGS_REG)
18141           (if_then_else:CC (ne (match_dup 6)
18142                                (const_int 0))
18143             (compare:CC (mem:BLK (match_dup 4))
18144                         (mem:BLK (match_dup 5)))
18145             (const_int 0)))
18146      (use (match_dup 3))
18147      (use (reg:CC FLAGS_REG))
18148      (use (reg:SI DIRFLAG_REG))
18149      (clobber (match_dup 0))
18150      (clobber (match_dup 1))
18151      (clobber (match_dup 2))])]
18152   "")
18156 ;; Conditional move instructions.
18158 (define_expand "movdicc"
18159   [(set (match_operand:DI 0 "register_operand" "")
18160         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18161                          (match_operand:DI 2 "general_operand" "")
18162                          (match_operand:DI 3 "general_operand" "")))]
18163   "TARGET_64BIT"
18164   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18166 (define_insn "x86_movdicc_0_m1_rex64"
18167   [(set (match_operand:DI 0 "register_operand" "=r")
18168         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18169           (const_int -1)
18170           (const_int 0)))
18171    (clobber (reg:CC FLAGS_REG))]
18172   "TARGET_64BIT"
18173   "sbb{q}\t%0, %0"
18174   ; Since we don't have the proper number of operands for an alu insn,
18175   ; fill in all the blanks.
18176   [(set_attr "type" "alu")
18177    (set_attr "pent_pair" "pu")
18178    (set_attr "memory" "none")
18179    (set_attr "imm_disp" "false")
18180    (set_attr "mode" "DI")
18181    (set_attr "length_immediate" "0")])
18183 (define_insn "*movdicc_c_rex64"
18184   [(set (match_operand:DI 0 "register_operand" "=r,r")
18185         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18186                                 [(reg FLAGS_REG) (const_int 0)])
18187                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18188                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18189   "TARGET_64BIT && TARGET_CMOVE
18190    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18191   "@
18192    cmov%O2%C1\t{%2, %0|%0, %2}
18193    cmov%O2%c1\t{%3, %0|%0, %3}"
18194   [(set_attr "type" "icmov")
18195    (set_attr "mode" "DI")])
18197 (define_expand "movsicc"
18198   [(set (match_operand:SI 0 "register_operand" "")
18199         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18200                          (match_operand:SI 2 "general_operand" "")
18201                          (match_operand:SI 3 "general_operand" "")))]
18202   ""
18203   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18205 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18206 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18207 ;; So just document what we're doing explicitly.
18209 (define_insn "x86_movsicc_0_m1"
18210   [(set (match_operand:SI 0 "register_operand" "=r")
18211         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18212           (const_int -1)
18213           (const_int 0)))
18214    (clobber (reg:CC FLAGS_REG))]
18215   ""
18216   "sbb{l}\t%0, %0"
18217   ; Since we don't have the proper number of operands for an alu insn,
18218   ; fill in all the blanks.
18219   [(set_attr "type" "alu")
18220    (set_attr "pent_pair" "pu")
18221    (set_attr "memory" "none")
18222    (set_attr "imm_disp" "false")
18223    (set_attr "mode" "SI")
18224    (set_attr "length_immediate" "0")])
18226 (define_insn "*movsicc_noc"
18227   [(set (match_operand:SI 0 "register_operand" "=r,r")
18228         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18229                                 [(reg FLAGS_REG) (const_int 0)])
18230                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18231                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18232   "TARGET_CMOVE
18233    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18234   "@
18235    cmov%O2%C1\t{%2, %0|%0, %2}
18236    cmov%O2%c1\t{%3, %0|%0, %3}"
18237   [(set_attr "type" "icmov")
18238    (set_attr "mode" "SI")])
18240 (define_expand "movhicc"
18241   [(set (match_operand:HI 0 "register_operand" "")
18242         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18243                          (match_operand:HI 2 "general_operand" "")
18244                          (match_operand:HI 3 "general_operand" "")))]
18245   "TARGET_HIMODE_MATH"
18246   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18248 (define_insn "*movhicc_noc"
18249   [(set (match_operand:HI 0 "register_operand" "=r,r")
18250         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18251                                 [(reg FLAGS_REG) (const_int 0)])
18252                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18253                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18254   "TARGET_CMOVE
18255    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18256   "@
18257    cmov%O2%C1\t{%2, %0|%0, %2}
18258    cmov%O2%c1\t{%3, %0|%0, %3}"
18259   [(set_attr "type" "icmov")
18260    (set_attr "mode" "HI")])
18262 (define_expand "movqicc"
18263   [(set (match_operand:QI 0 "register_operand" "")
18264         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18265                          (match_operand:QI 2 "general_operand" "")
18266                          (match_operand:QI 3 "general_operand" "")))]
18267   "TARGET_QIMODE_MATH"
18268   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18270 (define_insn_and_split "*movqicc_noc"
18271   [(set (match_operand:QI 0 "register_operand" "=r,r")
18272         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18273                                 [(match_operand 4 "flags_reg_operand" "")
18274                                  (const_int 0)])
18275                       (match_operand:QI 2 "register_operand" "r,0")
18276                       (match_operand:QI 3 "register_operand" "0,r")))]
18277   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18278   "#"
18279   "&& reload_completed"
18280   [(set (match_dup 0)
18281         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18282                       (match_dup 2)
18283                       (match_dup 3)))]
18284   "operands[0] = gen_lowpart (SImode, operands[0]);
18285    operands[2] = gen_lowpart (SImode, operands[2]);
18286    operands[3] = gen_lowpart (SImode, operands[3]);"
18287   [(set_attr "type" "icmov")
18288    (set_attr "mode" "SI")])
18290 (define_expand "movsfcc"
18291   [(set (match_operand:SF 0 "register_operand" "")
18292         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18293                          (match_operand:SF 2 "register_operand" "")
18294                          (match_operand:SF 3 "register_operand" "")))]
18295   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18296   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18298 (define_insn "*movsfcc_1_387"
18299   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18300         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18301                                 [(reg FLAGS_REG) (const_int 0)])
18302                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18303                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18304   "TARGET_80387 && TARGET_CMOVE
18305    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18306   "@
18307    fcmov%F1\t{%2, %0|%0, %2}
18308    fcmov%f1\t{%3, %0|%0, %3}
18309    cmov%O2%C1\t{%2, %0|%0, %2}
18310    cmov%O2%c1\t{%3, %0|%0, %3}"
18311   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18312    (set_attr "mode" "SF,SF,SI,SI")])
18314 (define_expand "movdfcc"
18315   [(set (match_operand:DF 0 "register_operand" "")
18316         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18317                          (match_operand:DF 2 "register_operand" "")
18318                          (match_operand:DF 3 "register_operand" "")))]
18319   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18320   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18322 (define_insn "*movdfcc_1"
18323   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18324         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18325                                 [(reg FLAGS_REG) (const_int 0)])
18326                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18327                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18328   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18329    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18330   "@
18331    fcmov%F1\t{%2, %0|%0, %2}
18332    fcmov%f1\t{%3, %0|%0, %3}
18333    #
18334    #"
18335   [(set_attr "type" "fcmov,fcmov,multi,multi")
18336    (set_attr "mode" "DF")])
18338 (define_insn "*movdfcc_1_rex64"
18339   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18340         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18341                                 [(reg FLAGS_REG) (const_int 0)])
18342                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18343                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18344   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18345    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18346   "@
18347    fcmov%F1\t{%2, %0|%0, %2}
18348    fcmov%f1\t{%3, %0|%0, %3}
18349    cmov%O2%C1\t{%2, %0|%0, %2}
18350    cmov%O2%c1\t{%3, %0|%0, %3}"
18351   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18352    (set_attr "mode" "DF")])
18354 (define_split
18355   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18356         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18357                                 [(match_operand 4 "flags_reg_operand" "")
18358                                  (const_int 0)])
18359                       (match_operand:DF 2 "nonimmediate_operand" "")
18360                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18361   "!TARGET_64BIT && reload_completed"
18362   [(set (match_dup 2)
18363         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18364                       (match_dup 5)
18365                       (match_dup 7)))
18366    (set (match_dup 3)
18367         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18368                       (match_dup 6)
18369                       (match_dup 8)))]
18370   "split_di (operands+2, 1, operands+5, operands+6);
18371    split_di (operands+3, 1, operands+7, operands+8);
18372    split_di (operands, 1, operands+2, operands+3);")
18374 (define_expand "movxfcc"
18375   [(set (match_operand:XF 0 "register_operand" "")
18376         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18377                          (match_operand:XF 2 "register_operand" "")
18378                          (match_operand:XF 3 "register_operand" "")))]
18379   "TARGET_80387 && TARGET_CMOVE"
18380   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18382 (define_insn "*movxfcc_1"
18383   [(set (match_operand:XF 0 "register_operand" "=f,f")
18384         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18385                                 [(reg FLAGS_REG) (const_int 0)])
18386                       (match_operand:XF 2 "register_operand" "f,0")
18387                       (match_operand:XF 3 "register_operand" "0,f")))]
18388   "TARGET_80387 && TARGET_CMOVE"
18389   "@
18390    fcmov%F1\t{%2, %0|%0, %2}
18391    fcmov%f1\t{%3, %0|%0, %3}"
18392   [(set_attr "type" "fcmov")
18393    (set_attr "mode" "XF")])
18395 ;; These versions of the min/max patterns are intentionally ignorant of
18396 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18397 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18398 ;; are undefined in this condition, we're certain this is correct.
18400 (define_insn "sminsf3"
18401   [(set (match_operand:SF 0 "register_operand" "=x")
18402         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18403                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18404   "TARGET_SSE_MATH"
18405   "minss\t{%2, %0|%0, %2}"
18406   [(set_attr "type" "sseadd")
18407    (set_attr "mode" "SF")])
18409 (define_insn "smaxsf3"
18410   [(set (match_operand:SF 0 "register_operand" "=x")
18411         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18412                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18413   "TARGET_SSE_MATH"
18414   "maxss\t{%2, %0|%0, %2}"
18415   [(set_attr "type" "sseadd")
18416    (set_attr "mode" "SF")])
18418 (define_insn "smindf3"
18419   [(set (match_operand:DF 0 "register_operand" "=x")
18420         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18421                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18422   "TARGET_SSE2 && TARGET_SSE_MATH"
18423   "minsd\t{%2, %0|%0, %2}"
18424   [(set_attr "type" "sseadd")
18425    (set_attr "mode" "DF")])
18427 (define_insn "smaxdf3"
18428   [(set (match_operand:DF 0 "register_operand" "=x")
18429         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18430                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18431   "TARGET_SSE2 && TARGET_SSE_MATH"
18432   "maxsd\t{%2, %0|%0, %2}"
18433   [(set_attr "type" "sseadd")
18434    (set_attr "mode" "DF")])
18436 ;; These versions of the min/max patterns implement exactly the operations
18437 ;;   min = (op1 < op2 ? op1 : op2)
18438 ;;   max = (!(op1 < op2) ? op1 : op2)
18439 ;; Their operands are not commutative, and thus they may be used in the
18440 ;; presence of -0.0 and NaN.
18442 (define_insn "*ieee_sminsf3"
18443   [(set (match_operand:SF 0 "register_operand" "=x")
18444         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18445                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18446                    UNSPEC_IEEE_MIN))]
18447   "TARGET_SSE_MATH"
18448   "minss\t{%2, %0|%0, %2}"
18449   [(set_attr "type" "sseadd")
18450    (set_attr "mode" "SF")])
18452 (define_insn "*ieee_smaxsf3"
18453   [(set (match_operand:SF 0 "register_operand" "=x")
18454         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18455                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18456                    UNSPEC_IEEE_MAX))]
18457   "TARGET_SSE_MATH"
18458   "maxss\t{%2, %0|%0, %2}"
18459   [(set_attr "type" "sseadd")
18460    (set_attr "mode" "SF")])
18462 (define_insn "*ieee_smindf3"
18463   [(set (match_operand:DF 0 "register_operand" "=x")
18464         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18465                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18466                    UNSPEC_IEEE_MIN))]
18467   "TARGET_SSE2 && TARGET_SSE_MATH"
18468   "minsd\t{%2, %0|%0, %2}"
18469   [(set_attr "type" "sseadd")
18470    (set_attr "mode" "DF")])
18472 (define_insn "*ieee_smaxdf3"
18473   [(set (match_operand:DF 0 "register_operand" "=x")
18474         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18475                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18476                    UNSPEC_IEEE_MAX))]
18477   "TARGET_SSE2 && TARGET_SSE_MATH"
18478   "maxsd\t{%2, %0|%0, %2}"
18479   [(set_attr "type" "sseadd")
18480    (set_attr "mode" "DF")])
18482 ;; Conditional addition patterns
18483 (define_expand "addqicc"
18484   [(match_operand:QI 0 "register_operand" "")
18485    (match_operand 1 "comparison_operator" "")
18486    (match_operand:QI 2 "register_operand" "")
18487    (match_operand:QI 3 "const_int_operand" "")]
18488   ""
18489   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18491 (define_expand "addhicc"
18492   [(match_operand:HI 0 "register_operand" "")
18493    (match_operand 1 "comparison_operator" "")
18494    (match_operand:HI 2 "register_operand" "")
18495    (match_operand:HI 3 "const_int_operand" "")]
18496   ""
18497   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18499 (define_expand "addsicc"
18500   [(match_operand:SI 0 "register_operand" "")
18501    (match_operand 1 "comparison_operator" "")
18502    (match_operand:SI 2 "register_operand" "")
18503    (match_operand:SI 3 "const_int_operand" "")]
18504   ""
18505   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18507 (define_expand "adddicc"
18508   [(match_operand:DI 0 "register_operand" "")
18509    (match_operand 1 "comparison_operator" "")
18510    (match_operand:DI 2 "register_operand" "")
18511    (match_operand:DI 3 "const_int_operand" "")]
18512   "TARGET_64BIT"
18513   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18516 ;; Misc patterns (?)
18518 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18519 ;; Otherwise there will be nothing to keep
18520 ;; 
18521 ;; [(set (reg ebp) (reg esp))]
18522 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18523 ;;  (clobber (eflags)]
18524 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18526 ;; in proper program order.
18527 (define_insn "pro_epilogue_adjust_stack_1"
18528   [(set (match_operand:SI 0 "register_operand" "=r,r")
18529         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18530                  (match_operand:SI 2 "immediate_operand" "i,i")))
18531    (clobber (reg:CC FLAGS_REG))
18532    (clobber (mem:BLK (scratch)))]
18533   "!TARGET_64BIT"
18535   switch (get_attr_type (insn))
18536     {
18537     case TYPE_IMOV:
18538       return "mov{l}\t{%1, %0|%0, %1}";
18540     case TYPE_ALU:
18541       if (GET_CODE (operands[2]) == CONST_INT
18542           && (INTVAL (operands[2]) == 128
18543               || (INTVAL (operands[2]) < 0
18544                   && INTVAL (operands[2]) != -128)))
18545         {
18546           operands[2] = GEN_INT (-INTVAL (operands[2]));
18547           return "sub{l}\t{%2, %0|%0, %2}";
18548         }
18549       return "add{l}\t{%2, %0|%0, %2}";
18551     case TYPE_LEA:
18552       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18553       return "lea{l}\t{%a2, %0|%0, %a2}";
18555     default:
18556       gcc_unreachable ();
18557     }
18559   [(set (attr "type")
18560         (cond [(eq_attr "alternative" "0")
18561                  (const_string "alu")
18562                (match_operand:SI 2 "const0_operand" "")
18563                  (const_string "imov")
18564               ]
18565               (const_string "lea")))
18566    (set_attr "mode" "SI")])
18568 (define_insn "pro_epilogue_adjust_stack_rex64"
18569   [(set (match_operand:DI 0 "register_operand" "=r,r")
18570         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18571                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18572    (clobber (reg:CC FLAGS_REG))
18573    (clobber (mem:BLK (scratch)))]
18574   "TARGET_64BIT"
18576   switch (get_attr_type (insn))
18577     {
18578     case TYPE_IMOV:
18579       return "mov{q}\t{%1, %0|%0, %1}";
18581     case TYPE_ALU:
18582       if (GET_CODE (operands[2]) == CONST_INT
18583           /* Avoid overflows.  */
18584           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18585           && (INTVAL (operands[2]) == 128
18586               || (INTVAL (operands[2]) < 0
18587                   && INTVAL (operands[2]) != -128)))
18588         {
18589           operands[2] = GEN_INT (-INTVAL (operands[2]));
18590           return "sub{q}\t{%2, %0|%0, %2}";
18591         }
18592       return "add{q}\t{%2, %0|%0, %2}";
18594     case TYPE_LEA:
18595       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18596       return "lea{q}\t{%a2, %0|%0, %a2}";
18598     default:
18599       gcc_unreachable ();
18600     }
18602   [(set (attr "type")
18603         (cond [(eq_attr "alternative" "0")
18604                  (const_string "alu")
18605                (match_operand:DI 2 "const0_operand" "")
18606                  (const_string "imov")
18607               ]
18608               (const_string "lea")))
18609    (set_attr "mode" "DI")])
18611 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18612   [(set (match_operand:DI 0 "register_operand" "=r,r")
18613         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18614                  (match_operand:DI 3 "immediate_operand" "i,i")))
18615    (use (match_operand:DI 2 "register_operand" "r,r"))
18616    (clobber (reg:CC FLAGS_REG))
18617    (clobber (mem:BLK (scratch)))]
18618   "TARGET_64BIT"
18620   switch (get_attr_type (insn))
18621     {
18622     case TYPE_ALU:
18623       return "add{q}\t{%2, %0|%0, %2}";
18625     case TYPE_LEA:
18626       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18627       return "lea{q}\t{%a2, %0|%0, %a2}";
18629     default:
18630       gcc_unreachable ();
18631     }
18633   [(set_attr "type" "alu,lea")
18634    (set_attr "mode" "DI")])
18636 (define_expand "allocate_stack_worker"
18637   [(match_operand:SI 0 "register_operand" "")]
18638   "TARGET_STACK_PROBE"
18640   if (reload_completed)
18641     {
18642       if (TARGET_64BIT)
18643         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18644       else
18645         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18646     }
18647   else
18648     {
18649       if (TARGET_64BIT)
18650         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18651       else
18652         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18653     }
18654   DONE;
18657 (define_insn "allocate_stack_worker_1"
18658   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18659     UNSPECV_STACK_PROBE)
18660    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18661    (clobber (match_scratch:SI 1 "=0"))
18662    (clobber (reg:CC FLAGS_REG))]
18663   "!TARGET_64BIT && TARGET_STACK_PROBE"
18664   "call\t__alloca"
18665   [(set_attr "type" "multi")
18666    (set_attr "length" "5")])
18668 (define_expand "allocate_stack_worker_postreload"
18669   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18670                                     UNSPECV_STACK_PROBE)
18671               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18672               (clobber (match_dup 0))
18673               (clobber (reg:CC FLAGS_REG))])]
18674   ""
18675   "")
18677 (define_insn "allocate_stack_worker_rex64"
18678   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18679     UNSPECV_STACK_PROBE)
18680    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18681    (clobber (match_scratch:DI 1 "=0"))
18682    (clobber (reg:CC FLAGS_REG))]
18683   "TARGET_64BIT && TARGET_STACK_PROBE"
18684   "call\t__alloca"
18685   [(set_attr "type" "multi")
18686    (set_attr "length" "5")])
18688 (define_expand "allocate_stack_worker_rex64_postreload"
18689   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18690                                     UNSPECV_STACK_PROBE)
18691               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18692               (clobber (match_dup 0))
18693               (clobber (reg:CC FLAGS_REG))])]
18694   ""
18695   "")
18697 (define_expand "allocate_stack"
18698   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18699                    (minus:SI (reg:SI SP_REG)
18700                              (match_operand:SI 1 "general_operand" "")))
18701               (clobber (reg:CC FLAGS_REG))])
18702    (parallel [(set (reg:SI SP_REG)
18703                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18704               (clobber (reg:CC FLAGS_REG))])]
18705   "TARGET_STACK_PROBE"
18707 #ifdef CHECK_STACK_LIMIT
18708   if (GET_CODE (operands[1]) == CONST_INT
18709       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18710     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18711                            operands[1]));
18712   else 
18713 #endif
18714     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18715                                                             operands[1])));
18717   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18718   DONE;
18721 (define_expand "builtin_setjmp_receiver"
18722   [(label_ref (match_operand 0 "" ""))]
18723   "!TARGET_64BIT && flag_pic"
18725   emit_insn (gen_set_got (pic_offset_table_rtx));
18726   DONE;
18729 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18731 (define_split
18732   [(set (match_operand 0 "register_operand" "")
18733         (match_operator 3 "promotable_binary_operator"
18734            [(match_operand 1 "register_operand" "")
18735             (match_operand 2 "aligned_operand" "")]))
18736    (clobber (reg:CC FLAGS_REG))]
18737   "! TARGET_PARTIAL_REG_STALL && reload_completed
18738    && ((GET_MODE (operands[0]) == HImode 
18739         && ((!optimize_size && !TARGET_FAST_PREFIX)
18740             || GET_CODE (operands[2]) != CONST_INT
18741             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18742        || (GET_MODE (operands[0]) == QImode 
18743            && (TARGET_PROMOTE_QImode || optimize_size)))"
18744   [(parallel [(set (match_dup 0)
18745                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18746               (clobber (reg:CC FLAGS_REG))])]
18747   "operands[0] = gen_lowpart (SImode, operands[0]);
18748    operands[1] = gen_lowpart (SImode, operands[1]);
18749    if (GET_CODE (operands[3]) != ASHIFT)
18750      operands[2] = gen_lowpart (SImode, operands[2]);
18751    PUT_MODE (operands[3], SImode);")
18753 ; Promote the QImode tests, as i386 has encoding of the AND
18754 ; instruction with 32-bit sign-extended immediate and thus the
18755 ; instruction size is unchanged, except in the %eax case for
18756 ; which it is increased by one byte, hence the ! optimize_size.
18757 (define_split
18758   [(set (match_operand 0 "flags_reg_operand" "")
18759         (match_operator 2 "compare_operator"
18760           [(and (match_operand 3 "aligned_operand" "")
18761                 (match_operand 4 "const_int_operand" ""))
18762            (const_int 0)]))
18763    (set (match_operand 1 "register_operand" "")
18764         (and (match_dup 3) (match_dup 4)))]
18765   "! TARGET_PARTIAL_REG_STALL && reload_completed
18766    /* Ensure that the operand will remain sign-extended immediate.  */
18767    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18768    && ! optimize_size
18769    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18770        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18771   [(parallel [(set (match_dup 0)
18772                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18773                                     (const_int 0)]))
18774               (set (match_dup 1)
18775                    (and:SI (match_dup 3) (match_dup 4)))])]
18777   operands[4]
18778     = gen_int_mode (INTVAL (operands[4])
18779                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18780   operands[1] = gen_lowpart (SImode, operands[1]);
18781   operands[3] = gen_lowpart (SImode, operands[3]);
18784 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18785 ; the TEST instruction with 32-bit sign-extended immediate and thus
18786 ; the instruction size would at least double, which is not what we
18787 ; want even with ! optimize_size.
18788 (define_split
18789   [(set (match_operand 0 "flags_reg_operand" "")
18790         (match_operator 1 "compare_operator"
18791           [(and (match_operand:HI 2 "aligned_operand" "")
18792                 (match_operand:HI 3 "const_int_operand" ""))
18793            (const_int 0)]))]
18794   "! TARGET_PARTIAL_REG_STALL && reload_completed
18795    /* Ensure that the operand will remain sign-extended immediate.  */
18796    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18797    && ! TARGET_FAST_PREFIX
18798    && ! optimize_size"
18799   [(set (match_dup 0)
18800         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18801                          (const_int 0)]))]
18803   operands[3]
18804     = gen_int_mode (INTVAL (operands[3])
18805                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18806   operands[2] = gen_lowpart (SImode, operands[2]);
18809 (define_split
18810   [(set (match_operand 0 "register_operand" "")
18811         (neg (match_operand 1 "register_operand" "")))
18812    (clobber (reg:CC FLAGS_REG))]
18813   "! TARGET_PARTIAL_REG_STALL && reload_completed
18814    && (GET_MODE (operands[0]) == HImode
18815        || (GET_MODE (operands[0]) == QImode 
18816            && (TARGET_PROMOTE_QImode || optimize_size)))"
18817   [(parallel [(set (match_dup 0)
18818                    (neg:SI (match_dup 1)))
18819               (clobber (reg:CC FLAGS_REG))])]
18820   "operands[0] = gen_lowpart (SImode, operands[0]);
18821    operands[1] = gen_lowpart (SImode, operands[1]);")
18823 (define_split
18824   [(set (match_operand 0 "register_operand" "")
18825         (not (match_operand 1 "register_operand" "")))]
18826   "! TARGET_PARTIAL_REG_STALL && reload_completed
18827    && (GET_MODE (operands[0]) == HImode
18828        || (GET_MODE (operands[0]) == QImode 
18829            && (TARGET_PROMOTE_QImode || optimize_size)))"
18830   [(set (match_dup 0)
18831         (not:SI (match_dup 1)))]
18832   "operands[0] = gen_lowpart (SImode, operands[0]);
18833    operands[1] = gen_lowpart (SImode, operands[1]);")
18835 (define_split 
18836   [(set (match_operand 0 "register_operand" "")
18837         (if_then_else (match_operator 1 "comparison_operator" 
18838                                 [(reg FLAGS_REG) (const_int 0)])
18839                       (match_operand 2 "register_operand" "")
18840                       (match_operand 3 "register_operand" "")))]
18841   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18842    && (GET_MODE (operands[0]) == HImode
18843        || (GET_MODE (operands[0]) == QImode 
18844            && (TARGET_PROMOTE_QImode || optimize_size)))"
18845   [(set (match_dup 0)
18846         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18847   "operands[0] = gen_lowpart (SImode, operands[0]);
18848    operands[2] = gen_lowpart (SImode, operands[2]);
18849    operands[3] = gen_lowpart (SImode, operands[3]);")
18850                         
18852 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18853 ;; transform a complex memory operation into two memory to register operations.
18855 ;; Don't push memory operands
18856 (define_peephole2
18857   [(set (match_operand:SI 0 "push_operand" "")
18858         (match_operand:SI 1 "memory_operand" ""))
18859    (match_scratch:SI 2 "r")]
18860   "! optimize_size && ! TARGET_PUSH_MEMORY"
18861   [(set (match_dup 2) (match_dup 1))
18862    (set (match_dup 0) (match_dup 2))]
18863   "")
18865 (define_peephole2
18866   [(set (match_operand:DI 0 "push_operand" "")
18867         (match_operand:DI 1 "memory_operand" ""))
18868    (match_scratch:DI 2 "r")]
18869   "! optimize_size && ! TARGET_PUSH_MEMORY"
18870   [(set (match_dup 2) (match_dup 1))
18871    (set (match_dup 0) (match_dup 2))]
18872   "")
18874 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18875 ;; SImode pushes.
18876 (define_peephole2
18877   [(set (match_operand:SF 0 "push_operand" "")
18878         (match_operand:SF 1 "memory_operand" ""))
18879    (match_scratch:SF 2 "r")]
18880   "! optimize_size && ! TARGET_PUSH_MEMORY"
18881   [(set (match_dup 2) (match_dup 1))
18882    (set (match_dup 0) (match_dup 2))]
18883   "")
18885 (define_peephole2
18886   [(set (match_operand:HI 0 "push_operand" "")
18887         (match_operand:HI 1 "memory_operand" ""))
18888    (match_scratch:HI 2 "r")]
18889   "! optimize_size && ! TARGET_PUSH_MEMORY"
18890   [(set (match_dup 2) (match_dup 1))
18891    (set (match_dup 0) (match_dup 2))]
18892   "")
18894 (define_peephole2
18895   [(set (match_operand:QI 0 "push_operand" "")
18896         (match_operand:QI 1 "memory_operand" ""))
18897    (match_scratch:QI 2 "q")]
18898   "! optimize_size && ! TARGET_PUSH_MEMORY"
18899   [(set (match_dup 2) (match_dup 1))
18900    (set (match_dup 0) (match_dup 2))]
18901   "")
18903 ;; Don't move an immediate directly to memory when the instruction
18904 ;; gets too big.
18905 (define_peephole2
18906   [(match_scratch:SI 1 "r")
18907    (set (match_operand:SI 0 "memory_operand" "")
18908         (const_int 0))]
18909   "! optimize_size
18910    && ! TARGET_USE_MOV0
18911    && TARGET_SPLIT_LONG_MOVES
18912    && get_attr_length (insn) >= ix86_cost->large_insn
18913    && peep2_regno_dead_p (0, FLAGS_REG)"
18914   [(parallel [(set (match_dup 1) (const_int 0))
18915               (clobber (reg:CC FLAGS_REG))])
18916    (set (match_dup 0) (match_dup 1))]
18917   "")
18919 (define_peephole2
18920   [(match_scratch:HI 1 "r")
18921    (set (match_operand:HI 0 "memory_operand" "")
18922         (const_int 0))]
18923   "! optimize_size
18924    && ! TARGET_USE_MOV0
18925    && TARGET_SPLIT_LONG_MOVES
18926    && get_attr_length (insn) >= ix86_cost->large_insn
18927    && peep2_regno_dead_p (0, FLAGS_REG)"
18928   [(parallel [(set (match_dup 2) (const_int 0))
18929               (clobber (reg:CC FLAGS_REG))])
18930    (set (match_dup 0) (match_dup 1))]
18931   "operands[2] = gen_lowpart (SImode, operands[1]);")
18933 (define_peephole2
18934   [(match_scratch:QI 1 "q")
18935    (set (match_operand:QI 0 "memory_operand" "")
18936         (const_int 0))]
18937   "! optimize_size
18938    && ! TARGET_USE_MOV0
18939    && TARGET_SPLIT_LONG_MOVES
18940    && get_attr_length (insn) >= ix86_cost->large_insn
18941    && peep2_regno_dead_p (0, FLAGS_REG)"
18942   [(parallel [(set (match_dup 2) (const_int 0))
18943               (clobber (reg:CC FLAGS_REG))])
18944    (set (match_dup 0) (match_dup 1))]
18945   "operands[2] = gen_lowpart (SImode, operands[1]);")
18947 (define_peephole2
18948   [(match_scratch:SI 2 "r")
18949    (set (match_operand:SI 0 "memory_operand" "")
18950         (match_operand:SI 1 "immediate_operand" ""))]
18951   "! optimize_size
18952    && get_attr_length (insn) >= ix86_cost->large_insn
18953    && TARGET_SPLIT_LONG_MOVES"
18954   [(set (match_dup 2) (match_dup 1))
18955    (set (match_dup 0) (match_dup 2))]
18956   "")
18958 (define_peephole2
18959   [(match_scratch:HI 2 "r")
18960    (set (match_operand:HI 0 "memory_operand" "")
18961         (match_operand:HI 1 "immediate_operand" ""))]
18962   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18963   && TARGET_SPLIT_LONG_MOVES"
18964   [(set (match_dup 2) (match_dup 1))
18965    (set (match_dup 0) (match_dup 2))]
18966   "")
18968 (define_peephole2
18969   [(match_scratch:QI 2 "q")
18970    (set (match_operand:QI 0 "memory_operand" "")
18971         (match_operand:QI 1 "immediate_operand" ""))]
18972   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18973   && TARGET_SPLIT_LONG_MOVES"
18974   [(set (match_dup 2) (match_dup 1))
18975    (set (match_dup 0) (match_dup 2))]
18976   "")
18978 ;; Don't compare memory with zero, load and use a test instead.
18979 (define_peephole2
18980   [(set (match_operand 0 "flags_reg_operand" "")
18981         (match_operator 1 "compare_operator"
18982           [(match_operand:SI 2 "memory_operand" "")
18983            (const_int 0)]))
18984    (match_scratch:SI 3 "r")]
18985   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18986   [(set (match_dup 3) (match_dup 2))
18987    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18988   "")
18990 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18991 ;; Don't split NOTs with a displacement operand, because resulting XOR
18992 ;; will not be pairable anyway.
18994 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18995 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18996 ;; so this split helps here as well.
18998 ;; Note: Can't do this as a regular split because we can't get proper
18999 ;; lifetime information then.
19001 (define_peephole2
19002   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19003         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19004   "!optimize_size
19005    && peep2_regno_dead_p (0, FLAGS_REG)
19006    && ((TARGET_PENTIUM 
19007         && (GET_CODE (operands[0]) != MEM
19008             || !memory_displacement_operand (operands[0], SImode)))
19009        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19010   [(parallel [(set (match_dup 0)
19011                    (xor:SI (match_dup 1) (const_int -1)))
19012               (clobber (reg:CC FLAGS_REG))])]
19013   "")
19015 (define_peephole2
19016   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19017         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19018   "!optimize_size
19019    && peep2_regno_dead_p (0, FLAGS_REG)
19020    && ((TARGET_PENTIUM 
19021         && (GET_CODE (operands[0]) != MEM
19022             || !memory_displacement_operand (operands[0], HImode)))
19023        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19024   [(parallel [(set (match_dup 0)
19025                    (xor:HI (match_dup 1) (const_int -1)))
19026               (clobber (reg:CC FLAGS_REG))])]
19027   "")
19029 (define_peephole2
19030   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19031         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19032   "!optimize_size
19033    && peep2_regno_dead_p (0, FLAGS_REG)
19034    && ((TARGET_PENTIUM 
19035         && (GET_CODE (operands[0]) != MEM
19036             || !memory_displacement_operand (operands[0], QImode)))
19037        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19038   [(parallel [(set (match_dup 0)
19039                    (xor:QI (match_dup 1) (const_int -1)))
19040               (clobber (reg:CC FLAGS_REG))])]
19041   "")
19043 ;; Non pairable "test imm, reg" instructions can be translated to
19044 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19045 ;; byte opcode instead of two, have a short form for byte operands),
19046 ;; so do it for other CPUs as well.  Given that the value was dead,
19047 ;; this should not create any new dependencies.  Pass on the sub-word
19048 ;; versions if we're concerned about partial register stalls.
19050 (define_peephole2
19051   [(set (match_operand 0 "flags_reg_operand" "")
19052         (match_operator 1 "compare_operator"
19053           [(and:SI (match_operand:SI 2 "register_operand" "")
19054                    (match_operand:SI 3 "immediate_operand" ""))
19055            (const_int 0)]))]
19056   "ix86_match_ccmode (insn, CCNOmode)
19057    && (true_regnum (operands[2]) != 0
19058        || (GET_CODE (operands[3]) == CONST_INT
19059            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19060    && peep2_reg_dead_p (1, operands[2])"
19061   [(parallel
19062      [(set (match_dup 0)
19063            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19064                             (const_int 0)]))
19065       (set (match_dup 2)
19066            (and:SI (match_dup 2) (match_dup 3)))])]
19067   "")
19069 ;; We don't need to handle HImode case, because it will be promoted to SImode
19070 ;; on ! TARGET_PARTIAL_REG_STALL
19072 (define_peephole2
19073   [(set (match_operand 0 "flags_reg_operand" "")
19074         (match_operator 1 "compare_operator"
19075           [(and:QI (match_operand:QI 2 "register_operand" "")
19076                    (match_operand:QI 3 "immediate_operand" ""))
19077            (const_int 0)]))]
19078   "! TARGET_PARTIAL_REG_STALL
19079    && ix86_match_ccmode (insn, CCNOmode)
19080    && true_regnum (operands[2]) != 0
19081    && peep2_reg_dead_p (1, operands[2])"
19082   [(parallel
19083      [(set (match_dup 0)
19084            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19085                             (const_int 0)]))
19086       (set (match_dup 2)
19087            (and:QI (match_dup 2) (match_dup 3)))])]
19088   "")
19090 (define_peephole2
19091   [(set (match_operand 0 "flags_reg_operand" "")
19092         (match_operator 1 "compare_operator"
19093           [(and:SI
19094              (zero_extract:SI
19095                (match_operand 2 "ext_register_operand" "")
19096                (const_int 8)
19097                (const_int 8))
19098              (match_operand 3 "const_int_operand" ""))
19099            (const_int 0)]))]
19100   "! TARGET_PARTIAL_REG_STALL
19101    && ix86_match_ccmode (insn, CCNOmode)
19102    && true_regnum (operands[2]) != 0
19103    && peep2_reg_dead_p (1, operands[2])"
19104   [(parallel [(set (match_dup 0)
19105                    (match_op_dup 1
19106                      [(and:SI
19107                         (zero_extract:SI
19108                           (match_dup 2)
19109                           (const_int 8)
19110                           (const_int 8))
19111                         (match_dup 3))
19112                       (const_int 0)]))
19113               (set (zero_extract:SI (match_dup 2)
19114                                     (const_int 8)
19115                                     (const_int 8))
19116                    (and:SI 
19117                      (zero_extract:SI
19118                        (match_dup 2)
19119                        (const_int 8)
19120                        (const_int 8))
19121                      (match_dup 3)))])]
19122   "")
19124 ;; Don't do logical operations with memory inputs.
19125 (define_peephole2
19126   [(match_scratch:SI 2 "r")
19127    (parallel [(set (match_operand:SI 0 "register_operand" "")
19128                    (match_operator:SI 3 "arith_or_logical_operator"
19129                      [(match_dup 0)
19130                       (match_operand:SI 1 "memory_operand" "")]))
19131               (clobber (reg:CC FLAGS_REG))])]
19132   "! optimize_size && ! TARGET_READ_MODIFY"
19133   [(set (match_dup 2) (match_dup 1))
19134    (parallel [(set (match_dup 0)
19135                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19136               (clobber (reg:CC FLAGS_REG))])]
19137   "")
19139 (define_peephole2
19140   [(match_scratch:SI 2 "r")
19141    (parallel [(set (match_operand:SI 0 "register_operand" "")
19142                    (match_operator:SI 3 "arith_or_logical_operator"
19143                      [(match_operand:SI 1 "memory_operand" "")
19144                       (match_dup 0)]))
19145               (clobber (reg:CC FLAGS_REG))])]
19146   "! optimize_size && ! TARGET_READ_MODIFY"
19147   [(set (match_dup 2) (match_dup 1))
19148    (parallel [(set (match_dup 0)
19149                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19150               (clobber (reg:CC FLAGS_REG))])]
19151   "")
19153 ; Don't do logical operations with memory outputs
19155 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19156 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19157 ; the same decoder scheduling characteristics as the original.
19159 (define_peephole2
19160   [(match_scratch:SI 2 "r")
19161    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19162                    (match_operator:SI 3 "arith_or_logical_operator"
19163                      [(match_dup 0)
19164                       (match_operand:SI 1 "nonmemory_operand" "")]))
19165               (clobber (reg:CC FLAGS_REG))])]
19166   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19167   [(set (match_dup 2) (match_dup 0))
19168    (parallel [(set (match_dup 2)
19169                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19170               (clobber (reg:CC FLAGS_REG))])
19171    (set (match_dup 0) (match_dup 2))]
19172   "")
19174 (define_peephole2
19175   [(match_scratch:SI 2 "r")
19176    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19177                    (match_operator:SI 3 "arith_or_logical_operator"
19178                      [(match_operand:SI 1 "nonmemory_operand" "")
19179                       (match_dup 0)]))
19180               (clobber (reg:CC FLAGS_REG))])]
19181   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19182   [(set (match_dup 2) (match_dup 0))
19183    (parallel [(set (match_dup 2)
19184                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19185               (clobber (reg:CC FLAGS_REG))])
19186    (set (match_dup 0) (match_dup 2))]
19187   "")
19189 ;; Attempt to always use XOR for zeroing registers.
19190 (define_peephole2
19191   [(set (match_operand 0 "register_operand" "")
19192         (match_operand 1 "const0_operand" ""))]
19193   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19194    && (! TARGET_USE_MOV0 || optimize_size)
19195    && GENERAL_REG_P (operands[0])
19196    && peep2_regno_dead_p (0, FLAGS_REG)"
19197   [(parallel [(set (match_dup 0) (const_int 0))
19198               (clobber (reg:CC FLAGS_REG))])]
19200   operands[0] = gen_lowpart (word_mode, operands[0]);
19203 (define_peephole2
19204   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19205         (const_int 0))]
19206   "(GET_MODE (operands[0]) == QImode
19207     || GET_MODE (operands[0]) == HImode)
19208    && (! TARGET_USE_MOV0 || optimize_size)
19209    && peep2_regno_dead_p (0, FLAGS_REG)"
19210   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19211               (clobber (reg:CC FLAGS_REG))])])
19213 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19214 (define_peephole2
19215   [(set (match_operand 0 "register_operand" "")
19216         (const_int -1))]
19217   "(GET_MODE (operands[0]) == HImode
19218     || GET_MODE (operands[0]) == SImode 
19219     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19220    && (optimize_size || TARGET_PENTIUM)
19221    && peep2_regno_dead_p (0, FLAGS_REG)"
19222   [(parallel [(set (match_dup 0) (const_int -1))
19223               (clobber (reg:CC FLAGS_REG))])]
19224   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19225                               operands[0]);")
19227 ;; Attempt to convert simple leas to adds. These can be created by
19228 ;; move expanders.
19229 (define_peephole2
19230   [(set (match_operand:SI 0 "register_operand" "")
19231         (plus:SI (match_dup 0)
19232                  (match_operand:SI 1 "nonmemory_operand" "")))]
19233   "peep2_regno_dead_p (0, FLAGS_REG)"
19234   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19235               (clobber (reg:CC FLAGS_REG))])]
19236   "")
19238 (define_peephole2
19239   [(set (match_operand:SI 0 "register_operand" "")
19240         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19241                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19242   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19243   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19244               (clobber (reg:CC FLAGS_REG))])]
19245   "operands[2] = gen_lowpart (SImode, operands[2]);")
19247 (define_peephole2
19248   [(set (match_operand:DI 0 "register_operand" "")
19249         (plus:DI (match_dup 0)
19250                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19251   "peep2_regno_dead_p (0, FLAGS_REG)"
19252   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19253               (clobber (reg:CC FLAGS_REG))])]
19254   "")
19256 (define_peephole2
19257   [(set (match_operand:SI 0 "register_operand" "")
19258         (mult:SI (match_dup 0)
19259                  (match_operand:SI 1 "const_int_operand" "")))]
19260   "exact_log2 (INTVAL (operands[1])) >= 0
19261    && peep2_regno_dead_p (0, FLAGS_REG)"
19262   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19263               (clobber (reg:CC FLAGS_REG))])]
19264   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19266 (define_peephole2
19267   [(set (match_operand:DI 0 "register_operand" "")
19268         (mult:DI (match_dup 0)
19269                  (match_operand:DI 1 "const_int_operand" "")))]
19270   "exact_log2 (INTVAL (operands[1])) >= 0
19271    && peep2_regno_dead_p (0, FLAGS_REG)"
19272   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19273               (clobber (reg:CC FLAGS_REG))])]
19274   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19276 (define_peephole2
19277   [(set (match_operand:SI 0 "register_operand" "")
19278         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19279                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19280   "exact_log2 (INTVAL (operands[2])) >= 0
19281    && REGNO (operands[0]) == REGNO (operands[1])
19282    && peep2_regno_dead_p (0, FLAGS_REG)"
19283   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19284               (clobber (reg:CC FLAGS_REG))])]
19285   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19287 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19288 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19289 ;; many CPUs it is also faster, since special hardware to avoid esp
19290 ;; dependencies is present.
19292 ;; While some of these conversions may be done using splitters, we use peepholes
19293 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19295 ;; Convert prologue esp subtractions to push.
19296 ;; We need register to push.  In order to keep verify_flow_info happy we have
19297 ;; two choices
19298 ;; - use scratch and clobber it in order to avoid dependencies
19299 ;; - use already live register
19300 ;; We can't use the second way right now, since there is no reliable way how to
19301 ;; verify that given register is live.  First choice will also most likely in
19302 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19303 ;; call clobbered registers are dead.  We may want to use base pointer as an
19304 ;; alternative when no register is available later.
19306 (define_peephole2
19307   [(match_scratch:SI 0 "r")
19308    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19309               (clobber (reg:CC FLAGS_REG))
19310               (clobber (mem:BLK (scratch)))])]
19311   "optimize_size || !TARGET_SUB_ESP_4"
19312   [(clobber (match_dup 0))
19313    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19314               (clobber (mem:BLK (scratch)))])])
19316 (define_peephole2
19317   [(match_scratch:SI 0 "r")
19318    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19319               (clobber (reg:CC FLAGS_REG))
19320               (clobber (mem:BLK (scratch)))])]
19321   "optimize_size || !TARGET_SUB_ESP_8"
19322   [(clobber (match_dup 0))
19323    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19324    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19325               (clobber (mem:BLK (scratch)))])])
19327 ;; Convert esp subtractions to push.
19328 (define_peephole2
19329   [(match_scratch:SI 0 "r")
19330    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "optimize_size || !TARGET_SUB_ESP_4"
19333   [(clobber (match_dup 0))
19334    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19336 (define_peephole2
19337   [(match_scratch:SI 0 "r")
19338    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "optimize_size || !TARGET_SUB_ESP_8"
19341   [(clobber (match_dup 0))
19342    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19343    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19345 ;; Convert epilogue deallocator to pop.
19346 (define_peephole2
19347   [(match_scratch:SI 0 "r")
19348    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19349               (clobber (reg:CC FLAGS_REG))
19350               (clobber (mem:BLK (scratch)))])]
19351   "optimize_size || !TARGET_ADD_ESP_4"
19352   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19353               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19354               (clobber (mem:BLK (scratch)))])]
19355   "")
19357 ;; Two pops case is tricky, since pop causes dependency on destination register.
19358 ;; We use two registers if available.
19359 (define_peephole2
19360   [(match_scratch:SI 0 "r")
19361    (match_scratch:SI 1 "r")
19362    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19363               (clobber (reg:CC FLAGS_REG))
19364               (clobber (mem:BLK (scratch)))])]
19365   "optimize_size || !TARGET_ADD_ESP_8"
19366   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19367               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19368               (clobber (mem:BLK (scratch)))])
19369    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19370               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19371   "")
19373 (define_peephole2
19374   [(match_scratch:SI 0 "r")
19375    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19376               (clobber (reg:CC FLAGS_REG))
19377               (clobber (mem:BLK (scratch)))])]
19378   "optimize_size"
19379   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19380               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19381               (clobber (mem:BLK (scratch)))])
19382    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19383               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19384   "")
19386 ;; Convert esp additions to pop.
19387 (define_peephole2
19388   [(match_scratch:SI 0 "r")
19389    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19390               (clobber (reg:CC FLAGS_REG))])]
19391   ""
19392   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19393               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19394   "")
19396 ;; Two pops case is tricky, since pop causes dependency on destination register.
19397 ;; We use two registers if available.
19398 (define_peephole2
19399   [(match_scratch:SI 0 "r")
19400    (match_scratch:SI 1 "r")
19401    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19402               (clobber (reg:CC FLAGS_REG))])]
19403   ""
19404   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19405               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19406    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19407               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19408   "")
19410 (define_peephole2
19411   [(match_scratch:SI 0 "r")
19412    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19413               (clobber (reg:CC FLAGS_REG))])]
19414   "optimize_size"
19415   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19416               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19417    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19418               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19419   "")
19421 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19422 ;; required and register dies.  Similarly for 128 to plus -128.
19423 (define_peephole2
19424   [(set (match_operand 0 "flags_reg_operand" "")
19425         (match_operator 1 "compare_operator"
19426           [(match_operand 2 "register_operand" "")
19427            (match_operand 3 "const_int_operand" "")]))]
19428   "(INTVAL (operands[3]) == -1
19429     || INTVAL (operands[3]) == 1
19430     || INTVAL (operands[3]) == 128)
19431    && ix86_match_ccmode (insn, CCGCmode)
19432    && peep2_reg_dead_p (1, operands[2])"
19433   [(parallel [(set (match_dup 0)
19434                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19435               (clobber (match_dup 2))])]
19436   "")
19438 (define_peephole2
19439   [(match_scratch:DI 0 "r")
19440    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19441               (clobber (reg:CC FLAGS_REG))
19442               (clobber (mem:BLK (scratch)))])]
19443   "optimize_size || !TARGET_SUB_ESP_4"
19444   [(clobber (match_dup 0))
19445    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19446               (clobber (mem:BLK (scratch)))])])
19448 (define_peephole2
19449   [(match_scratch:DI 0 "r")
19450    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19451               (clobber (reg:CC FLAGS_REG))
19452               (clobber (mem:BLK (scratch)))])]
19453   "optimize_size || !TARGET_SUB_ESP_8"
19454   [(clobber (match_dup 0))
19455    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19456    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19457               (clobber (mem:BLK (scratch)))])])
19459 ;; Convert esp subtractions to push.
19460 (define_peephole2
19461   [(match_scratch:DI 0 "r")
19462    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19463               (clobber (reg:CC FLAGS_REG))])]
19464   "optimize_size || !TARGET_SUB_ESP_4"
19465   [(clobber (match_dup 0))
19466    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19468 (define_peephole2
19469   [(match_scratch:DI 0 "r")
19470    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19471               (clobber (reg:CC FLAGS_REG))])]
19472   "optimize_size || !TARGET_SUB_ESP_8"
19473   [(clobber (match_dup 0))
19474    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19475    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19477 ;; Convert epilogue deallocator to pop.
19478 (define_peephole2
19479   [(match_scratch:DI 0 "r")
19480    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19481               (clobber (reg:CC FLAGS_REG))
19482               (clobber (mem:BLK (scratch)))])]
19483   "optimize_size || !TARGET_ADD_ESP_4"
19484   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19485               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19486               (clobber (mem:BLK (scratch)))])]
19487   "")
19489 ;; Two pops case is tricky, since pop causes dependency on destination register.
19490 ;; We use two registers if available.
19491 (define_peephole2
19492   [(match_scratch:DI 0 "r")
19493    (match_scratch:DI 1 "r")
19494    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19495               (clobber (reg:CC FLAGS_REG))
19496               (clobber (mem:BLK (scratch)))])]
19497   "optimize_size || !TARGET_ADD_ESP_8"
19498   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19499               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19500               (clobber (mem:BLK (scratch)))])
19501    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19502               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19503   "")
19505 (define_peephole2
19506   [(match_scratch:DI 0 "r")
19507    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19508               (clobber (reg:CC FLAGS_REG))
19509               (clobber (mem:BLK (scratch)))])]
19510   "optimize_size"
19511   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19512               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19513               (clobber (mem:BLK (scratch)))])
19514    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19515               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19516   "")
19518 ;; Convert esp additions to pop.
19519 (define_peephole2
19520   [(match_scratch:DI 0 "r")
19521    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19522               (clobber (reg:CC FLAGS_REG))])]
19523   ""
19524   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19525               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19526   "")
19528 ;; Two pops case is tricky, since pop causes dependency on destination register.
19529 ;; We use two registers if available.
19530 (define_peephole2
19531   [(match_scratch:DI 0 "r")
19532    (match_scratch:DI 1 "r")
19533    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19534               (clobber (reg:CC FLAGS_REG))])]
19535   ""
19536   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19537               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19538    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19539               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19540   "")
19542 (define_peephole2
19543   [(match_scratch:DI 0 "r")
19544    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19545               (clobber (reg:CC FLAGS_REG))])]
19546   "optimize_size"
19547   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19548               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19549    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19550               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19551   "")
19553 ;; Convert imul by three, five and nine into lea
19554 (define_peephole2
19555   [(parallel
19556     [(set (match_operand:SI 0 "register_operand" "")
19557           (mult:SI (match_operand:SI 1 "register_operand" "")
19558                    (match_operand:SI 2 "const_int_operand" "")))
19559      (clobber (reg:CC FLAGS_REG))])]
19560   "INTVAL (operands[2]) == 3
19561    || INTVAL (operands[2]) == 5
19562    || INTVAL (operands[2]) == 9"
19563   [(set (match_dup 0)
19564         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19565                  (match_dup 1)))]
19566   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19568 (define_peephole2
19569   [(parallel
19570     [(set (match_operand:SI 0 "register_operand" "")
19571           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19572                    (match_operand:SI 2 "const_int_operand" "")))
19573      (clobber (reg:CC FLAGS_REG))])]
19574   "!optimize_size 
19575    && (INTVAL (operands[2]) == 3
19576        || INTVAL (operands[2]) == 5
19577        || INTVAL (operands[2]) == 9)"
19578   [(set (match_dup 0) (match_dup 1))
19579    (set (match_dup 0)
19580         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19581                  (match_dup 0)))]
19582   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19584 (define_peephole2
19585   [(parallel
19586     [(set (match_operand:DI 0 "register_operand" "")
19587           (mult:DI (match_operand:DI 1 "register_operand" "")
19588                    (match_operand:DI 2 "const_int_operand" "")))
19589      (clobber (reg:CC FLAGS_REG))])]
19590   "TARGET_64BIT
19591    && (INTVAL (operands[2]) == 3
19592        || INTVAL (operands[2]) == 5
19593        || INTVAL (operands[2]) == 9)"
19594   [(set (match_dup 0)
19595         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19596                  (match_dup 1)))]
19597   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19599 (define_peephole2
19600   [(parallel
19601     [(set (match_operand:DI 0 "register_operand" "")
19602           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19603                    (match_operand:DI 2 "const_int_operand" "")))
19604      (clobber (reg:CC FLAGS_REG))])]
19605   "TARGET_64BIT
19606    && !optimize_size 
19607    && (INTVAL (operands[2]) == 3
19608        || INTVAL (operands[2]) == 5
19609        || INTVAL (operands[2]) == 9)"
19610   [(set (match_dup 0) (match_dup 1))
19611    (set (match_dup 0)
19612         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19613                  (match_dup 0)))]
19614   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19616 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19617 ;; imul $32bit_imm, reg, reg is direct decoded.
19618 (define_peephole2
19619   [(match_scratch:DI 3 "r")
19620    (parallel [(set (match_operand:DI 0 "register_operand" "")
19621                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19622                             (match_operand:DI 2 "immediate_operand" "")))
19623               (clobber (reg:CC FLAGS_REG))])]
19624   "TARGET_K8 && !optimize_size
19625    && (GET_CODE (operands[2]) != CONST_INT
19626        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19627   [(set (match_dup 3) (match_dup 1))
19628    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19629               (clobber (reg:CC FLAGS_REG))])]
19632 (define_peephole2
19633   [(match_scratch:SI 3 "r")
19634    (parallel [(set (match_operand:SI 0 "register_operand" "")
19635                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19636                             (match_operand:SI 2 "immediate_operand" "")))
19637               (clobber (reg:CC FLAGS_REG))])]
19638   "TARGET_K8 && !optimize_size
19639    && (GET_CODE (operands[2]) != CONST_INT
19640        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19641   [(set (match_dup 3) (match_dup 1))
19642    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19643               (clobber (reg:CC FLAGS_REG))])]
19646 (define_peephole2
19647   [(match_scratch:SI 3 "r")
19648    (parallel [(set (match_operand:DI 0 "register_operand" "")
19649                    (zero_extend:DI
19650                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19651                               (match_operand:SI 2 "immediate_operand" ""))))
19652               (clobber (reg:CC FLAGS_REG))])]
19653   "TARGET_K8 && !optimize_size
19654    && (GET_CODE (operands[2]) != CONST_INT
19655        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19656   [(set (match_dup 3) (match_dup 1))
19657    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19658               (clobber (reg:CC FLAGS_REG))])]
19661 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19662 ;; Convert it into imul reg, reg
19663 ;; It would be better to force assembler to encode instruction using long
19664 ;; immediate, but there is apparently no way to do so.
19665 (define_peephole2
19666   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19667                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19668                             (match_operand:DI 2 "const_int_operand" "")))
19669               (clobber (reg:CC FLAGS_REG))])
19670    (match_scratch:DI 3 "r")]
19671   "TARGET_K8 && !optimize_size
19672    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19673   [(set (match_dup 3) (match_dup 2))
19674    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19675               (clobber (reg:CC FLAGS_REG))])]
19677   if (!rtx_equal_p (operands[0], operands[1]))
19678     emit_move_insn (operands[0], operands[1]);
19681 (define_peephole2
19682   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19683                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19684                             (match_operand:SI 2 "const_int_operand" "")))
19685               (clobber (reg:CC FLAGS_REG))])
19686    (match_scratch:SI 3 "r")]
19687   "TARGET_K8 && !optimize_size
19688    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19689   [(set (match_dup 3) (match_dup 2))
19690    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19691               (clobber (reg:CC FLAGS_REG))])]
19693   if (!rtx_equal_p (operands[0], operands[1]))
19694     emit_move_insn (operands[0], operands[1]);
19697 (define_peephole2
19698   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19699                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19700                             (match_operand:HI 2 "immediate_operand" "")))
19701               (clobber (reg:CC FLAGS_REG))])
19702    (match_scratch:HI 3 "r")]
19703   "TARGET_K8 && !optimize_size"
19704   [(set (match_dup 3) (match_dup 2))
19705    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19706               (clobber (reg:CC FLAGS_REG))])]
19708   if (!rtx_equal_p (operands[0], operands[1]))
19709     emit_move_insn (operands[0], operands[1]);
19712 ;; Call-value patterns last so that the wildcard operand does not
19713 ;; disrupt insn-recog's switch tables.
19715 (define_insn "*call_value_pop_0"
19716   [(set (match_operand 0 "" "")
19717         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19718               (match_operand:SI 2 "" "")))
19719    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19720                             (match_operand:SI 3 "immediate_operand" "")))]
19721   "!TARGET_64BIT"
19723   if (SIBLING_CALL_P (insn))
19724     return "jmp\t%P1";
19725   else
19726     return "call\t%P1";
19728   [(set_attr "type" "callv")])
19730 (define_insn "*call_value_pop_1"
19731   [(set (match_operand 0 "" "")
19732         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19733               (match_operand:SI 2 "" "")))
19734    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19735                             (match_operand:SI 3 "immediate_operand" "i")))]
19736   "!TARGET_64BIT"
19738   if (constant_call_address_operand (operands[1], Pmode))
19739     {
19740       if (SIBLING_CALL_P (insn))
19741         return "jmp\t%P1";
19742       else
19743         return "call\t%P1";
19744     }
19745   if (SIBLING_CALL_P (insn))
19746     return "jmp\t%A1";
19747   else
19748     return "call\t%A1";
19750   [(set_attr "type" "callv")])
19752 (define_insn "*call_value_0"
19753   [(set (match_operand 0 "" "")
19754         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19755               (match_operand:SI 2 "" "")))]
19756   "!TARGET_64BIT"
19758   if (SIBLING_CALL_P (insn))
19759     return "jmp\t%P1";
19760   else
19761     return "call\t%P1";
19763   [(set_attr "type" "callv")])
19765 (define_insn "*call_value_0_rex64"
19766   [(set (match_operand 0 "" "")
19767         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19768               (match_operand:DI 2 "const_int_operand" "")))]
19769   "TARGET_64BIT"
19771   if (SIBLING_CALL_P (insn))
19772     return "jmp\t%P1";
19773   else
19774     return "call\t%P1";
19776   [(set_attr "type" "callv")])
19778 (define_insn "*call_value_1"
19779   [(set (match_operand 0 "" "")
19780         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19781               (match_operand:SI 2 "" "")))]
19782   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19784   if (constant_call_address_operand (operands[1], Pmode))
19785     return "call\t%P1";
19786   return "call\t%A1";
19788   [(set_attr "type" "callv")])
19790 (define_insn "*sibcall_value_1"
19791   [(set (match_operand 0 "" "")
19792         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19793               (match_operand:SI 2 "" "")))]
19794   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19796   if (constant_call_address_operand (operands[1], Pmode))
19797     return "jmp\t%P1";
19798   return "jmp\t%A1";
19800   [(set_attr "type" "callv")])
19802 (define_insn "*call_value_1_rex64"
19803   [(set (match_operand 0 "" "")
19804         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19805               (match_operand:DI 2 "" "")))]
19806   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19808   if (constant_call_address_operand (operands[1], Pmode))
19809     return "call\t%P1";
19810   return "call\t%A1";
19812   [(set_attr "type" "callv")])
19814 (define_insn "*sibcall_value_1_rex64"
19815   [(set (match_operand 0 "" "")
19816         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19817               (match_operand:DI 2 "" "")))]
19818   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19819   "jmp\t%P1"
19820   [(set_attr "type" "callv")])
19822 (define_insn "*sibcall_value_1_rex64_v"
19823   [(set (match_operand 0 "" "")
19824         (call (mem:QI (reg:DI 40))
19825               (match_operand:DI 1 "" "")))]
19826   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19827   "jmp\t*%%r11"
19828   [(set_attr "type" "callv")])
19830 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19831 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19832 ;; caught for use by garbage collectors and the like.  Using an insn that
19833 ;; maps to SIGILL makes it more likely the program will rightfully die.
19834 ;; Keeping with tradition, "6" is in honor of #UD.
19835 (define_insn "trap"
19836   [(trap_if (const_int 1) (const_int 6))]
19837   ""
19838   ".word\t0x0b0f"
19839   [(set_attr "length" "2")])
19841 (define_expand "sse_prologue_save"
19842   [(parallel [(set (match_operand:BLK 0 "" "")
19843                    (unspec:BLK [(reg:DI 21)
19844                                 (reg:DI 22)
19845                                 (reg:DI 23)
19846                                 (reg:DI 24)
19847                                 (reg:DI 25)
19848                                 (reg:DI 26)
19849                                 (reg:DI 27)
19850                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19851               (use (match_operand:DI 1 "register_operand" ""))
19852               (use (match_operand:DI 2 "immediate_operand" ""))
19853               (use (label_ref:DI (match_operand 3 "" "")))])]
19854   "TARGET_64BIT"
19855   "")
19857 (define_insn "*sse_prologue_save_insn"
19858   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19859                           (match_operand:DI 4 "const_int_operand" "n")))
19860         (unspec:BLK [(reg:DI 21)
19861                      (reg:DI 22)
19862                      (reg:DI 23)
19863                      (reg:DI 24)
19864                      (reg:DI 25)
19865                      (reg:DI 26)
19866                      (reg:DI 27)
19867                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19868    (use (match_operand:DI 1 "register_operand" "r"))
19869    (use (match_operand:DI 2 "const_int_operand" "i"))
19870    (use (label_ref:DI (match_operand 3 "" "X")))]
19871   "TARGET_64BIT
19872    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19873    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19874   "*
19876   int i;
19877   operands[0] = gen_rtx_MEM (Pmode,
19878                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19879   output_asm_insn (\"jmp\\t%A1\", operands);
19880   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19881     {
19882       operands[4] = adjust_address (operands[0], DImode, i*16);
19883       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19884       PUT_MODE (operands[4], TImode);
19885       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19886         output_asm_insn (\"rex\", operands);
19887       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19888     }
19889   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19890                              CODE_LABEL_NUMBER (operands[3]));
19891   RET;
19893   "
19894   [(set_attr "type" "other")
19895    (set_attr "length_immediate" "0")
19896    (set_attr "length_address" "0")
19897    (set_attr "length" "135")
19898    (set_attr "memory" "store")
19899    (set_attr "modrm" "0")
19900    (set_attr "mode" "DI")])
19902 (define_expand "prefetch"
19903   [(prefetch (match_operand 0 "address_operand" "")
19904              (match_operand:SI 1 "const_int_operand" "")
19905              (match_operand:SI 2 "const_int_operand" ""))]
19906   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19908   int rw = INTVAL (operands[1]);
19909   int locality = INTVAL (operands[2]);
19911   gcc_assert (rw == 0 || rw == 1);
19912   gcc_assert (locality >= 0 && locality <= 3);
19913   gcc_assert (GET_MODE (operands[0]) == Pmode
19914               || GET_MODE (operands[0]) == VOIDmode);
19916   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19917      supported by SSE counterpart or the SSE prefetch is not available
19918      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19919      of locality.  */
19920   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19921     operands[2] = GEN_INT (3);
19922   else
19923     operands[1] = const0_rtx;
19926 (define_insn "*prefetch_sse"
19927   [(prefetch (match_operand:SI 0 "address_operand" "p")
19928              (const_int 0)
19929              (match_operand:SI 1 "const_int_operand" ""))]
19930   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19932   static const char * const patterns[4] = {
19933    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19934   };
19936   int locality = INTVAL (operands[1]);
19937   gcc_assert (locality >= 0 && locality <= 3);
19939   return patterns[locality];  
19941   [(set_attr "type" "sse")
19942    (set_attr "memory" "none")])
19944 (define_insn "*prefetch_sse_rex"
19945   [(prefetch (match_operand:DI 0 "address_operand" "p")
19946              (const_int 0)
19947              (match_operand:SI 1 "const_int_operand" ""))]
19948   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19950   static const char * const patterns[4] = {
19951    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19952   };
19954   int locality = INTVAL (operands[1]);
19955   gcc_assert (locality >= 0 && locality <= 3);
19957   return patterns[locality];  
19959   [(set_attr "type" "sse")
19960    (set_attr "memory" "none")])
19962 (define_insn "*prefetch_3dnow"
19963   [(prefetch (match_operand:SI 0 "address_operand" "p")
19964              (match_operand:SI 1 "const_int_operand" "n")
19965              (const_int 3))]
19966   "TARGET_3DNOW && !TARGET_64BIT"
19968   if (INTVAL (operands[1]) == 0)
19969     return "prefetch\t%a0";
19970   else
19971     return "prefetchw\t%a0";
19973   [(set_attr "type" "mmx")
19974    (set_attr "memory" "none")])
19976 (define_insn "*prefetch_3dnow_rex"
19977   [(prefetch (match_operand:DI 0 "address_operand" "p")
19978              (match_operand:SI 1 "const_int_operand" "n")
19979              (const_int 3))]
19980   "TARGET_3DNOW && TARGET_64BIT"
19982   if (INTVAL (operands[1]) == 0)
19983     return "prefetch\t%a0";
19984   else
19985     return "prefetchw\t%a0";
19987   [(set_attr "type" "mmx")
19988    (set_attr "memory" "none")])
19990 (define_expand "stack_protect_set"
19991   [(match_operand 0 "memory_operand" "")
19992    (match_operand 1 "memory_operand" "")]
19993   ""
19995 #ifdef TARGET_THREAD_SSP_OFFSET
19996   if (TARGET_64BIT)
19997     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19998                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19999   else
20000     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20001                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20002 #else
20003   if (TARGET_64BIT)
20004     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20005   else
20006     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20007 #endif
20008   DONE;
20011 (define_insn "stack_protect_set_si"
20012   [(set (match_operand:SI 0 "memory_operand" "=m")
20013         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20014    (set (match_scratch:SI 2 "=&r") (const_int 0))
20015    (clobber (reg:CC FLAGS_REG))]
20016   ""
20017   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20018   [(set_attr "type" "multi")])
20020 (define_insn "stack_protect_set_di"
20021   [(set (match_operand:DI 0 "memory_operand" "=m")
20022         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20023    (set (match_scratch:DI 2 "=&r") (const_int 0))
20024    (clobber (reg:CC FLAGS_REG))]
20025   "TARGET_64BIT"
20026   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20027   [(set_attr "type" "multi")])
20029 (define_insn "stack_tls_protect_set_si"
20030   [(set (match_operand:SI 0 "memory_operand" "=m")
20031         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20032    (set (match_scratch:SI 2 "=&r") (const_int 0))
20033    (clobber (reg:CC FLAGS_REG))]
20034   ""
20035   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20036   [(set_attr "type" "multi")])
20038 (define_insn "stack_tls_protect_set_di"
20039   [(set (match_operand:DI 0 "memory_operand" "=m")
20040         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20041    (set (match_scratch:DI 2 "=&r") (const_int 0))
20042    (clobber (reg:CC FLAGS_REG))]
20043   "TARGET_64BIT"
20044   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20045   [(set_attr "type" "multi")])
20047 (define_expand "stack_protect_test"
20048   [(match_operand 0 "memory_operand" "")
20049    (match_operand 1 "memory_operand" "")
20050    (match_operand 2 "" "")]
20051   ""
20053   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20054   ix86_compare_op0 = operands[0];
20055   ix86_compare_op1 = operands[1];
20056   ix86_compare_emitted = flags;
20058 #ifdef TARGET_THREAD_SSP_OFFSET
20059   if (TARGET_64BIT)
20060     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20061                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20062   else
20063     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20064                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20065 #else
20066   if (TARGET_64BIT)
20067     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20068   else
20069     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20070 #endif
20071   emit_jump_insn (gen_beq (operands[2]));
20072   DONE;
20075 (define_insn "stack_protect_test_si"
20076   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20077         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20078                      (match_operand:SI 2 "memory_operand" "m")]
20079                     UNSPEC_SP_TEST))
20080    (clobber (match_scratch:SI 3 "=&r"))]
20081   ""
20082   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20083   [(set_attr "type" "multi")])
20085 (define_insn "stack_protect_test_di"
20086   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20087         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20088                      (match_operand:DI 2 "memory_operand" "m")]
20089                     UNSPEC_SP_TEST))
20090    (clobber (match_scratch:DI 3 "=&r"))]
20091   "TARGET_64BIT"
20092   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20093   [(set_attr "type" "multi")])
20095 (define_insn "stack_tls_protect_test_si"
20096   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20097         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20098                      (match_operand:SI 2 "const_int_operand" "i")]
20099                     UNSPEC_SP_TLS_TEST))
20100    (clobber (match_scratch:SI 3 "=r"))]
20101   ""
20102   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20103   [(set_attr "type" "multi")])
20105 (define_insn "stack_tls_protect_test_di"
20106   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20107         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20108                      (match_operand:DI 2 "const_int_operand" "i")]
20109                     UNSPEC_SP_TLS_TEST))
20110    (clobber (match_scratch:DI 3 "=r"))]
20111   "TARGET_64BIT"
20112   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20113   [(set_attr "type" "multi")])
20115 (include "sse.md")
20116 (include "mmx.md")
20117 (include "sync.md")