OSDN Git Service

622686beeaf109b1e6d9c9c3a42e25db6d7eae2d
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 3, or (at your option)
13 ;; any later version.
14 ;;
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.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_NOP                  48)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                49)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123    (UNSPEC_TAN                  68)
124    (UNSPEC_FXAM                 69)
125
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
133
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    (UNSPEC_C2_FLAG              95)
147
148    ; SSP patterns
149    (UNSPEC_SP_SET               100)
150    (UNSPEC_SP_TEST              101)
151    (UNSPEC_SP_TLS_SET           102)
152    (UNSPEC_SP_TLS_TEST          103)
153
154    ; SSSE3
155    (UNSPEC_PSHUFB               120)
156    (UNSPEC_PSIGN                121)
157    (UNSPEC_PALIGNR              122)
158
159    ; For SSE4A support
160    (UNSPEC_EXTRQI               130)
161    (UNSPEC_EXTRQ                131)   
162    (UNSPEC_INSERTQI             132)
163    (UNSPEC_INSERTQ              133)
164
165    ; For SSE4.1 support
166    (UNSPEC_BLENDV               134)
167    (UNSPEC_INSERTPS             135)
168    (UNSPEC_DP                   136)
169    (UNSPEC_MOVNTDQA             137)
170    (UNSPEC_MPSADBW              138)
171    (UNSPEC_PHMINPOSUW           139)
172    (UNSPEC_PTEST                140)
173    (UNSPEC_ROUND                141)
174
175    ; For SSE4.2 support
176    (UNSPEC_CRC32                143)
177    (UNSPEC_PCMPESTR             144)
178    (UNSPEC_PCMPISTR             145)
179
180    ;; For SSE5
181    (UNSPEC_SSE5_INTRINSIC       150)
182    (UNSPEC_SSE5_UNSIGNED_CMP    151)
183    (UNSPEC_SSE5_TRUEFALSE       152)
184    (UNSPEC_SSE5_PERMUTE         153)
185    (UNSPEC_SSE5_ASHIFT          154)
186    (UNSPEC_SSE5_LSHIFT          155)
187    (UNSPEC_FRCZ                 156)
188    (UNSPEC_CVTPH2PS             157)
189    (UNSPEC_CVTPS2PH             158)
190   ])
191
192 (define_constants
193   [(UNSPECV_BLOCKAGE            0)
194    (UNSPECV_STACK_PROBE         1)
195    (UNSPECV_EMMS                2)
196    (UNSPECV_LDMXCSR             3)
197    (UNSPECV_STMXCSR             4)
198    (UNSPECV_FEMMS               5)
199    (UNSPECV_CLFLUSH             6)
200    (UNSPECV_ALIGN               7)
201    (UNSPECV_MONITOR             8)
202    (UNSPECV_MWAIT               9)
203    (UNSPECV_CMPXCHG_1           10)
204    (UNSPECV_CMPXCHG_2           11)
205    (UNSPECV_XCHG                12)
206    (UNSPECV_LOCK                13)
207    (UNSPECV_PROLOGUE_USE        14)
208   ])
209
210 ;; Constants to represent pcomtrue/pcomfalse varients
211 (define_constants
212   [(PCOM_FALSE                  0)
213    (PCOM_TRUE                   1)
214    (COM_FALSE_S                 2)
215    (COM_FALSE_P                 3)
216    (COM_TRUE_S                  4)
217    (COM_TRUE_P                  5)
218   ])
219
220 ;; Registers by name.
221 (define_constants
222   [(BP_REG                       6)
223    (SP_REG                       7)
224    (FLAGS_REG                   17)
225    (FPSR_REG                    18)
226    (FPCR_REG                    19)
227    (R10_REG                     39)
228    (R11_REG                     40)
229   ])
230
231 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
232 ;; from i386.c.
233
234 ;; In C guard expressions, put expressions which may be compile-time
235 ;; constants first.  This allows for better optimization.  For
236 ;; example, write "TARGET_64BIT && reload_completed", not
237 ;; "reload_completed && TARGET_64BIT".
238
239 \f
240 ;; Processor type.  This attribute must exactly match the processor_type
241 ;; enumeration in i386.h.
242 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
243                     nocona,core2,generic32,generic64,amdfam10"
244   (const (symbol_ref "ix86_tune")))
245
246 ;; A basic instruction type.  Refinements due to arguments to be
247 ;; provided in other attributes.
248 (define_attr "type"
249   "other,multi,
250    alu,alu1,negnot,imov,imovx,lea,
251    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
252    icmp,test,ibr,setcc,icmov,
253    push,pop,call,callv,leave,
254    str,bitmanip,
255    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
256    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
257    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
258    ssemuladd,sse4arg,
259    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
260   (const_string "other"))
261
262 ;; Main data type used by the insn
263 (define_attr "mode"
264   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
265   (const_string "unknown"))
266
267 ;; The CPU unit operations uses.
268 (define_attr "unit" "integer,i387,sse,mmx,unknown"
269   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
270            (const_string "i387")
271          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
273                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
274            (const_string "sse")
275          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
276            (const_string "mmx")
277          (eq_attr "type" "other")
278            (const_string "unknown")]
279          (const_string "integer")))
280
281 ;; The (bounding maximum) length of an instruction immediate.
282 (define_attr "length_immediate" ""
283   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
284                           bitmanip")
285            (const_int 0)
286          (eq_attr "unit" "i387,sse,mmx")
287            (const_int 0)
288          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
289                           imul,icmp,push,pop")
290            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
291          (eq_attr "type" "imov,test")
292            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
293          (eq_attr "type" "call")
294            (if_then_else (match_operand 0 "constant_call_address_operand" "")
295              (const_int 4)
296              (const_int 0))
297          (eq_attr "type" "callv")
298            (if_then_else (match_operand 1 "constant_call_address_operand" "")
299              (const_int 4)
300              (const_int 0))
301          ;; We don't know the size before shorten_branches.  Expect
302          ;; the instruction to fit for better scheduling.
303          (eq_attr "type" "ibr")
304            (const_int 1)
305          ]
306          (symbol_ref "/* Update immediate_length and other attributes! */
307                       gcc_unreachable (),1")))
308
309 ;; The (bounding maximum) length of an instruction address.
310 (define_attr "length_address" ""
311   (cond [(eq_attr "type" "str,other,multi,fxch")
312            (const_int 0)
313          (and (eq_attr "type" "call")
314               (match_operand 0 "constant_call_address_operand" ""))
315              (const_int 0)
316          (and (eq_attr "type" "callv")
317               (match_operand 1 "constant_call_address_operand" ""))
318              (const_int 0)
319          ]
320          (symbol_ref "ix86_attr_length_address_default (insn)")))
321
322 ;; Set when length prefix is used.
323 (define_attr "prefix_data16" ""
324   (if_then_else (ior (eq_attr "mode" "HI")
325                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
326     (const_int 1)
327     (const_int 0)))
328
329 ;; Set when string REP prefix is used.
330 (define_attr "prefix_rep" ""
331   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
332     (const_int 1)
333     (const_int 0)))
334
335 ;; Set when 0f opcode prefix is used.
336 (define_attr "prefix_0f" ""
337   (if_then_else
338     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
339          (eq_attr "unit" "sse,mmx"))
340     (const_int 1)
341     (const_int 0)))
342
343 ;; Set when REX opcode prefix is used.
344 (define_attr "prefix_rex" ""
345   (cond [(and (eq_attr "mode" "DI")
346               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
347            (const_int 1)
348          (and (eq_attr "mode" "QI")
349               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
350                   (const_int 0)))
351            (const_int 1)
352          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
353              (const_int 0))
354            (const_int 1)
355         ]
356         (const_int 0)))
357
358 ;; There are also additional prefixes in SSSE3.
359 (define_attr "prefix_extra" "" (const_int 0))
360
361 ;; Set when modrm byte is used.
362 (define_attr "modrm" ""
363   (cond [(eq_attr "type" "str,leave")
364            (const_int 0)
365          (eq_attr "unit" "i387")
366            (const_int 0)
367          (and (eq_attr "type" "incdec")
368               (ior (match_operand:SI 1 "register_operand" "")
369                    (match_operand:HI 1 "register_operand" "")))
370            (const_int 0)
371          (and (eq_attr "type" "push")
372               (not (match_operand 1 "memory_operand" "")))
373            (const_int 0)
374          (and (eq_attr "type" "pop")
375               (not (match_operand 0 "memory_operand" "")))
376            (const_int 0)
377          (and (eq_attr "type" "imov")
378               (ior (and (match_operand 0 "register_operand" "")
379                         (match_operand 1 "immediate_operand" ""))
380                    (ior (and (match_operand 0 "ax_reg_operand" "")
381                              (match_operand 1 "memory_displacement_only_operand" ""))
382                         (and (match_operand 0 "memory_displacement_only_operand" "")
383                              (match_operand 1 "ax_reg_operand" "")))))
384            (const_int 0)
385          (and (eq_attr "type" "call")
386               (match_operand 0 "constant_call_address_operand" ""))
387              (const_int 0)
388          (and (eq_attr "type" "callv")
389               (match_operand 1 "constant_call_address_operand" ""))
390              (const_int 0)
391          ]
392          (const_int 1)))
393
394 ;; The (bounding maximum) length of an instruction in bytes.
395 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
396 ;; Later we may want to split them and compute proper length as for
397 ;; other insns.
398 (define_attr "length" ""
399   (cond [(eq_attr "type" "other,multi,fistp,frndint")
400            (const_int 16)
401          (eq_attr "type" "fcmp")
402            (const_int 4)
403          (eq_attr "unit" "i387")
404            (plus (const_int 2)
405                  (plus (attr "prefix_data16")
406                        (attr "length_address")))]
407          (plus (plus (attr "modrm")
408                      (plus (attr "prefix_0f")
409                            (plus (attr "prefix_rex")
410                                  (plus (attr "prefix_extra")
411                                        (const_int 1)))))
412                (plus (attr "prefix_rep")
413                      (plus (attr "prefix_data16")
414                            (plus (attr "length_immediate")
415                                  (attr "length_address")))))))
416
417 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
418 ;; `store' if there is a simple memory reference therein, or `unknown'
419 ;; if the instruction is complex.
420
421 (define_attr "memory" "none,load,store,both,unknown"
422   (cond [(eq_attr "type" "other,multi,str")
423            (const_string "unknown")
424          (eq_attr "type" "lea,fcmov,fpspc")
425            (const_string "none")
426          (eq_attr "type" "fistp,leave")
427            (const_string "both")
428          (eq_attr "type" "frndint")
429            (const_string "load")
430          (eq_attr "type" "push")
431            (if_then_else (match_operand 1 "memory_operand" "")
432              (const_string "both")
433              (const_string "store"))
434          (eq_attr "type" "pop")
435            (if_then_else (match_operand 0 "memory_operand" "")
436              (const_string "both")
437              (const_string "load"))
438          (eq_attr "type" "setcc")
439            (if_then_else (match_operand 0 "memory_operand" "")
440              (const_string "store")
441              (const_string "none"))
442          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
443            (if_then_else (ior (match_operand 0 "memory_operand" "")
444                               (match_operand 1 "memory_operand" ""))
445              (const_string "load")
446              (const_string "none"))
447          (eq_attr "type" "ibr")
448            (if_then_else (match_operand 0 "memory_operand" "")
449              (const_string "load")
450              (const_string "none"))
451          (eq_attr "type" "call")
452            (if_then_else (match_operand 0 "constant_call_address_operand" "")
453              (const_string "none")
454              (const_string "load"))
455          (eq_attr "type" "callv")
456            (if_then_else (match_operand 1 "constant_call_address_operand" "")
457              (const_string "none")
458              (const_string "load"))
459          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
460               (match_operand 1 "memory_operand" ""))
461            (const_string "both")
462          (and (match_operand 0 "memory_operand" "")
463               (match_operand 1 "memory_operand" ""))
464            (const_string "both")
465          (match_operand 0 "memory_operand" "")
466            (const_string "store")
467          (match_operand 1 "memory_operand" "")
468            (const_string "load")
469          (and (eq_attr "type"
470                  "!alu1,negnot,ishift1,
471                    imov,imovx,icmp,test,bitmanip,
472                    fmov,fcmp,fsgn,
473                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
474                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
475               (match_operand 2 "memory_operand" ""))
476            (const_string "load")
477          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
478               (match_operand 3 "memory_operand" ""))
479            (const_string "load")
480         ]
481         (const_string "none")))
482
483 ;; Indicates if an instruction has both an immediate and a displacement.
484
485 (define_attr "imm_disp" "false,true,unknown"
486   (cond [(eq_attr "type" "other,multi")
487            (const_string "unknown")
488          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
489               (and (match_operand 0 "memory_displacement_operand" "")
490                    (match_operand 1 "immediate_operand" "")))
491            (const_string "true")
492          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
493               (and (match_operand 0 "memory_displacement_operand" "")
494                    (match_operand 2 "immediate_operand" "")))
495            (const_string "true")
496         ]
497         (const_string "false")))
498
499 ;; Indicates if an FP operation has an integer source.
500
501 (define_attr "fp_int_src" "false,true"
502   (const_string "false"))
503
504 ;; Defines rounding mode of an FP operation.
505
506 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
507   (const_string "any"))
508
509 ;; Describe a user's asm statement.
510 (define_asm_attributes
511   [(set_attr "length" "128")
512    (set_attr "type" "multi")])
513
514 (define_code_iterator plusminus [plus minus])
515
516 ;; Base name for define_insn and insn mnemonic.
517 (define_code_attr addsub [(plus "add") (minus "sub")])
518
519 ;; Mark commutative operators as such in constraints.
520 (define_code_attr comm [(plus "%") (minus "")])
521
522 ;; All single word integer modes.
523 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
524
525 ;; Instruction suffix for integer modes.
526 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
527
528 ;; Register class for integer modes.
529 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
530
531 ;; Immediate operand constraint for integer modes.
532 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
533
534 ;; General operand predicate for integer modes.
535 (define_mode_attr general_operand
536         [(QI "general_operand")
537          (HI "general_operand")
538          (SI "general_operand")
539          (DI "x86_64_general_operand")])
540
541 ;; SSE and x87 SFmode and DFmode floating point modes
542 (define_mode_iterator MODEF [SF DF])
543
544 ;; All x87 floating point modes
545 (define_mode_iterator X87MODEF [SF DF XF])
546
547 ;; All integer modes handled by x87 fisttp operator.
548 (define_mode_iterator X87MODEI [HI SI DI])
549
550 ;; All integer modes handled by integer x87 operators.
551 (define_mode_iterator X87MODEI12 [HI SI])
552
553 ;; All integer modes handled by SSE cvtts?2si* operators.
554 (define_mode_iterator SSEMODEI24 [SI DI])
555
556 ;; SSE asm suffix for floating point modes
557 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
558
559 ;; SSE vector mode corresponding to a scalar mode
560 (define_mode_attr ssevecmode
561   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
562 \f
563 ;; Scheduling descriptions
564
565 (include "pentium.md")
566 (include "ppro.md")
567 (include "k6.md")
568 (include "athlon.md")
569 (include "geode.md")
570
571 \f
572 ;; Operand and operator predicates and constraints
573
574 (include "predicates.md")
575 (include "constraints.md")
576
577 \f
578 ;; Compare instructions.
579
580 ;; All compare insns have expanders that save the operands away without
581 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
582 ;; after the cmp) will actually emit the cmpM.
583
584 (define_expand "cmpti"
585   [(set (reg:CC FLAGS_REG)
586         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
587                     (match_operand:TI 1 "x86_64_general_operand" "")))]
588   "TARGET_64BIT"
589 {
590   if (MEM_P (operands[0]) && MEM_P (operands[1]))
591     operands[0] = force_reg (TImode, operands[0]);
592   ix86_compare_op0 = operands[0];
593   ix86_compare_op1 = operands[1];
594   DONE;
595 })
596
597 (define_expand "cmpdi"
598   [(set (reg:CC FLAGS_REG)
599         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
600                     (match_operand:DI 1 "x86_64_general_operand" "")))]
601   ""
602 {
603   if (MEM_P (operands[0]) && MEM_P (operands[1]))
604     operands[0] = force_reg (DImode, operands[0]);
605   ix86_compare_op0 = operands[0];
606   ix86_compare_op1 = operands[1];
607   DONE;
608 })
609
610 (define_expand "cmpsi"
611   [(set (reg:CC FLAGS_REG)
612         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
613                     (match_operand:SI 1 "general_operand" "")))]
614   ""
615 {
616   if (MEM_P (operands[0]) && MEM_P (operands[1]))
617     operands[0] = force_reg (SImode, operands[0]);
618   ix86_compare_op0 = operands[0];
619   ix86_compare_op1 = operands[1];
620   DONE;
621 })
622
623 (define_expand "cmphi"
624   [(set (reg:CC FLAGS_REG)
625         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
626                     (match_operand:HI 1 "general_operand" "")))]
627   ""
628 {
629   if (MEM_P (operands[0]) && MEM_P (operands[1]))
630     operands[0] = force_reg (HImode, operands[0]);
631   ix86_compare_op0 = operands[0];
632   ix86_compare_op1 = operands[1];
633   DONE;
634 })
635
636 (define_expand "cmpqi"
637   [(set (reg:CC FLAGS_REG)
638         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
639                     (match_operand:QI 1 "general_operand" "")))]
640   "TARGET_QIMODE_MATH"
641 {
642   if (MEM_P (operands[0]) && MEM_P (operands[1]))
643     operands[0] = force_reg (QImode, operands[0]);
644   ix86_compare_op0 = operands[0];
645   ix86_compare_op1 = operands[1];
646   DONE;
647 })
648
649 (define_insn "cmpdi_ccno_1_rex64"
650   [(set (reg FLAGS_REG)
651         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
652                  (match_operand:DI 1 "const0_operand" "n,n")))]
653   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
654   "@
655    test{q}\t%0, %0
656    cmp{q}\t{%1, %0|%0, %1}"
657   [(set_attr "type" "test,icmp")
658    (set_attr "length_immediate" "0,1")
659    (set_attr "mode" "DI")])
660
661 (define_insn "*cmpdi_minus_1_rex64"
662   [(set (reg FLAGS_REG)
663         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
664                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
665                  (const_int 0)))]
666   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
667   "cmp{q}\t{%1, %0|%0, %1}"
668   [(set_attr "type" "icmp")
669    (set_attr "mode" "DI")])
670
671 (define_expand "cmpdi_1_rex64"
672   [(set (reg:CC FLAGS_REG)
673         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
674                     (match_operand:DI 1 "general_operand" "")))]
675   "TARGET_64BIT"
676   "")
677
678 (define_insn "cmpdi_1_insn_rex64"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
681                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
682   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
683   "cmp{q}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "DI")])
686
687
688 (define_insn "*cmpsi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
691                  (match_operand:SI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{l}\t%0, %0
695    cmp{l}\t{%1, %0|%0, %1}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "SI")])
699
700 (define_insn "*cmpsi_minus_1"
701   [(set (reg FLAGS_REG)
702         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
703                            (match_operand:SI 1 "general_operand" "ri,mr"))
704                  (const_int 0)))]
705   "ix86_match_ccmode (insn, CCGOCmode)"
706   "cmp{l}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "SI")])
709
710 (define_expand "cmpsi_1"
711   [(set (reg:CC FLAGS_REG)
712         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
713                     (match_operand:SI 1 "general_operand" "")))]
714   ""
715   "")
716
717 (define_insn "*cmpsi_1_insn"
718   [(set (reg FLAGS_REG)
719         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
720                  (match_operand:SI 1 "general_operand" "ri,mr")))]
721   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
722     && ix86_match_ccmode (insn, CCmode)"
723   "cmp{l}\t{%1, %0|%0, %1}"
724   [(set_attr "type" "icmp")
725    (set_attr "mode" "SI")])
726
727 (define_insn "*cmphi_ccno_1"
728   [(set (reg FLAGS_REG)
729         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
730                  (match_operand:HI 1 "const0_operand" "n,n")))]
731   "ix86_match_ccmode (insn, CCNOmode)"
732   "@
733    test{w}\t%0, %0
734    cmp{w}\t{%1, %0|%0, %1}"
735   [(set_attr "type" "test,icmp")
736    (set_attr "length_immediate" "0,1")
737    (set_attr "mode" "HI")])
738
739 (define_insn "*cmphi_minus_1"
740   [(set (reg FLAGS_REG)
741         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
742                            (match_operand:HI 1 "general_operand" "ri,mr"))
743                  (const_int 0)))]
744   "ix86_match_ccmode (insn, CCGOCmode)"
745   "cmp{w}\t{%1, %0|%0, %1}"
746   [(set_attr "type" "icmp")
747    (set_attr "mode" "HI")])
748
749 (define_insn "*cmphi_1"
750   [(set (reg FLAGS_REG)
751         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
752                  (match_operand:HI 1 "general_operand" "ri,mr")))]
753   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
754    && ix86_match_ccmode (insn, CCmode)"
755   "cmp{w}\t{%1, %0|%0, %1}"
756   [(set_attr "type" "icmp")
757    (set_attr "mode" "HI")])
758
759 (define_insn "*cmpqi_ccno_1"
760   [(set (reg FLAGS_REG)
761         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
762                  (match_operand:QI 1 "const0_operand" "n,n")))]
763   "ix86_match_ccmode (insn, CCNOmode)"
764   "@
765    test{b}\t%0, %0
766    cmp{b}\t{$0, %0|%0, 0}"
767   [(set_attr "type" "test,icmp")
768    (set_attr "length_immediate" "0,1")
769    (set_attr "mode" "QI")])
770
771 (define_insn "*cmpqi_1"
772   [(set (reg FLAGS_REG)
773         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
774                  (match_operand:QI 1 "general_operand" "qi,mq")))]
775   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
776     && ix86_match_ccmode (insn, CCmode)"
777   "cmp{b}\t{%1, %0|%0, %1}"
778   [(set_attr "type" "icmp")
779    (set_attr "mode" "QI")])
780
781 (define_insn "*cmpqi_minus_1"
782   [(set (reg FLAGS_REG)
783         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
784                            (match_operand:QI 1 "general_operand" "qi,mq"))
785                  (const_int 0)))]
786   "ix86_match_ccmode (insn, CCGOCmode)"
787   "cmp{b}\t{%1, %0|%0, %1}"
788   [(set_attr "type" "icmp")
789    (set_attr "mode" "QI")])
790
791 (define_insn "*cmpqi_ext_1"
792   [(set (reg FLAGS_REG)
793         (compare
794           (match_operand:QI 0 "general_operand" "Qm")
795           (subreg:QI
796             (zero_extract:SI
797               (match_operand 1 "ext_register_operand" "Q")
798               (const_int 8)
799               (const_int 8)) 0)))]
800   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
801   "cmp{b}\t{%h1, %0|%0, %h1}"
802   [(set_attr "type" "icmp")
803    (set_attr "mode" "QI")])
804
805 (define_insn "*cmpqi_ext_1_rex64"
806   [(set (reg FLAGS_REG)
807         (compare
808           (match_operand:QI 0 "register_operand" "Q")
809           (subreg:QI
810             (zero_extract:SI
811               (match_operand 1 "ext_register_operand" "Q")
812               (const_int 8)
813               (const_int 8)) 0)))]
814   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
815   "cmp{b}\t{%h1, %0|%0, %h1}"
816   [(set_attr "type" "icmp")
817    (set_attr "mode" "QI")])
818
819 (define_insn "*cmpqi_ext_2"
820   [(set (reg FLAGS_REG)
821         (compare
822           (subreg:QI
823             (zero_extract:SI
824               (match_operand 0 "ext_register_operand" "Q")
825               (const_int 8)
826               (const_int 8)) 0)
827           (match_operand:QI 1 "const0_operand" "n")))]
828   "ix86_match_ccmode (insn, CCNOmode)"
829   "test{b}\t%h0, %h0"
830   [(set_attr "type" "test")
831    (set_attr "length_immediate" "0")
832    (set_attr "mode" "QI")])
833
834 (define_expand "cmpqi_ext_3"
835   [(set (reg:CC FLAGS_REG)
836         (compare:CC
837           (subreg:QI
838             (zero_extract:SI
839               (match_operand 0 "ext_register_operand" "")
840               (const_int 8)
841               (const_int 8)) 0)
842           (match_operand:QI 1 "general_operand" "")))]
843   ""
844   "")
845
846 (define_insn "cmpqi_ext_3_insn"
847   [(set (reg FLAGS_REG)
848         (compare
849           (subreg:QI
850             (zero_extract:SI
851               (match_operand 0 "ext_register_operand" "Q")
852               (const_int 8)
853               (const_int 8)) 0)
854           (match_operand:QI 1 "general_operand" "Qmn")))]
855   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
856   "cmp{b}\t{%1, %h0|%h0, %1}"
857   [(set_attr "type" "icmp")
858    (set_attr "mode" "QI")])
859
860 (define_insn "cmpqi_ext_3_insn_rex64"
861   [(set (reg FLAGS_REG)
862         (compare
863           (subreg:QI
864             (zero_extract:SI
865               (match_operand 0 "ext_register_operand" "Q")
866               (const_int 8)
867               (const_int 8)) 0)
868           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
869   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
870   "cmp{b}\t{%1, %h0|%h0, %1}"
871   [(set_attr "type" "icmp")
872    (set_attr "mode" "QI")])
873
874 (define_insn "*cmpqi_ext_4"
875   [(set (reg FLAGS_REG)
876         (compare
877           (subreg:QI
878             (zero_extract:SI
879               (match_operand 0 "ext_register_operand" "Q")
880               (const_int 8)
881               (const_int 8)) 0)
882           (subreg:QI
883             (zero_extract:SI
884               (match_operand 1 "ext_register_operand" "Q")
885               (const_int 8)
886               (const_int 8)) 0)))]
887   "ix86_match_ccmode (insn, CCmode)"
888   "cmp{b}\t{%h1, %h0|%h0, %h1}"
889   [(set_attr "type" "icmp")
890    (set_attr "mode" "QI")])
891
892 ;; These implement float point compares.
893 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
894 ;; which would allow mix and match FP modes on the compares.  Which is what
895 ;; the old patterns did, but with many more of them.
896
897 (define_expand "cmpxf"
898   [(set (reg:CC FLAGS_REG)
899         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
900                     (match_operand:XF 1 "nonmemory_operand" "")))]
901   "TARGET_80387"
902 {
903   ix86_compare_op0 = operands[0];
904   ix86_compare_op1 = operands[1];
905   DONE;
906 })
907
908 (define_expand "cmp<mode>"
909   [(set (reg:CC FLAGS_REG)
910         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
911                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
912   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
913 {
914   ix86_compare_op0 = operands[0];
915   ix86_compare_op1 = operands[1];
916   DONE;
917 })
918
919 ;; FP compares, step 1:
920 ;; Set the FP condition codes.
921 ;;
922 ;; CCFPmode     compare with exceptions
923 ;; CCFPUmode    compare with no exceptions
924
925 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
926 ;; used to manage the reg stack popping would not be preserved.
927
928 (define_insn "*cmpfp_0"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFP
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "const0_operand" "X"))]
934         UNSPEC_FNSTSW))]
935   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
936    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937   "* return output_fp_compare (insn, operands, 0, 0);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set (attr "mode")
941      (cond [(match_operand:SF 1 "" "")
942               (const_string "SF")
943             (match_operand:DF 1 "" "")
944               (const_string "DF")
945            ]
946            (const_string "XF")))])
947
948 (define_insn_and_split "*cmpfp_0_cc"
949   [(set (reg:CCFP FLAGS_REG)
950         (compare:CCFP
951           (match_operand 1 "register_operand" "f")
952           (match_operand 2 "const0_operand" "X")))
953    (clobber (match_operand:HI 0 "register_operand" "=a"))]
954   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
955    && TARGET_SAHF && !TARGET_CMOVE
956    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
957   "#"
958   "&& reload_completed"
959   [(set (match_dup 0)
960         (unspec:HI
961           [(compare:CCFP (match_dup 1)(match_dup 2))]
962         UNSPEC_FNSTSW))
963    (set (reg:CC FLAGS_REG)
964         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
965   ""
966   [(set_attr "type" "multi")
967    (set_attr "unit" "i387")
968    (set (attr "mode")
969      (cond [(match_operand:SF 1 "" "")
970               (const_string "SF")
971             (match_operand:DF 1 "" "")
972               (const_string "DF")
973            ]
974            (const_string "XF")))])
975
976 (define_insn "*cmpfp_xf"
977   [(set (match_operand:HI 0 "register_operand" "=a")
978         (unspec:HI
979           [(compare:CCFP
980              (match_operand:XF 1 "register_operand" "f")
981              (match_operand:XF 2 "register_operand" "f"))]
982           UNSPEC_FNSTSW))]
983   "TARGET_80387"
984   "* return output_fp_compare (insn, operands, 0, 0);"
985   [(set_attr "type" "multi")
986    (set_attr "unit" "i387")
987    (set_attr "mode" "XF")])
988
989 (define_insn_and_split "*cmpfp_xf_cc"
990   [(set (reg:CCFP FLAGS_REG)
991         (compare:CCFP
992           (match_operand:XF 1 "register_operand" "f")
993           (match_operand:XF 2 "register_operand" "f")))
994    (clobber (match_operand:HI 0 "register_operand" "=a"))]
995   "TARGET_80387
996    && TARGET_SAHF && !TARGET_CMOVE"
997   "#"
998   "&& reload_completed"
999   [(set (match_dup 0)
1000         (unspec:HI
1001           [(compare:CCFP (match_dup 1)(match_dup 2))]
1002         UNSPEC_FNSTSW))
1003    (set (reg:CC FLAGS_REG)
1004         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1005   ""
1006   [(set_attr "type" "multi")
1007    (set_attr "unit" "i387")
1008    (set_attr "mode" "XF")])
1009
1010 (define_insn "*cmpfp_<mode>"
1011   [(set (match_operand:HI 0 "register_operand" "=a")
1012         (unspec:HI
1013           [(compare:CCFP
1014              (match_operand:MODEF 1 "register_operand" "f")
1015              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1016           UNSPEC_FNSTSW))]
1017   "TARGET_80387"
1018   "* return output_fp_compare (insn, operands, 0, 0);"
1019   [(set_attr "type" "multi")
1020    (set_attr "unit" "i387")
1021    (set_attr "mode" "<MODE>")])
1022
1023 (define_insn_and_split "*cmpfp_<mode>_cc"
1024   [(set (reg:CCFP FLAGS_REG)
1025         (compare:CCFP
1026           (match_operand:MODEF 1 "register_operand" "f")
1027           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1028    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1029   "TARGET_80387
1030    && TARGET_SAHF && !TARGET_CMOVE"
1031   "#"
1032   "&& reload_completed"
1033   [(set (match_dup 0)
1034         (unspec:HI
1035           [(compare:CCFP (match_dup 1)(match_dup 2))]
1036         UNSPEC_FNSTSW))
1037    (set (reg:CC FLAGS_REG)
1038         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1039   ""
1040   [(set_attr "type" "multi")
1041    (set_attr "unit" "i387")
1042    (set_attr "mode" "<MODE>")])
1043
1044 (define_insn "*cmpfp_u"
1045   [(set (match_operand:HI 0 "register_operand" "=a")
1046         (unspec:HI
1047           [(compare:CCFPU
1048              (match_operand 1 "register_operand" "f")
1049              (match_operand 2 "register_operand" "f"))]
1050           UNSPEC_FNSTSW))]
1051   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1052    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1053   "* return output_fp_compare (insn, operands, 0, 1);"
1054   [(set_attr "type" "multi")
1055    (set_attr "unit" "i387")
1056    (set (attr "mode")
1057      (cond [(match_operand:SF 1 "" "")
1058               (const_string "SF")
1059             (match_operand:DF 1 "" "")
1060               (const_string "DF")
1061            ]
1062            (const_string "XF")))])
1063
1064 (define_insn_and_split "*cmpfp_u_cc"
1065   [(set (reg:CCFPU FLAGS_REG)
1066         (compare:CCFPU
1067           (match_operand 1 "register_operand" "f")
1068           (match_operand 2 "register_operand" "f")))
1069    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1070   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1071    && TARGET_SAHF && !TARGET_CMOVE
1072    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1073   "#"
1074   "&& reload_completed"
1075   [(set (match_dup 0)
1076         (unspec:HI
1077           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1078         UNSPEC_FNSTSW))
1079    (set (reg:CC FLAGS_REG)
1080         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1081   ""
1082   [(set_attr "type" "multi")
1083    (set_attr "unit" "i387")
1084    (set (attr "mode")
1085      (cond [(match_operand:SF 1 "" "")
1086               (const_string "SF")
1087             (match_operand:DF 1 "" "")
1088               (const_string "DF")
1089            ]
1090            (const_string "XF")))])
1091
1092 (define_insn "*cmpfp_<mode>"
1093   [(set (match_operand:HI 0 "register_operand" "=a")
1094         (unspec:HI
1095           [(compare:CCFP
1096              (match_operand 1 "register_operand" "f")
1097              (match_operator 3 "float_operator"
1098                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1099           UNSPEC_FNSTSW))]
1100   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1101    && TARGET_USE_<MODE>MODE_FIOP
1102    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1103   "* return output_fp_compare (insn, operands, 0, 0);"
1104   [(set_attr "type" "multi")
1105    (set_attr "unit" "i387")
1106    (set_attr "fp_int_src" "true")
1107    (set_attr "mode" "<MODE>")])
1108
1109 (define_insn_and_split "*cmpfp_<mode>_cc"
1110   [(set (reg:CCFP FLAGS_REG)
1111         (compare:CCFP
1112           (match_operand 1 "register_operand" "f")
1113           (match_operator 3 "float_operator"
1114             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1115    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1116   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1117    && TARGET_SAHF && !TARGET_CMOVE
1118    && TARGET_USE_<MODE>MODE_FIOP
1119    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1120   "#"
1121   "&& reload_completed"
1122   [(set (match_dup 0)
1123         (unspec:HI
1124           [(compare:CCFP
1125              (match_dup 1)
1126              (match_op_dup 3 [(match_dup 2)]))]
1127         UNSPEC_FNSTSW))
1128    (set (reg:CC FLAGS_REG)
1129         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1130   ""
1131   [(set_attr "type" "multi")
1132    (set_attr "unit" "i387")
1133    (set_attr "fp_int_src" "true")
1134    (set_attr "mode" "<MODE>")])
1135
1136 ;; FP compares, step 2
1137 ;; Move the fpsw to ax.
1138
1139 (define_insn "x86_fnstsw_1"
1140   [(set (match_operand:HI 0 "register_operand" "=a")
1141         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1142   "TARGET_80387"
1143   "fnstsw\t%0"
1144   [(set_attr "length" "2")
1145    (set_attr "mode" "SI")
1146    (set_attr "unit" "i387")])
1147
1148 ;; FP compares, step 3
1149 ;; Get ax into flags, general case.
1150
1151 (define_insn "x86_sahf_1"
1152   [(set (reg:CC FLAGS_REG)
1153         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1154                    UNSPEC_SAHF))]
1155   "TARGET_SAHF"
1156 {
1157 #ifdef HAVE_AS_IX86_SAHF
1158   return "sahf";
1159 #else
1160   return ".byte\t0x9e";
1161 #endif
1162 }
1163   [(set_attr "length" "1")
1164    (set_attr "athlon_decode" "vector")
1165    (set_attr "amdfam10_decode" "direct")
1166    (set_attr "mode" "SI")])
1167
1168 ;; Pentium Pro can do steps 1 through 3 in one go.
1169 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
1170 (define_insn "*cmpfp_i_mixed"
1171   [(set (reg:CCFP FLAGS_REG)
1172         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1173                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1174   "TARGET_MIX_SSE_I387
1175    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1176    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1177   "* return output_fp_compare (insn, operands, 1, 0);"
1178   [(set_attr "type" "fcmp,ssecomi")
1179    (set (attr "mode")
1180      (if_then_else (match_operand:SF 1 "" "")
1181         (const_string "SF")
1182         (const_string "DF")))
1183    (set_attr "athlon_decode" "vector")
1184    (set_attr "amdfam10_decode" "direct")])
1185
1186 (define_insn "*cmpfp_i_sse"
1187   [(set (reg:CCFP FLAGS_REG)
1188         (compare:CCFP (match_operand 0 "register_operand" "x")
1189                       (match_operand 1 "nonimmediate_operand" "xm")))]
1190   "TARGET_SSE_MATH
1191    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1192    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1193   "* return output_fp_compare (insn, operands, 1, 0);"
1194   [(set_attr "type" "ssecomi")
1195    (set (attr "mode")
1196      (if_then_else (match_operand:SF 1 "" "")
1197         (const_string "SF")
1198         (const_string "DF")))
1199    (set_attr "athlon_decode" "vector")
1200    (set_attr "amdfam10_decode" "direct")])
1201
1202 (define_insn "*cmpfp_i_i387"
1203   [(set (reg:CCFP FLAGS_REG)
1204         (compare:CCFP (match_operand 0 "register_operand" "f")
1205                       (match_operand 1 "register_operand" "f")))]
1206   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1207    && TARGET_CMOVE
1208    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1209    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1210   "* return output_fp_compare (insn, operands, 1, 0);"
1211   [(set_attr "type" "fcmp")
1212    (set (attr "mode")
1213      (cond [(match_operand:SF 1 "" "")
1214               (const_string "SF")
1215             (match_operand:DF 1 "" "")
1216               (const_string "DF")
1217            ]
1218            (const_string "XF")))
1219    (set_attr "athlon_decode" "vector")
1220    (set_attr "amdfam10_decode" "direct")])
1221
1222 (define_insn "*cmpfp_iu_mixed"
1223   [(set (reg:CCFPU FLAGS_REG)
1224         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1225                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1226   "TARGET_MIX_SSE_I387
1227    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1228    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1229   "* return output_fp_compare (insn, operands, 1, 1);"
1230   [(set_attr "type" "fcmp,ssecomi")
1231    (set (attr "mode")
1232      (if_then_else (match_operand:SF 1 "" "")
1233         (const_string "SF")
1234         (const_string "DF")))
1235    (set_attr "athlon_decode" "vector")
1236    (set_attr "amdfam10_decode" "direct")])
1237
1238 (define_insn "*cmpfp_iu_sse"
1239   [(set (reg:CCFPU FLAGS_REG)
1240         (compare:CCFPU (match_operand 0 "register_operand" "x")
1241                        (match_operand 1 "nonimmediate_operand" "xm")))]
1242   "TARGET_SSE_MATH
1243    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1244    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1245   "* return output_fp_compare (insn, operands, 1, 1);"
1246   [(set_attr "type" "ssecomi")
1247    (set (attr "mode")
1248      (if_then_else (match_operand:SF 1 "" "")
1249         (const_string "SF")
1250         (const_string "DF")))
1251    (set_attr "athlon_decode" "vector")
1252    (set_attr "amdfam10_decode" "direct")])
1253
1254 (define_insn "*cmpfp_iu_387"
1255   [(set (reg:CCFPU FLAGS_REG)
1256         (compare:CCFPU (match_operand 0 "register_operand" "f")
1257                        (match_operand 1 "register_operand" "f")))]
1258   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1259    && TARGET_CMOVE
1260    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1261    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1262   "* return output_fp_compare (insn, operands, 1, 1);"
1263   [(set_attr "type" "fcmp")
1264    (set (attr "mode")
1265      (cond [(match_operand:SF 1 "" "")
1266               (const_string "SF")
1267             (match_operand:DF 1 "" "")
1268               (const_string "DF")
1269            ]
1270            (const_string "XF")))
1271    (set_attr "athlon_decode" "vector")
1272    (set_attr "amdfam10_decode" "direct")])
1273 \f
1274 ;; Move instructions.
1275
1276 ;; General case of fullword move.
1277
1278 (define_expand "movsi"
1279   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1280         (match_operand:SI 1 "general_operand" ""))]
1281   ""
1282   "ix86_expand_move (SImode, operands); DONE;")
1283
1284 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1285 ;; general_operand.
1286 ;;
1287 ;; %%% We don't use a post-inc memory reference because x86 is not a
1288 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1289 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1290 ;; targets without our curiosities, and it is just as easy to represent
1291 ;; this differently.
1292
1293 (define_insn "*pushsi2"
1294   [(set (match_operand:SI 0 "push_operand" "=<")
1295         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1296   "!TARGET_64BIT"
1297   "push{l}\t%1"
1298   [(set_attr "type" "push")
1299    (set_attr "mode" "SI")])
1300
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushsi2_rex64"
1303   [(set (match_operand:SI 0 "push_operand" "=X")
1304         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1305   "TARGET_64BIT"
1306   "push{q}\t%q1"
1307   [(set_attr "type" "push")
1308    (set_attr "mode" "SI")])
1309
1310 (define_insn "*pushsi2_prologue"
1311   [(set (match_operand:SI 0 "push_operand" "=<")
1312         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1313    (clobber (mem:BLK (scratch)))]
1314   "!TARGET_64BIT"
1315   "push{l}\t%1"
1316   [(set_attr "type" "push")
1317    (set_attr "mode" "SI")])
1318
1319 (define_insn "*popsi1_epilogue"
1320   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1321         (mem:SI (reg:SI SP_REG)))
1322    (set (reg:SI SP_REG)
1323         (plus:SI (reg:SI SP_REG) (const_int 4)))
1324    (clobber (mem:BLK (scratch)))]
1325   "!TARGET_64BIT"
1326   "pop{l}\t%0"
1327   [(set_attr "type" "pop")
1328    (set_attr "mode" "SI")])
1329
1330 (define_insn "popsi1"
1331   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1332         (mem:SI (reg:SI SP_REG)))
1333    (set (reg:SI SP_REG)
1334         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1335   "!TARGET_64BIT"
1336   "pop{l}\t%0"
1337   [(set_attr "type" "pop")
1338    (set_attr "mode" "SI")])
1339
1340 (define_insn "*movsi_xor"
1341   [(set (match_operand:SI 0 "register_operand" "=r")
1342         (match_operand:SI 1 "const0_operand" "i"))
1343    (clobber (reg:CC FLAGS_REG))]
1344   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1345   "xor{l}\t%0, %0"
1346   [(set_attr "type" "alu1")
1347    (set_attr "mode" "SI")
1348    (set_attr "length_immediate" "0")])
1349
1350 (define_insn "*movsi_or"
1351   [(set (match_operand:SI 0 "register_operand" "=r")
1352         (match_operand:SI 1 "immediate_operand" "i"))
1353    (clobber (reg:CC FLAGS_REG))]
1354   "reload_completed
1355    && operands[1] == constm1_rtx
1356    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1357 {
1358   operands[1] = constm1_rtx;
1359   return "or{l}\t{%1, %0|%0, %1}";
1360 }
1361   [(set_attr "type" "alu1")
1362    (set_attr "mode" "SI")
1363    (set_attr "length_immediate" "1")])
1364
1365 (define_insn "*movsi_1"
1366   [(set (match_operand:SI 0 "nonimmediate_operand"
1367                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1368         (match_operand:SI 1 "general_operand"
1369                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1370   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1371 {
1372   switch (get_attr_type (insn))
1373     {
1374     case TYPE_SSELOG1:
1375       if (get_attr_mode (insn) == MODE_TI)
1376         return "pxor\t%0, %0";
1377       return "xorps\t%0, %0";
1378
1379     case TYPE_SSEMOV:
1380       switch (get_attr_mode (insn))
1381         {
1382         case MODE_TI:
1383           return "movdqa\t{%1, %0|%0, %1}";
1384         case MODE_V4SF:
1385           return "movaps\t{%1, %0|%0, %1}";
1386         case MODE_SI:
1387           return "movd\t{%1, %0|%0, %1}";
1388         case MODE_SF:
1389           return "movss\t{%1, %0|%0, %1}";
1390         default:
1391           gcc_unreachable ();
1392         }
1393
1394     case TYPE_MMXADD:
1395       return "pxor\t%0, %0";
1396
1397     case TYPE_MMXMOV:
1398       if (get_attr_mode (insn) == MODE_DI)
1399         return "movq\t{%1, %0|%0, %1}";
1400       return "movd\t{%1, %0|%0, %1}";
1401
1402     case TYPE_LEA:
1403       return "lea{l}\t{%1, %0|%0, %1}";
1404
1405     default:
1406       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1407       return "mov{l}\t{%1, %0|%0, %1}";
1408     }
1409 }
1410   [(set (attr "type")
1411      (cond [(eq_attr "alternative" "2")
1412               (const_string "mmxadd")
1413             (eq_attr "alternative" "3,4,5")
1414               (const_string "mmxmov")
1415             (eq_attr "alternative" "6")
1416               (const_string "sselog1")
1417             (eq_attr "alternative" "7,8,9,10,11")
1418               (const_string "ssemov")
1419             (match_operand:DI 1 "pic_32bit_operand" "")
1420               (const_string "lea")
1421            ]
1422            (const_string "imov")))
1423    (set (attr "mode")
1424      (cond [(eq_attr "alternative" "2,3")
1425               (const_string "DI")
1426             (eq_attr "alternative" "6,7")
1427               (if_then_else
1428                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1429                 (const_string "V4SF")
1430                 (const_string "TI"))
1431             (and (eq_attr "alternative" "8,9,10,11")
1432                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1433               (const_string "SF")
1434            ]
1435            (const_string "SI")))])
1436
1437 ;; Stores and loads of ax to arbitrary constant address.
1438 ;; We fake an second form of instruction to force reload to load address
1439 ;; into register when rax is not available
1440 (define_insn "*movabssi_1_rex64"
1441   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1442         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1443   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1444   "@
1445    movabs{l}\t{%1, %P0|%P0, %1}
1446    mov{l}\t{%1, %a0|%a0, %1}"
1447   [(set_attr "type" "imov")
1448    (set_attr "modrm" "0,*")
1449    (set_attr "length_address" "8,0")
1450    (set_attr "length_immediate" "0,*")
1451    (set_attr "memory" "store")
1452    (set_attr "mode" "SI")])
1453
1454 (define_insn "*movabssi_2_rex64"
1455   [(set (match_operand:SI 0 "register_operand" "=a,r")
1456         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1457   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1458   "@
1459    movabs{l}\t{%P1, %0|%0, %P1}
1460    mov{l}\t{%a1, %0|%0, %a1}"
1461   [(set_attr "type" "imov")
1462    (set_attr "modrm" "0,*")
1463    (set_attr "length_address" "8,0")
1464    (set_attr "length_immediate" "0")
1465    (set_attr "memory" "load")
1466    (set_attr "mode" "SI")])
1467
1468 (define_insn "*swapsi"
1469   [(set (match_operand:SI 0 "register_operand" "+r")
1470         (match_operand:SI 1 "register_operand" "+r"))
1471    (set (match_dup 1)
1472         (match_dup 0))]
1473   ""
1474   "xchg{l}\t%1, %0"
1475   [(set_attr "type" "imov")
1476    (set_attr "mode" "SI")
1477    (set_attr "pent_pair" "np")
1478    (set_attr "athlon_decode" "vector")
1479    (set_attr "amdfam10_decode" "double")])   
1480
1481 (define_expand "movhi"
1482   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1483         (match_operand:HI 1 "general_operand" ""))]
1484   ""
1485   "ix86_expand_move (HImode, operands); DONE;")
1486
1487 (define_insn "*pushhi2"
1488   [(set (match_operand:HI 0 "push_operand" "=X")
1489         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1490   "!TARGET_64BIT"
1491   "push{l}\t%k1"
1492   [(set_attr "type" "push")
1493    (set_attr "mode" "SI")])
1494
1495 ;; For 64BIT abi we always round up to 8 bytes.
1496 (define_insn "*pushhi2_rex64"
1497   [(set (match_operand:HI 0 "push_operand" "=X")
1498         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1499   "TARGET_64BIT"
1500   "push{q}\t%q1"
1501   [(set_attr "type" "push")
1502    (set_attr "mode" "DI")])
1503
1504 (define_insn "*movhi_1"
1505   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1506         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1507   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1508 {
1509   switch (get_attr_type (insn))
1510     {
1511     case TYPE_IMOVX:
1512       /* movzwl is faster than movw on p2 due to partial word stalls,
1513          though not as fast as an aligned movl.  */
1514       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1515     default:
1516       if (get_attr_mode (insn) == MODE_SI)
1517         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1518       else
1519         return "mov{w}\t{%1, %0|%0, %1}";
1520     }
1521 }
1522   [(set (attr "type")
1523      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "0")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (and (eq_attr "alternative" "1,2")
1532                  (match_operand:HI 1 "aligned_operand" ""))
1533               (const_string "imov")
1534             (and (ne (symbol_ref "TARGET_MOVX")
1535                      (const_int 0))
1536                  (eq_attr "alternative" "0,2"))
1537               (const_string "imovx")
1538            ]
1539            (const_string "imov")))
1540     (set (attr "mode")
1541       (cond [(eq_attr "type" "imovx")
1542                (const_string "SI")
1543              (and (eq_attr "alternative" "1,2")
1544                   (match_operand:HI 1 "aligned_operand" ""))
1545                (const_string "SI")
1546              (and (eq_attr "alternative" "0")
1547                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1548                            (const_int 0))
1549                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1550                            (const_int 0))))
1551                (const_string "SI")
1552             ]
1553             (const_string "HI")))])
1554
1555 ;; Stores and loads of ax to arbitrary constant address.
1556 ;; We fake an second form of instruction to force reload to load address
1557 ;; into register when rax is not available
1558 (define_insn "*movabshi_1_rex64"
1559   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1560         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1561   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1562   "@
1563    movabs{w}\t{%1, %P0|%P0, %1}
1564    mov{w}\t{%1, %a0|%a0, %1}"
1565   [(set_attr "type" "imov")
1566    (set_attr "modrm" "0,*")
1567    (set_attr "length_address" "8,0")
1568    (set_attr "length_immediate" "0,*")
1569    (set_attr "memory" "store")
1570    (set_attr "mode" "HI")])
1571
1572 (define_insn "*movabshi_2_rex64"
1573   [(set (match_operand:HI 0 "register_operand" "=a,r")
1574         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1575   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1576   "@
1577    movabs{w}\t{%P1, %0|%0, %P1}
1578    mov{w}\t{%a1, %0|%0, %a1}"
1579   [(set_attr "type" "imov")
1580    (set_attr "modrm" "0,*")
1581    (set_attr "length_address" "8,0")
1582    (set_attr "length_immediate" "0")
1583    (set_attr "memory" "load")
1584    (set_attr "mode" "HI")])
1585
1586 (define_insn "*swaphi_1"
1587   [(set (match_operand:HI 0 "register_operand" "+r")
1588         (match_operand:HI 1 "register_operand" "+r"))
1589    (set (match_dup 1)
1590         (match_dup 0))]
1591   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1592   "xchg{l}\t%k1, %k0"
1593   [(set_attr "type" "imov")
1594    (set_attr "mode" "SI")
1595    (set_attr "pent_pair" "np")
1596    (set_attr "athlon_decode" "vector")
1597    (set_attr "amdfam10_decode" "double")])   
1598
1599 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1600 (define_insn "*swaphi_2"
1601   [(set (match_operand:HI 0 "register_operand" "+r")
1602         (match_operand:HI 1 "register_operand" "+r"))
1603    (set (match_dup 1)
1604         (match_dup 0))]
1605   "TARGET_PARTIAL_REG_STALL"
1606   "xchg{w}\t%1, %0"
1607   [(set_attr "type" "imov")
1608    (set_attr "mode" "HI")
1609    (set_attr "pent_pair" "np")
1610    (set_attr "athlon_decode" "vector")])
1611
1612 (define_expand "movstricthi"
1613   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1614         (match_operand:HI 1 "general_operand" ""))]
1615   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1616 {
1617   /* Don't generate memory->memory moves, go through a register */
1618   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1619     operands[1] = force_reg (HImode, operands[1]);
1620 })
1621
1622 (define_insn "*movstricthi_1"
1623   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1624         (match_operand:HI 1 "general_operand" "rn,m"))]
1625   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1626    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627   "mov{w}\t{%1, %0|%0, %1}"
1628   [(set_attr "type" "imov")
1629    (set_attr "mode" "HI")])
1630
1631 (define_insn "*movstricthi_xor"
1632   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1633         (match_operand:HI 1 "const0_operand" "i"))
1634    (clobber (reg:CC FLAGS_REG))]
1635   "reload_completed
1636    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1637   "xor{w}\t%0, %0"
1638   [(set_attr "type" "alu1")
1639    (set_attr "mode" "HI")
1640    (set_attr "length_immediate" "0")])
1641
1642 (define_expand "movqi"
1643   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1644         (match_operand:QI 1 "general_operand" ""))]
1645   ""
1646   "ix86_expand_move (QImode, operands); DONE;")
1647
1648 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1649 ;; "push a byte".  But actually we use pushl, which has the effect
1650 ;; of rounding the amount pushed up to a word.
1651
1652 (define_insn "*pushqi2"
1653   [(set (match_operand:QI 0 "push_operand" "=X")
1654         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1655   "!TARGET_64BIT"
1656   "push{l}\t%k1"
1657   [(set_attr "type" "push")
1658    (set_attr "mode" "SI")])
1659
1660 ;; For 64BIT abi we always round up to 8 bytes.
1661 (define_insn "*pushqi2_rex64"
1662   [(set (match_operand:QI 0 "push_operand" "=X")
1663         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1664   "TARGET_64BIT"
1665   "push{q}\t%q1"
1666   [(set_attr "type" "push")
1667    (set_attr "mode" "DI")])
1668
1669 ;; Situation is quite tricky about when to choose full sized (SImode) move
1670 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1671 ;; partial register dependency machines (such as AMD Athlon), where QImode
1672 ;; moves issue extra dependency and for partial register stalls machines
1673 ;; that don't use QImode patterns (and QImode move cause stall on the next
1674 ;; instruction).
1675 ;;
1676 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1677 ;; register stall machines with, where we use QImode instructions, since
1678 ;; partial register stall can be caused there.  Then we use movzx.
1679 (define_insn "*movqi_1"
1680   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1681         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1683 {
1684   switch (get_attr_type (insn))
1685     {
1686     case TYPE_IMOVX:
1687       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1688       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1689     default:
1690       if (get_attr_mode (insn) == MODE_SI)
1691         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1692       else
1693         return "mov{b}\t{%1, %0|%0, %1}";
1694     }
1695 }
1696   [(set (attr "type")
1697      (cond [(and (eq_attr "alternative" "5")
1698                  (not (match_operand:QI 1 "aligned_operand" "")))
1699               (const_string "imovx")
1700             (ne (symbol_ref "optimize_size") (const_int 0))
1701               (const_string "imov")
1702             (and (eq_attr "alternative" "3")
1703                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1704                           (const_int 0))
1705                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1706                           (const_int 0))))
1707               (const_string "imov")
1708             (eq_attr "alternative" "3,5")
1709               (const_string "imovx")
1710             (and (ne (symbol_ref "TARGET_MOVX")
1711                      (const_int 0))
1712                  (eq_attr "alternative" "2"))
1713               (const_string "imovx")
1714            ]
1715            (const_string "imov")))
1716    (set (attr "mode")
1717       (cond [(eq_attr "alternative" "3,4,5")
1718                (const_string "SI")
1719              (eq_attr "alternative" "6")
1720                (const_string "QI")
1721              (eq_attr "type" "imovx")
1722                (const_string "SI")
1723              (and (eq_attr "type" "imov")
1724                   (and (eq_attr "alternative" "0,1")
1725                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1726                                 (const_int 0))
1727                             (and (eq (symbol_ref "optimize_size")
1728                                      (const_int 0))
1729                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1730                                      (const_int 0))))))
1731                (const_string "SI")
1732              ;; Avoid partial register stalls when not using QImode arithmetic
1733              (and (eq_attr "type" "imov")
1734                   (and (eq_attr "alternative" "0,1")
1735                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1736                                 (const_int 0))
1737                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1738                                 (const_int 0)))))
1739                (const_string "SI")
1740            ]
1741            (const_string "QI")))])
1742
1743 (define_expand "reload_outqi"
1744   [(parallel [(match_operand:QI 0 "" "=m")
1745               (match_operand:QI 1 "register_operand" "r")
1746               (match_operand:QI 2 "register_operand" "=&q")])]
1747   ""
1748 {
1749   rtx op0, op1, op2;
1750   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1751
1752   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1753   if (! q_regs_operand (op1, QImode))
1754     {
1755       emit_insn (gen_movqi (op2, op1));
1756       op1 = op2;
1757     }
1758   emit_insn (gen_movqi (op0, op1));
1759   DONE;
1760 })
1761
1762 (define_insn "*swapqi_1"
1763   [(set (match_operand:QI 0 "register_operand" "+r")
1764         (match_operand:QI 1 "register_operand" "+r"))
1765    (set (match_dup 1)
1766         (match_dup 0))]
1767   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1768   "xchg{l}\t%k1, %k0"
1769   [(set_attr "type" "imov")
1770    (set_attr "mode" "SI")
1771    (set_attr "pent_pair" "np")
1772    (set_attr "athlon_decode" "vector")
1773    (set_attr "amdfam10_decode" "vector")])   
1774
1775 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1776 (define_insn "*swapqi_2"
1777   [(set (match_operand:QI 0 "register_operand" "+q")
1778         (match_operand:QI 1 "register_operand" "+q"))
1779    (set (match_dup 1)
1780         (match_dup 0))]
1781   "TARGET_PARTIAL_REG_STALL"
1782   "xchg{b}\t%1, %0"
1783   [(set_attr "type" "imov")
1784    (set_attr "mode" "QI")
1785    (set_attr "pent_pair" "np")
1786    (set_attr "athlon_decode" "vector")])
1787
1788 (define_expand "movstrictqi"
1789   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1790         (match_operand:QI 1 "general_operand" ""))]
1791   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1792 {
1793   /* Don't generate memory->memory moves, go through a register.  */
1794   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1795     operands[1] = force_reg (QImode, operands[1]);
1796 })
1797
1798 (define_insn "*movstrictqi_1"
1799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1800         (match_operand:QI 1 "general_operand" "*qn,m"))]
1801   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1802    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803   "mov{b}\t{%1, %0|%0, %1}"
1804   [(set_attr "type" "imov")
1805    (set_attr "mode" "QI")])
1806
1807 (define_insn "*movstrictqi_xor"
1808   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1809         (match_operand:QI 1 "const0_operand" "i"))
1810    (clobber (reg:CC FLAGS_REG))]
1811   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1812   "xor{b}\t%0, %0"
1813   [(set_attr "type" "alu1")
1814    (set_attr "mode" "QI")
1815    (set_attr "length_immediate" "0")])
1816
1817 (define_insn "*movsi_extv_1"
1818   [(set (match_operand:SI 0 "register_operand" "=R")
1819         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1820                          (const_int 8)
1821                          (const_int 8)))]
1822   ""
1823   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1824   [(set_attr "type" "imovx")
1825    (set_attr "mode" "SI")])
1826
1827 (define_insn "*movhi_extv_1"
1828   [(set (match_operand:HI 0 "register_operand" "=R")
1829         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1830                          (const_int 8)
1831                          (const_int 8)))]
1832   ""
1833   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1834   [(set_attr "type" "imovx")
1835    (set_attr "mode" "SI")])
1836
1837 (define_insn "*movqi_extv_1"
1838   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1839         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1840                          (const_int 8)
1841                          (const_int 8)))]
1842   "!TARGET_64BIT"
1843 {
1844   switch (get_attr_type (insn))
1845     {
1846     case TYPE_IMOVX:
1847       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1848     default:
1849       return "mov{b}\t{%h1, %0|%0, %h1}";
1850     }
1851 }
1852   [(set (attr "type")
1853      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1854                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1855                              (ne (symbol_ref "TARGET_MOVX")
1856                                  (const_int 0))))
1857         (const_string "imovx")
1858         (const_string "imov")))
1859    (set (attr "mode")
1860      (if_then_else (eq_attr "type" "imovx")
1861         (const_string "SI")
1862         (const_string "QI")))])
1863
1864 (define_insn "*movqi_extv_1_rex64"
1865   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1866         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1867                          (const_int 8)
1868                          (const_int 8)))]
1869   "TARGET_64BIT"
1870 {
1871   switch (get_attr_type (insn))
1872     {
1873     case TYPE_IMOVX:
1874       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1875     default:
1876       return "mov{b}\t{%h1, %0|%0, %h1}";
1877     }
1878 }
1879   [(set (attr "type")
1880      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1881                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1882                              (ne (symbol_ref "TARGET_MOVX")
1883                                  (const_int 0))))
1884         (const_string "imovx")
1885         (const_string "imov")))
1886    (set (attr "mode")
1887      (if_then_else (eq_attr "type" "imovx")
1888         (const_string "SI")
1889         (const_string "QI")))])
1890
1891 ;; Stores and loads of ax to arbitrary constant address.
1892 ;; We fake an second form of instruction to force reload to load address
1893 ;; into register when rax is not available
1894 (define_insn "*movabsqi_1_rex64"
1895   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1896         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1897   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1898   "@
1899    movabs{b}\t{%1, %P0|%P0, %1}
1900    mov{b}\t{%1, %a0|%a0, %1}"
1901   [(set_attr "type" "imov")
1902    (set_attr "modrm" "0,*")
1903    (set_attr "length_address" "8,0")
1904    (set_attr "length_immediate" "0,*")
1905    (set_attr "memory" "store")
1906    (set_attr "mode" "QI")])
1907
1908 (define_insn "*movabsqi_2_rex64"
1909   [(set (match_operand:QI 0 "register_operand" "=a,r")
1910         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1911   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1912   "@
1913    movabs{b}\t{%P1, %0|%0, %P1}
1914    mov{b}\t{%a1, %0|%0, %a1}"
1915   [(set_attr "type" "imov")
1916    (set_attr "modrm" "0,*")
1917    (set_attr "length_address" "8,0")
1918    (set_attr "length_immediate" "0")
1919    (set_attr "memory" "load")
1920    (set_attr "mode" "QI")])
1921
1922 (define_insn "*movdi_extzv_1"
1923   [(set (match_operand:DI 0 "register_operand" "=R")
1924         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1925                          (const_int 8)
1926                          (const_int 8)))]
1927   "TARGET_64BIT"
1928   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1929   [(set_attr "type" "imovx")
1930    (set_attr "mode" "DI")])
1931
1932 (define_insn "*movsi_extzv_1"
1933   [(set (match_operand:SI 0 "register_operand" "=R")
1934         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1935                          (const_int 8)
1936                          (const_int 8)))]
1937   ""
1938   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1939   [(set_attr "type" "imovx")
1940    (set_attr "mode" "SI")])
1941
1942 (define_insn "*movqi_extzv_2"
1943   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1944         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1945                                     (const_int 8)
1946                                     (const_int 8)) 0))]
1947   "!TARGET_64BIT"
1948 {
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_IMOVX:
1952       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1953     default:
1954       return "mov{b}\t{%h1, %0|%0, %h1}";
1955     }
1956 }
1957   [(set (attr "type")
1958      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1959                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1960                              (ne (symbol_ref "TARGET_MOVX")
1961                                  (const_int 0))))
1962         (const_string "imovx")
1963         (const_string "imov")))
1964    (set (attr "mode")
1965      (if_then_else (eq_attr "type" "imovx")
1966         (const_string "SI")
1967         (const_string "QI")))])
1968
1969 (define_insn "*movqi_extzv_2_rex64"
1970   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1971         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1972                                     (const_int 8)
1973                                     (const_int 8)) 0))]
1974   "TARGET_64BIT"
1975 {
1976   switch (get_attr_type (insn))
1977     {
1978     case TYPE_IMOVX:
1979       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1980     default:
1981       return "mov{b}\t{%h1, %0|%0, %h1}";
1982     }
1983 }
1984   [(set (attr "type")
1985      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986                         (ne (symbol_ref "TARGET_MOVX")
1987                             (const_int 0)))
1988         (const_string "imovx")
1989         (const_string "imov")))
1990    (set (attr "mode")
1991      (if_then_else (eq_attr "type" "imovx")
1992         (const_string "SI")
1993         (const_string "QI")))])
1994
1995 (define_insn "movsi_insv_1"
1996   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1997                          (const_int 8)
1998                          (const_int 8))
1999         (match_operand:SI 1 "general_operand" "Qmn"))]
2000   "!TARGET_64BIT"
2001   "mov{b}\t{%b1, %h0|%h0, %b1}"
2002   [(set_attr "type" "imov")
2003    (set_attr "mode" "QI")])
2004
2005 (define_insn "*movsi_insv_1_rex64"
2006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2007                          (const_int 8)
2008                          (const_int 8))
2009         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2010   "TARGET_64BIT"
2011   "mov{b}\t{%b1, %h0|%h0, %b1}"
2012   [(set_attr "type" "imov")
2013    (set_attr "mode" "QI")])
2014
2015 (define_insn "movdi_insv_1_rex64"
2016   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2017                          (const_int 8)
2018                          (const_int 8))
2019         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2020   "TARGET_64BIT"
2021   "mov{b}\t{%b1, %h0|%h0, %b1}"
2022   [(set_attr "type" "imov")
2023    (set_attr "mode" "QI")])
2024
2025 (define_insn "*movqi_insv_2"
2026   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2027                          (const_int 8)
2028                          (const_int 8))
2029         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2030                      (const_int 8)))]
2031   ""
2032   "mov{b}\t{%h1, %h0|%h0, %h1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "mode" "QI")])
2035
2036 (define_expand "movdi"
2037   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2038         (match_operand:DI 1 "general_operand" ""))]
2039   ""
2040   "ix86_expand_move (DImode, operands); DONE;")
2041
2042 (define_insn "*pushdi"
2043   [(set (match_operand:DI 0 "push_operand" "=<")
2044         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2045   "!TARGET_64BIT"
2046   "#")
2047
2048 (define_insn "*pushdi2_rex64"
2049   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2050         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2051   "TARGET_64BIT"
2052   "@
2053    push{q}\t%1
2054    #"
2055   [(set_attr "type" "push,multi")
2056    (set_attr "mode" "DI")])
2057
2058 ;; Convert impossible pushes of immediate to existing instructions.
2059 ;; First try to get scratch register and go through it.  In case this
2060 ;; fails, push sign extended lower part first and then overwrite
2061 ;; upper part by 32bit move.
2062 (define_peephole2
2063   [(match_scratch:DI 2 "r")
2064    (set (match_operand:DI 0 "push_operand" "")
2065         (match_operand:DI 1 "immediate_operand" ""))]
2066   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2067    && !x86_64_immediate_operand (operands[1], DImode)"
2068   [(set (match_dup 2) (match_dup 1))
2069    (set (match_dup 0) (match_dup 2))]
2070   "")
2071
2072 ;; We need to define this as both peepholer and splitter for case
2073 ;; peephole2 pass is not run.
2074 ;; "&& 1" is needed to keep it from matching the previous pattern.
2075 (define_peephole2
2076   [(set (match_operand:DI 0 "push_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2080   [(set (match_dup 0) (match_dup 1))
2081    (set (match_dup 2) (match_dup 3))]
2082   "split_di (operands + 1, 1, operands + 2, operands + 3);
2083    operands[1] = gen_lowpart (DImode, operands[2]);
2084    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2085                                                     GEN_INT (4)));
2086   ")
2087
2088 (define_split
2089   [(set (match_operand:DI 0 "push_operand" "")
2090         (match_operand:DI 1 "immediate_operand" ""))]
2091   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2092                     ? epilogue_completed : reload_completed)
2093    && !symbolic_operand (operands[1], DImode)
2094    && !x86_64_immediate_operand (operands[1], DImode)"
2095   [(set (match_dup 0) (match_dup 1))
2096    (set (match_dup 2) (match_dup 3))]
2097   "split_di (operands + 1, 1, operands + 2, operands + 3);
2098    operands[1] = gen_lowpart (DImode, operands[2]);
2099    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2100                                                     GEN_INT (4)));
2101   ")
2102
2103 (define_insn "*pushdi2_prologue_rex64"
2104   [(set (match_operand:DI 0 "push_operand" "=<")
2105         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2106    (clobber (mem:BLK (scratch)))]
2107   "TARGET_64BIT"
2108   "push{q}\t%1"
2109   [(set_attr "type" "push")
2110    (set_attr "mode" "DI")])
2111
2112 (define_insn "*popdi1_epilogue_rex64"
2113   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2114         (mem:DI (reg:DI SP_REG)))
2115    (set (reg:DI SP_REG)
2116         (plus:DI (reg:DI SP_REG) (const_int 8)))
2117    (clobber (mem:BLK (scratch)))]
2118   "TARGET_64BIT"
2119   "pop{q}\t%0"
2120   [(set_attr "type" "pop")
2121    (set_attr "mode" "DI")])
2122
2123 (define_insn "popdi1"
2124   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2125         (mem:DI (reg:DI SP_REG)))
2126    (set (reg:DI SP_REG)
2127         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2128   "TARGET_64BIT"
2129   "pop{q}\t%0"
2130   [(set_attr "type" "pop")
2131    (set_attr "mode" "DI")])
2132
2133 (define_insn "*movdi_xor_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "=r")
2135         (match_operand:DI 1 "const0_operand" "i"))
2136    (clobber (reg:CC FLAGS_REG))]
2137   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2138    && reload_completed"
2139   "xor{l}\t%k0, %k0";
2140   [(set_attr "type" "alu1")
2141    (set_attr "mode" "SI")
2142    (set_attr "length_immediate" "0")])
2143
2144 (define_insn "*movdi_or_rex64"
2145   [(set (match_operand:DI 0 "register_operand" "=r")
2146         (match_operand:DI 1 "const_int_operand" "i"))
2147    (clobber (reg:CC FLAGS_REG))]
2148   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2149    && reload_completed
2150    && operands[1] == constm1_rtx"
2151 {
2152   operands[1] = constm1_rtx;
2153   return "or{q}\t{%1, %0|%0, %1}";
2154 }
2155   [(set_attr "type" "alu1")
2156    (set_attr "mode" "DI")
2157    (set_attr "length_immediate" "1")])
2158
2159 (define_insn "*movdi_2"
2160   [(set (match_operand:DI 0 "nonimmediate_operand"
2161                         "=r  ,o  ,*y,m*y,*y,*Yt,m  ,*Yt,*Yt,*x,m ,*x,*x")
2162         (match_operand:DI 1 "general_operand"
2163                         "riFo,riF,C ,*y ,m ,C  ,*Yt,*Yt,m  ,C ,*x,*x,m "))]
2164   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2165   "@
2166    #
2167    #
2168    pxor\t%0, %0
2169    movq\t{%1, %0|%0, %1}
2170    movq\t{%1, %0|%0, %1}
2171    pxor\t%0, %0
2172    movq\t{%1, %0|%0, %1}
2173    movdqa\t{%1, %0|%0, %1}
2174    movq\t{%1, %0|%0, %1}
2175    xorps\t%0, %0
2176    movlps\t{%1, %0|%0, %1}
2177    movaps\t{%1, %0|%0, %1}
2178    movlps\t{%1, %0|%0, %1}"
2179   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2180    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2181
2182 (define_split
2183   [(set (match_operand:DI 0 "push_operand" "")
2184         (match_operand:DI 1 "general_operand" ""))]
2185   "!TARGET_64BIT && reload_completed
2186    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2187   [(const_int 0)]
2188   "ix86_split_long_move (operands); DONE;")
2189
2190 ;; %%% This multiword shite has got to go.
2191 (define_split
2192   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2193         (match_operand:DI 1 "general_operand" ""))]
2194   "!TARGET_64BIT && reload_completed
2195    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2196    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2197   [(const_int 0)]
2198   "ix86_split_long_move (operands); DONE;")
2199
2200 (define_insn "*movdi_1_rex64"
2201   [(set (match_operand:DI 0 "nonimmediate_operand"
2202           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2203         (match_operand:DI 1 "general_operand"
2204           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2205   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2206 {
2207   switch (get_attr_type (insn))
2208     {
2209     case TYPE_SSECVT:
2210       if (SSE_REG_P (operands[0]))
2211         return "movq2dq\t{%1, %0|%0, %1}";
2212       else
2213         return "movdq2q\t{%1, %0|%0, %1}";
2214
2215     case TYPE_SSEMOV:
2216       if (get_attr_mode (insn) == MODE_TI)
2217         return "movdqa\t{%1, %0|%0, %1}";
2218       /* FALLTHRU */
2219
2220     case TYPE_MMXMOV:
2221       /* Moves from and into integer register is done using movd
2222          opcode with REX prefix.  */
2223       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2224         return "movd\t{%1, %0|%0, %1}";
2225       return "movq\t{%1, %0|%0, %1}";
2226
2227     case TYPE_SSELOG1:
2228     case TYPE_MMXADD:
2229       return "pxor\t%0, %0";
2230
2231     case TYPE_MULTI:
2232       return "#";
2233
2234     case TYPE_LEA:
2235       return "lea{q}\t{%a1, %0|%0, %a1}";
2236
2237     default:
2238       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2239       if (get_attr_mode (insn) == MODE_SI)
2240         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2241       else if (which_alternative == 2)
2242         return "movabs{q}\t{%1, %0|%0, %1}";
2243       else
2244         return "mov{q}\t{%1, %0|%0, %1}";
2245     }
2246 }
2247   [(set (attr "type")
2248      (cond [(eq_attr "alternative" "5")
2249               (const_string "mmxadd")
2250             (eq_attr "alternative" "6,7,8,9,10")
2251               (const_string "mmxmov")
2252             (eq_attr "alternative" "11")
2253               (const_string "sselog1")
2254             (eq_attr "alternative" "12,13,14,15,16")
2255               (const_string "ssemov")
2256             (eq_attr "alternative" "17,18")
2257               (const_string "ssecvt")
2258             (eq_attr "alternative" "4")
2259               (const_string "multi")
2260             (match_operand:DI 1 "pic_32bit_operand" "")
2261               (const_string "lea")
2262            ]
2263            (const_string "imov")))
2264    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2265    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2266    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2267
2268 ;; Stores and loads of ax to arbitrary constant address.
2269 ;; We fake an second form of instruction to force reload to load address
2270 ;; into register when rax is not available
2271 (define_insn "*movabsdi_1_rex64"
2272   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2273         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2274   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2275   "@
2276    movabs{q}\t{%1, %P0|%P0, %1}
2277    mov{q}\t{%1, %a0|%a0, %1}"
2278   [(set_attr "type" "imov")
2279    (set_attr "modrm" "0,*")
2280    (set_attr "length_address" "8,0")
2281    (set_attr "length_immediate" "0,*")
2282    (set_attr "memory" "store")
2283    (set_attr "mode" "DI")])
2284
2285 (define_insn "*movabsdi_2_rex64"
2286   [(set (match_operand:DI 0 "register_operand" "=a,r")
2287         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2288   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2289   "@
2290    movabs{q}\t{%P1, %0|%0, %P1}
2291    mov{q}\t{%a1, %0|%0, %a1}"
2292   [(set_attr "type" "imov")
2293    (set_attr "modrm" "0,*")
2294    (set_attr "length_address" "8,0")
2295    (set_attr "length_immediate" "0")
2296    (set_attr "memory" "load")
2297    (set_attr "mode" "DI")])
2298
2299 ;; Convert impossible stores of immediate to existing instructions.
2300 ;; First try to get scratch register and go through it.  In case this
2301 ;; fails, move by 32bit parts.
2302 (define_peephole2
2303   [(match_scratch:DI 2 "r")
2304    (set (match_operand:DI 0 "memory_operand" "")
2305         (match_operand:DI 1 "immediate_operand" ""))]
2306   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2307    && !x86_64_immediate_operand (operands[1], DImode)"
2308   [(set (match_dup 2) (match_dup 1))
2309    (set (match_dup 0) (match_dup 2))]
2310   "")
2311
2312 ;; We need to define this as both peepholer and splitter for case
2313 ;; peephole2 pass is not run.
2314 ;; "&& 1" is needed to keep it from matching the previous pattern.
2315 (define_peephole2
2316   [(set (match_operand:DI 0 "memory_operand" "")
2317         (match_operand:DI 1 "immediate_operand" ""))]
2318   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2319    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2320   [(set (match_dup 2) (match_dup 3))
2321    (set (match_dup 4) (match_dup 5))]
2322   "split_di (operands, 2, operands + 2, operands + 4);")
2323
2324 (define_split
2325   [(set (match_operand:DI 0 "memory_operand" "")
2326         (match_operand:DI 1 "immediate_operand" ""))]
2327   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2328                     ? epilogue_completed : reload_completed)
2329    && !symbolic_operand (operands[1], DImode)
2330    && !x86_64_immediate_operand (operands[1], DImode)"
2331   [(set (match_dup 2) (match_dup 3))
2332    (set (match_dup 4) (match_dup 5))]
2333   "split_di (operands, 2, operands + 2, operands + 4);")
2334
2335 (define_insn "*swapdi_rex64"
2336   [(set (match_operand:DI 0 "register_operand" "+r")
2337         (match_operand:DI 1 "register_operand" "+r"))
2338    (set (match_dup 1)
2339         (match_dup 0))]
2340   "TARGET_64BIT"
2341   "xchg{q}\t%1, %0"
2342   [(set_attr "type" "imov")
2343    (set_attr "mode" "DI")
2344    (set_attr "pent_pair" "np")
2345    (set_attr "athlon_decode" "vector")
2346    (set_attr "amdfam10_decode" "double")])   
2347
2348 (define_expand "movti"
2349   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2350         (match_operand:TI 1 "nonimmediate_operand" ""))]
2351   "TARGET_SSE || TARGET_64BIT"
2352 {
2353   if (TARGET_64BIT)
2354     ix86_expand_move (TImode, operands);
2355   else if (push_operand (operands[0], TImode))
2356     ix86_expand_push (TImode, operands[1]);
2357   else
2358     ix86_expand_vector_move (TImode, operands);
2359   DONE;
2360 })
2361
2362 (define_insn "*movti_internal"
2363   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2364         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2365   "TARGET_SSE && !TARGET_64BIT
2366    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2367 {
2368   switch (which_alternative)
2369     {
2370     case 0:
2371       if (get_attr_mode (insn) == MODE_V4SF)
2372         return "xorps\t%0, %0";
2373       else
2374         return "pxor\t%0, %0";
2375     case 1:
2376     case 2:
2377       if (get_attr_mode (insn) == MODE_V4SF)
2378         return "movaps\t{%1, %0|%0, %1}";
2379       else
2380         return "movdqa\t{%1, %0|%0, %1}";
2381     default:
2382       gcc_unreachable ();
2383     }
2384 }
2385   [(set_attr "type" "sselog1,ssemov,ssemov")
2386    (set (attr "mode")
2387         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2388                     (ne (symbol_ref "optimize_size") (const_int 0)))
2389                  (const_string "V4SF")
2390                (and (eq_attr "alternative" "2")
2391                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2392                         (const_int 0)))
2393                  (const_string "V4SF")]
2394               (const_string "TI")))])
2395
2396 (define_insn "*movti_rex64"
2397   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2398         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2399   "TARGET_64BIT
2400    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2401 {
2402   switch (which_alternative)
2403     {
2404     case 0:
2405     case 1:
2406       return "#";
2407     case 2:
2408       if (get_attr_mode (insn) == MODE_V4SF)
2409         return "xorps\t%0, %0";
2410       else
2411         return "pxor\t%0, %0";
2412     case 3:
2413     case 4:
2414       if (get_attr_mode (insn) == MODE_V4SF)
2415         return "movaps\t{%1, %0|%0, %1}";
2416       else
2417         return "movdqa\t{%1, %0|%0, %1}";
2418     default:
2419       gcc_unreachable ();
2420     }
2421 }
2422   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2423    (set (attr "mode")
2424         (cond [(eq_attr "alternative" "2,3")
2425                  (if_then_else
2426                    (ne (symbol_ref "optimize_size")
2427                        (const_int 0))
2428                    (const_string "V4SF")
2429                    (const_string "TI"))
2430                (eq_attr "alternative" "4")
2431                  (if_then_else
2432                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2433                             (const_int 0))
2434                         (ne (symbol_ref "optimize_size")
2435                             (const_int 0)))
2436                    (const_string "V4SF")
2437                    (const_string "TI"))]
2438                (const_string "DI")))])
2439
2440 (define_split
2441   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2442         (match_operand:TI 1 "general_operand" ""))]
2443   "reload_completed && !SSE_REG_P (operands[0])
2444    && !SSE_REG_P (operands[1])"
2445   [(const_int 0)]
2446   "ix86_split_long_move (operands); DONE;")
2447
2448 ;; This expands to what emit_move_complex would generate if we didn't
2449 ;; have a movti pattern.  Having this avoids problems with reload on
2450 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2451 ;; to have around all the time.
2452 (define_expand "movcdi"
2453   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2454         (match_operand:CDI 1 "general_operand" ""))]
2455   ""
2456 {
2457   if (push_operand (operands[0], CDImode))
2458     emit_move_complex_push (CDImode, operands[0], operands[1]);
2459   else
2460     emit_move_complex_parts (operands[0], operands[1]);
2461   DONE;
2462 })
2463
2464 (define_expand "movsf"
2465   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2466         (match_operand:SF 1 "general_operand" ""))]
2467   ""
2468   "ix86_expand_move (SFmode, operands); DONE;")
2469
2470 (define_insn "*pushsf"
2471   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2472         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2473   "!TARGET_64BIT"
2474 {
2475   /* Anything else should be already split before reg-stack.  */
2476   gcc_assert (which_alternative == 1);
2477   return "push{l}\t%1";
2478 }
2479   [(set_attr "type" "multi,push,multi")
2480    (set_attr "unit" "i387,*,*")
2481    (set_attr "mode" "SF,SI,SF")])
2482
2483 (define_insn "*pushsf_rex64"
2484   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2485         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2486   "TARGET_64BIT"
2487 {
2488   /* Anything else should be already split before reg-stack.  */
2489   gcc_assert (which_alternative == 1);
2490   return "push{q}\t%q1";
2491 }
2492   [(set_attr "type" "multi,push,multi")
2493    (set_attr "unit" "i387,*,*")
2494    (set_attr "mode" "SF,DI,SF")])
2495
2496 (define_split
2497   [(set (match_operand:SF 0 "push_operand" "")
2498         (match_operand:SF 1 "memory_operand" ""))]
2499   "reload_completed
2500    && MEM_P (operands[1])
2501    && (operands[2] = find_constant_src (insn))"
2502   [(set (match_dup 0)
2503         (match_dup 2))])
2504
2505
2506 ;; %%% Kill this when call knows how to work this out.
2507 (define_split
2508   [(set (match_operand:SF 0 "push_operand" "")
2509         (match_operand:SF 1 "any_fp_register_operand" ""))]
2510   "!TARGET_64BIT"
2511   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2512    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2513
2514 (define_split
2515   [(set (match_operand:SF 0 "push_operand" "")
2516         (match_operand:SF 1 "any_fp_register_operand" ""))]
2517   "TARGET_64BIT"
2518   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2519    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2520
2521 (define_insn "*movsf_1"
2522   [(set (match_operand:SF 0 "nonimmediate_operand"
2523           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2524         (match_operand:SF 1 "general_operand"
2525           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2526   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2527    && (reload_in_progress || reload_completed
2528        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2529        || (!TARGET_SSE_MATH && optimize_size
2530            && standard_80387_constant_p (operands[1]))
2531        || GET_CODE (operands[1]) != CONST_DOUBLE
2532        || memory_operand (operands[0], SFmode))"
2533 {
2534   switch (which_alternative)
2535     {
2536     case 0:
2537     case 1:
2538       return output_387_reg_move (insn, operands);
2539
2540     case 2:
2541       return standard_80387_constant_opcode (operands[1]);
2542
2543     case 3:
2544     case 4:
2545       return "mov{l}\t{%1, %0|%0, %1}";
2546     case 5:
2547       if (get_attr_mode (insn) == MODE_TI)
2548         return "pxor\t%0, %0";
2549       else
2550         return "xorps\t%0, %0";
2551     case 6:
2552       if (get_attr_mode (insn) == MODE_V4SF)
2553         return "movaps\t{%1, %0|%0, %1}";
2554       else
2555         return "movss\t{%1, %0|%0, %1}";
2556     case 7: case 8:
2557       return "movss\t{%1, %0|%0, %1}";
2558
2559     case 9: case 10:
2560     case 12: case 13: case 14: case 15:
2561       return "movd\t{%1, %0|%0, %1}";
2562
2563     case 11:
2564       return "movq\t{%1, %0|%0, %1}";
2565
2566     default:
2567       gcc_unreachable ();
2568     }
2569 }
2570   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2571    (set (attr "mode")
2572         (cond [(eq_attr "alternative" "3,4,9,10")
2573                  (const_string "SI")
2574                (eq_attr "alternative" "5")
2575                  (if_then_else
2576                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2577                                  (const_int 0))
2578                              (ne (symbol_ref "TARGET_SSE2")
2579                                  (const_int 0)))
2580                         (eq (symbol_ref "optimize_size")
2581                             (const_int 0)))
2582                    (const_string "TI")
2583                    (const_string "V4SF"))
2584                /* For architectures resolving dependencies on
2585                   whole SSE registers use APS move to break dependency
2586                   chains, otherwise use short move to avoid extra work.
2587
2588                   Do the same for architectures resolving dependencies on
2589                   the parts.  While in DF mode it is better to always handle
2590                   just register parts, the SF mode is different due to lack
2591                   of instructions to load just part of the register.  It is
2592                   better to maintain the whole registers in single format
2593                   to avoid problems on using packed logical operations.  */
2594                (eq_attr "alternative" "6")
2595                  (if_then_else
2596                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2597                             (const_int 0))
2598                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2599                             (const_int 0)))
2600                    (const_string "V4SF")
2601                    (const_string "SF"))
2602                (eq_attr "alternative" "11")
2603                  (const_string "DI")]
2604                (const_string "SF")))])
2605
2606 (define_insn "*swapsf"
2607   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2608         (match_operand:SF 1 "fp_register_operand" "+f"))
2609    (set (match_dup 1)
2610         (match_dup 0))]
2611   "reload_completed || TARGET_80387"
2612 {
2613   if (STACK_TOP_P (operands[0]))
2614     return "fxch\t%1";
2615   else
2616     return "fxch\t%0";
2617 }
2618   [(set_attr "type" "fxch")
2619    (set_attr "mode" "SF")])
2620
2621 (define_expand "movdf"
2622   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2623         (match_operand:DF 1 "general_operand" ""))]
2624   ""
2625   "ix86_expand_move (DFmode, operands); DONE;")
2626
2627 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2628 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2629 ;; On the average, pushdf using integers can be still shorter.  Allow this
2630 ;; pattern for optimize_size too.
2631
2632 (define_insn "*pushdf_nointeger"
2633   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2634         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2635   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2636 {
2637   /* This insn should be already split before reg-stack.  */
2638   gcc_unreachable ();
2639 }
2640   [(set_attr "type" "multi")
2641    (set_attr "unit" "i387,*,*,*")
2642    (set_attr "mode" "DF,SI,SI,DF")])
2643
2644 (define_insn "*pushdf_integer"
2645   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2646         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2647   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2648 {
2649   /* This insn should be already split before reg-stack.  */
2650   gcc_unreachable ();
2651 }
2652   [(set_attr "type" "multi")
2653    (set_attr "unit" "i387,*,*")
2654    (set_attr "mode" "DF,SI,DF")])
2655
2656 ;; %%% Kill this when call knows how to work this out.
2657 (define_split
2658   [(set (match_operand:DF 0 "push_operand" "")
2659         (match_operand:DF 1 "any_fp_register_operand" ""))]
2660   "!TARGET_64BIT && reload_completed"
2661   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2662    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2663   "")
2664
2665 (define_split
2666   [(set (match_operand:DF 0 "push_operand" "")
2667         (match_operand:DF 1 "any_fp_register_operand" ""))]
2668   "TARGET_64BIT && reload_completed"
2669   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2670    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2671   "")
2672
2673 (define_split
2674   [(set (match_operand:DF 0 "push_operand" "")
2675         (match_operand:DF 1 "general_operand" ""))]
2676   "reload_completed"
2677   [(const_int 0)]
2678   "ix86_split_long_move (operands); DONE;")
2679
2680 ;; Moving is usually shorter when only FP registers are used. This separate
2681 ;; movdf pattern avoids the use of integer registers for FP operations
2682 ;; when optimizing for size.
2683
2684 (define_insn "*movdf_nointeger"
2685   [(set (match_operand:DF 0 "nonimmediate_operand"
2686                         "=f,m,f,*r  ,o  ,Yt*x,Yt*x,Yt*x ,m  ")
2687         (match_operand:DF 1 "general_operand"
2688                         "fm,f,G,*roF,F*r,C   ,Yt*x,mYt*x,Yt*x"))]
2689   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2690    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2691    && (reload_in_progress || reload_completed
2692        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2693        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2694            && standard_80387_constant_p (operands[1]))
2695        || GET_CODE (operands[1]) != CONST_DOUBLE
2696        || memory_operand (operands[0], DFmode))"
2697 {
2698   switch (which_alternative)
2699     {
2700     case 0:
2701     case 1:
2702       return output_387_reg_move (insn, operands);
2703
2704     case 2:
2705       return standard_80387_constant_opcode (operands[1]);
2706
2707     case 3:
2708     case 4:
2709       return "#";
2710     case 5:
2711       switch (get_attr_mode (insn))
2712         {
2713         case MODE_V4SF:
2714           return "xorps\t%0, %0";
2715         case MODE_V2DF:
2716           return "xorpd\t%0, %0";
2717         case MODE_TI:
2718           return "pxor\t%0, %0";
2719         default:
2720           gcc_unreachable ();
2721         }
2722     case 6:
2723     case 7:
2724     case 8:
2725       switch (get_attr_mode (insn))
2726         {
2727         case MODE_V4SF:
2728           return "movaps\t{%1, %0|%0, %1}";
2729         case MODE_V2DF:
2730           return "movapd\t{%1, %0|%0, %1}";
2731         case MODE_TI:
2732           return "movdqa\t{%1, %0|%0, %1}";
2733         case MODE_DI:
2734           return "movq\t{%1, %0|%0, %1}";
2735         case MODE_DF:
2736           return "movsd\t{%1, %0|%0, %1}";
2737         case MODE_V1DF:
2738           return "movlpd\t{%1, %0|%0, %1}";
2739         case MODE_V2SF:
2740           return "movlps\t{%1, %0|%0, %1}";
2741         default:
2742           gcc_unreachable ();
2743         }
2744
2745     default:
2746       gcc_unreachable ();
2747     }
2748 }
2749   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2750    (set (attr "mode")
2751         (cond [(eq_attr "alternative" "0,1,2")
2752                  (const_string "DF")
2753                (eq_attr "alternative" "3,4")
2754                  (const_string "SI")
2755
2756                /* For SSE1, we have many fewer alternatives.  */
2757                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2758                  (cond [(eq_attr "alternative" "5,6")
2759                           (const_string "V4SF")
2760                        ]
2761                    (const_string "V2SF"))
2762
2763                /* xorps is one byte shorter.  */
2764                (eq_attr "alternative" "5")
2765                  (cond [(ne (symbol_ref "optimize_size")
2766                             (const_int 0))
2767                           (const_string "V4SF")
2768                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2769                             (const_int 0))
2770                           (const_string "TI")
2771                        ]
2772                        (const_string "V2DF"))
2773
2774                /* For architectures resolving dependencies on
2775                   whole SSE registers use APD move to break dependency
2776                   chains, otherwise use short move to avoid extra work.
2777
2778                   movaps encodes one byte shorter.  */
2779                (eq_attr "alternative" "6")
2780                  (cond
2781                    [(ne (symbol_ref "optimize_size")
2782                         (const_int 0))
2783                       (const_string "V4SF")
2784                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2785                         (const_int 0))
2786                       (const_string "V2DF")
2787                    ]
2788                    (const_string "DF"))
2789                /* For architectures resolving dependencies on register
2790                   parts we may avoid extra work to zero out upper part
2791                   of register.  */
2792                (eq_attr "alternative" "7")
2793                  (if_then_else
2794                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2795                        (const_int 0))
2796                    (const_string "V1DF")
2797                    (const_string "DF"))
2798               ]
2799               (const_string "DF")))])
2800
2801 (define_insn "*movdf_integer_rex64"
2802   [(set (match_operand:DF 0 "nonimmediate_operand"
2803                 "=f,m,f,r  ,m ,Yt*x,Yt*x,Yt*x,m   ,Yi,r ")
2804         (match_operand:DF 1 "general_operand"
2805                 "fm,f,G,rmF,Fr,C   ,Yt*x,m   ,Yt*x,r ,Yi"))]
2806   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2807    && (reload_in_progress || reload_completed
2808        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2809        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2810            && standard_80387_constant_p (operands[1]))
2811        || GET_CODE (operands[1]) != CONST_DOUBLE
2812        || memory_operand (operands[0], DFmode))"
2813 {
2814   switch (which_alternative)
2815     {
2816     case 0:
2817     case 1:
2818       return output_387_reg_move (insn, operands);
2819
2820     case 2:
2821       return standard_80387_constant_opcode (operands[1]);
2822
2823     case 3:
2824     case 4:
2825       return "#";
2826
2827     case 5:
2828       switch (get_attr_mode (insn))
2829         {
2830         case MODE_V4SF:
2831           return "xorps\t%0, %0";
2832         case MODE_V2DF:
2833           return "xorpd\t%0, %0";
2834         case MODE_TI:
2835           return "pxor\t%0, %0";
2836         default:
2837           gcc_unreachable ();
2838         }
2839     case 6:
2840     case 7:
2841     case 8:
2842       switch (get_attr_mode (insn))
2843         {
2844         case MODE_V4SF:
2845           return "movaps\t{%1, %0|%0, %1}";
2846         case MODE_V2DF:
2847           return "movapd\t{%1, %0|%0, %1}";
2848         case MODE_TI:
2849           return "movdqa\t{%1, %0|%0, %1}";
2850         case MODE_DI:
2851           return "movq\t{%1, %0|%0, %1}";
2852         case MODE_DF:
2853           return "movsd\t{%1, %0|%0, %1}";
2854         case MODE_V1DF:
2855           return "movlpd\t{%1, %0|%0, %1}";
2856         case MODE_V2SF:
2857           return "movlps\t{%1, %0|%0, %1}";
2858         default:
2859           gcc_unreachable ();
2860         }
2861
2862     case 9:
2863     case 10:
2864       return "movd\t{%1, %0|%0, %1}";
2865
2866     default:
2867       gcc_unreachable();
2868     }
2869 }
2870   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2871    (set (attr "mode")
2872         (cond [(eq_attr "alternative" "0,1,2")
2873                  (const_string "DF")
2874                (eq_attr "alternative" "3,4,9,10")
2875                  (const_string "DI")
2876
2877                /* For SSE1, we have many fewer alternatives.  */
2878                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2879                  (cond [(eq_attr "alternative" "5,6")
2880                           (const_string "V4SF")
2881                        ]
2882                    (const_string "V2SF"))
2883
2884                /* xorps is one byte shorter.  */
2885                (eq_attr "alternative" "5")
2886                  (cond [(ne (symbol_ref "optimize_size")
2887                             (const_int 0))
2888                           (const_string "V4SF")
2889                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2890                             (const_int 0))
2891                           (const_string "TI")
2892                        ]
2893                        (const_string "V2DF"))
2894
2895                /* For architectures resolving dependencies on
2896                   whole SSE registers use APD move to break dependency
2897                   chains, otherwise use short move to avoid extra work.
2898
2899                   movaps encodes one byte shorter.  */
2900                (eq_attr "alternative" "6")
2901                  (cond
2902                    [(ne (symbol_ref "optimize_size")
2903                         (const_int 0))
2904                       (const_string "V4SF")
2905                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2906                         (const_int 0))
2907                       (const_string "V2DF")
2908                    ]
2909                    (const_string "DF"))
2910                /* For architectures resolving dependencies on register
2911                   parts we may avoid extra work to zero out upper part
2912                   of register.  */
2913                (eq_attr "alternative" "7")
2914                  (if_then_else
2915                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2916                        (const_int 0))
2917                    (const_string "V1DF")
2918                    (const_string "DF"))
2919               ]
2920               (const_string "DF")))])
2921
2922 (define_insn "*movdf_integer"
2923   [(set (match_operand:DF 0 "nonimmediate_operand"
2924                 "=f,m,f,r  ,o ,Yt*x,Yt*x,Yt*x,m   ")
2925         (match_operand:DF 1 "general_operand"
2926                 "fm,f,G,roF,Fr,C   ,Yt*x,m   ,Yt*x"))]
2927   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2928    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2929    && (reload_in_progress || reload_completed
2930        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2931        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2932            && standard_80387_constant_p (operands[1]))
2933        || GET_CODE (operands[1]) != CONST_DOUBLE
2934        || memory_operand (operands[0], DFmode))"
2935 {
2936   switch (which_alternative)
2937     {
2938     case 0:
2939     case 1:
2940       return output_387_reg_move (insn, operands);
2941
2942     case 2:
2943       return standard_80387_constant_opcode (operands[1]);
2944
2945     case 3:
2946     case 4:
2947       return "#";
2948
2949     case 5:
2950       switch (get_attr_mode (insn))
2951         {
2952         case MODE_V4SF:
2953           return "xorps\t%0, %0";
2954         case MODE_V2DF:
2955           return "xorpd\t%0, %0";
2956         case MODE_TI:
2957           return "pxor\t%0, %0";
2958         default:
2959           gcc_unreachable ();
2960         }
2961     case 6:
2962     case 7:
2963     case 8:
2964       switch (get_attr_mode (insn))
2965         {
2966         case MODE_V4SF:
2967           return "movaps\t{%1, %0|%0, %1}";
2968         case MODE_V2DF:
2969           return "movapd\t{%1, %0|%0, %1}";
2970         case MODE_TI:
2971           return "movdqa\t{%1, %0|%0, %1}";
2972         case MODE_DI:
2973           return "movq\t{%1, %0|%0, %1}";
2974         case MODE_DF:
2975           return "movsd\t{%1, %0|%0, %1}";
2976         case MODE_V1DF:
2977           return "movlpd\t{%1, %0|%0, %1}";
2978         case MODE_V2SF:
2979           return "movlps\t{%1, %0|%0, %1}";
2980         default:
2981           gcc_unreachable ();
2982         }
2983
2984     default:
2985       gcc_unreachable();
2986     }
2987 }
2988   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2989    (set (attr "mode")
2990         (cond [(eq_attr "alternative" "0,1,2")
2991                  (const_string "DF")
2992                (eq_attr "alternative" "3,4")
2993                  (const_string "SI")
2994
2995                /* For SSE1, we have many fewer alternatives.  */
2996                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2997                  (cond [(eq_attr "alternative" "5,6")
2998                           (const_string "V4SF")
2999                        ]
3000                    (const_string "V2SF"))
3001
3002                /* xorps is one byte shorter.  */
3003                (eq_attr "alternative" "5")
3004                  (cond [(ne (symbol_ref "optimize_size")
3005                             (const_int 0))
3006                           (const_string "V4SF")
3007                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3008                             (const_int 0))
3009                           (const_string "TI")
3010                        ]
3011                        (const_string "V2DF"))
3012
3013                /* For architectures resolving dependencies on
3014                   whole SSE registers use APD move to break dependency
3015                   chains, otherwise use short move to avoid extra work.
3016
3017                   movaps encodes one byte shorter.  */
3018                (eq_attr "alternative" "6")
3019                  (cond
3020                    [(ne (symbol_ref "optimize_size")
3021                         (const_int 0))
3022                       (const_string "V4SF")
3023                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3024                         (const_int 0))
3025                       (const_string "V2DF")
3026                    ]
3027                    (const_string "DF"))
3028                /* For architectures resolving dependencies on register
3029                   parts we may avoid extra work to zero out upper part
3030                   of register.  */
3031                (eq_attr "alternative" "7")
3032                  (if_then_else
3033                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3034                        (const_int 0))
3035                    (const_string "V1DF")
3036                    (const_string "DF"))
3037               ]
3038               (const_string "DF")))])
3039
3040 (define_split
3041   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3042         (match_operand:DF 1 "general_operand" ""))]
3043   "reload_completed
3044    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3045    && ! (ANY_FP_REG_P (operands[0]) ||
3046          (GET_CODE (operands[0]) == SUBREG
3047           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3048    && ! (ANY_FP_REG_P (operands[1]) ||
3049          (GET_CODE (operands[1]) == SUBREG
3050           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3051   [(const_int 0)]
3052   "ix86_split_long_move (operands); DONE;")
3053
3054 (define_insn "*swapdf"
3055   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3056         (match_operand:DF 1 "fp_register_operand" "+f"))
3057    (set (match_dup 1)
3058         (match_dup 0))]
3059   "reload_completed || TARGET_80387"
3060 {
3061   if (STACK_TOP_P (operands[0]))
3062     return "fxch\t%1";
3063   else
3064     return "fxch\t%0";
3065 }
3066   [(set_attr "type" "fxch")
3067    (set_attr "mode" "DF")])
3068
3069 (define_expand "movxf"
3070   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3071         (match_operand:XF 1 "general_operand" ""))]
3072   ""
3073   "ix86_expand_move (XFmode, operands); DONE;")
3074
3075 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3076 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3077 ;; Pushing using integer instructions is longer except for constants
3078 ;; and direct memory references.
3079 ;; (assuming that any given constant is pushed only once, but this ought to be
3080 ;;  handled elsewhere).
3081
3082 (define_insn "*pushxf_nointeger"
3083   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3084         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3085   "optimize_size"
3086 {
3087   /* This insn should be already split before reg-stack.  */
3088   gcc_unreachable ();
3089 }
3090   [(set_attr "type" "multi")
3091    (set_attr "unit" "i387,*,*")
3092    (set_attr "mode" "XF,SI,SI")])
3093
3094 (define_insn "*pushxf_integer"
3095   [(set (match_operand:XF 0 "push_operand" "=<,<")
3096         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3097   "!optimize_size"
3098 {
3099   /* This insn should be already split before reg-stack.  */
3100   gcc_unreachable ();
3101 }
3102   [(set_attr "type" "multi")
3103    (set_attr "unit" "i387,*")
3104    (set_attr "mode" "XF,SI")])
3105
3106 (define_split
3107   [(set (match_operand 0 "push_operand" "")
3108         (match_operand 1 "general_operand" ""))]
3109   "reload_completed
3110    && (GET_MODE (operands[0]) == XFmode
3111        || GET_MODE (operands[0]) == DFmode)
3112    && !ANY_FP_REG_P (operands[1])"
3113   [(const_int 0)]
3114   "ix86_split_long_move (operands); DONE;")
3115
3116 (define_split
3117   [(set (match_operand:XF 0 "push_operand" "")
3118         (match_operand:XF 1 "any_fp_register_operand" ""))]
3119   "!TARGET_64BIT"
3120   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3121    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3122   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3123
3124 (define_split
3125   [(set (match_operand:XF 0 "push_operand" "")
3126         (match_operand:XF 1 "any_fp_register_operand" ""))]
3127   "TARGET_64BIT"
3128   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3129    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3130   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3131
3132 ;; Do not use integer registers when optimizing for size
3133 (define_insn "*movxf_nointeger"
3134   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3135         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3136   "optimize_size
3137    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3138    && (reload_in_progress || reload_completed
3139        || (optimize_size && standard_80387_constant_p (operands[1]))
3140        || GET_CODE (operands[1]) != CONST_DOUBLE
3141        || memory_operand (operands[0], XFmode))"
3142 {
3143   switch (which_alternative)
3144     {
3145     case 0:
3146     case 1:
3147       return output_387_reg_move (insn, operands);
3148
3149     case 2:
3150       return standard_80387_constant_opcode (operands[1]);
3151
3152     case 3: case 4:
3153       return "#";
3154     default:
3155       gcc_unreachable ();
3156     }
3157 }
3158   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3159    (set_attr "mode" "XF,XF,XF,SI,SI")])
3160
3161 (define_insn "*movxf_integer"
3162   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3163         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3164   "!optimize_size
3165    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3166    && (reload_in_progress || reload_completed
3167        || (optimize_size && standard_80387_constant_p (operands[1]))
3168        || GET_CODE (operands[1]) != CONST_DOUBLE
3169        || memory_operand (operands[0], XFmode))"
3170 {
3171   switch (which_alternative)
3172     {
3173     case 0:
3174     case 1:
3175       return output_387_reg_move (insn, operands);
3176
3177     case 2:
3178       return standard_80387_constant_opcode (operands[1]);
3179
3180     case 3: case 4:
3181       return "#";
3182
3183     default:
3184       gcc_unreachable ();
3185     }
3186 }
3187   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3188    (set_attr "mode" "XF,XF,XF,SI,SI")])
3189
3190 (define_expand "movtf"
3191   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3192         (match_operand:TF 1 "nonimmediate_operand" ""))]
3193   "TARGET_64BIT"
3194 {
3195   ix86_expand_move (TFmode, operands);
3196   DONE;
3197 })
3198
3199 (define_insn "*movtf_internal"
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3201         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3202   "TARGET_64BIT
3203    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3204 {
3205   switch (which_alternative)
3206     {
3207     case 0:
3208     case 1:
3209       if (get_attr_mode (insn) == MODE_V4SF)
3210         return "movaps\t{%1, %0|%0, %1}";
3211       else
3212         return "movdqa\t{%1, %0|%0, %1}";
3213     case 2:
3214       if (get_attr_mode (insn) == MODE_V4SF)
3215         return "xorps\t%0, %0";
3216       else
3217         return "pxor\t%0, %0";
3218     case 3:
3219     case 4:
3220         return "#";
3221     default:
3222       gcc_unreachable ();
3223     }
3224 }
3225   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3226    (set (attr "mode")
3227         (cond [(eq_attr "alternative" "0,2")
3228                  (if_then_else
3229                    (ne (symbol_ref "optimize_size")
3230                        (const_int 0))
3231                    (const_string "V4SF")
3232                    (const_string "TI"))
3233                (eq_attr "alternative" "1")
3234                  (if_then_else
3235                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3236                             (const_int 0))
3237                         (ne (symbol_ref "optimize_size")
3238                             (const_int 0)))
3239                    (const_string "V4SF")
3240                    (const_string "TI"))]
3241                (const_string "DI")))])
3242
3243 (define_split
3244   [(set (match_operand 0 "nonimmediate_operand" "")
3245         (match_operand 1 "general_operand" ""))]
3246   "reload_completed
3247    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3248    && GET_MODE (operands[0]) == XFmode
3249    && ! (ANY_FP_REG_P (operands[0]) ||
3250          (GET_CODE (operands[0]) == SUBREG
3251           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3252    && ! (ANY_FP_REG_P (operands[1]) ||
3253          (GET_CODE (operands[1]) == SUBREG
3254           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3255   [(const_int 0)]
3256   "ix86_split_long_move (operands); DONE;")
3257
3258 (define_split
3259   [(set (match_operand 0 "register_operand" "")
3260         (match_operand 1 "memory_operand" ""))]
3261   "reload_completed
3262    && MEM_P (operands[1])
3263    && (GET_MODE (operands[0]) == TFmode
3264        || GET_MODE (operands[0]) == XFmode
3265        || GET_MODE (operands[0]) == SFmode
3266        || GET_MODE (operands[0]) == DFmode)
3267    && (operands[2] = find_constant_src (insn))"
3268   [(set (match_dup 0) (match_dup 2))]
3269 {
3270   rtx c = operands[2];
3271   rtx r = operands[0];
3272
3273   if (GET_CODE (r) == SUBREG)
3274     r = SUBREG_REG (r);
3275
3276   if (SSE_REG_P (r))
3277     {
3278       if (!standard_sse_constant_p (c))
3279         FAIL;
3280     }
3281   else if (FP_REG_P (r))
3282     {
3283       if (!standard_80387_constant_p (c))
3284         FAIL;
3285     }
3286   else if (MMX_REG_P (r))
3287     FAIL;
3288 })
3289
3290 (define_split
3291   [(set (match_operand 0 "register_operand" "")
3292         (float_extend (match_operand 1 "memory_operand" "")))]
3293   "reload_completed
3294    && MEM_P (operands[1])
3295    && (GET_MODE (operands[0]) == TFmode
3296        || GET_MODE (operands[0]) == XFmode
3297        || GET_MODE (operands[0]) == SFmode
3298        || GET_MODE (operands[0]) == DFmode)
3299    && (operands[2] = find_constant_src (insn))"
3300   [(set (match_dup 0) (match_dup 2))]
3301 {
3302   rtx c = operands[2];
3303   rtx r = operands[0];
3304
3305   if (GET_CODE (r) == SUBREG)
3306     r = SUBREG_REG (r);
3307
3308   if (SSE_REG_P (r))
3309     {
3310       if (!standard_sse_constant_p (c))
3311         FAIL;
3312     }
3313   else if (FP_REG_P (r))
3314     {
3315       if (!standard_80387_constant_p (c))
3316         FAIL;
3317     }
3318   else if (MMX_REG_P (r))
3319     FAIL;
3320 })
3321
3322 (define_insn "swapxf"
3323   [(set (match_operand:XF 0 "register_operand" "+f")
3324         (match_operand:XF 1 "register_operand" "+f"))
3325    (set (match_dup 1)
3326         (match_dup 0))]
3327   "TARGET_80387"
3328 {
3329   if (STACK_TOP_P (operands[0]))
3330     return "fxch\t%1";
3331   else
3332     return "fxch\t%0";
3333 }
3334   [(set_attr "type" "fxch")
3335    (set_attr "mode" "XF")])
3336
3337 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3338 (define_split
3339   [(set (match_operand:X87MODEF 0 "register_operand" "")
3340         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3341   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3342    && (standard_80387_constant_p (operands[1]) == 8
3343        || standard_80387_constant_p (operands[1]) == 9)"
3344   [(set (match_dup 0)(match_dup 1))
3345    (set (match_dup 0)
3346         (neg:X87MODEF (match_dup 0)))]
3347 {
3348   REAL_VALUE_TYPE r;
3349
3350   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3351   if (real_isnegzero (&r))
3352     operands[1] = CONST0_RTX (<MODE>mode);
3353   else
3354     operands[1] = CONST1_RTX (<MODE>mode);
3355 })
3356
3357 (define_split
3358   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3359         (match_operand:TF 1 "general_operand" ""))]
3360   "reload_completed
3361    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3362   [(const_int 0)]
3363   "ix86_split_long_move (operands); DONE;")
3364 \f
3365 ;; Zero extension instructions
3366
3367 (define_expand "zero_extendhisi2"
3368   [(set (match_operand:SI 0 "register_operand" "")
3369      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3370   ""
3371 {
3372   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3373     {
3374       operands[1] = force_reg (HImode, operands[1]);
3375       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3376       DONE;
3377     }
3378 })
3379
3380 (define_insn "zero_extendhisi2_and"
3381   [(set (match_operand:SI 0 "register_operand" "=r")
3382      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3385   "#"
3386   [(set_attr "type" "alu1")
3387    (set_attr "mode" "SI")])
3388
3389 (define_split
3390   [(set (match_operand:SI 0 "register_operand" "")
3391         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3392    (clobber (reg:CC FLAGS_REG))]
3393   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3394   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3395               (clobber (reg:CC FLAGS_REG))])]
3396   "")
3397
3398 (define_insn "*zero_extendhisi2_movzwl"
3399   [(set (match_operand:SI 0 "register_operand" "=r")
3400      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3401   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3402   "movz{wl|x}\t{%1, %0|%0, %1}"
3403   [(set_attr "type" "imovx")
3404    (set_attr "mode" "SI")])
3405
3406 (define_expand "zero_extendqihi2"
3407   [(parallel
3408     [(set (match_operand:HI 0 "register_operand" "")
3409        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3410      (clobber (reg:CC FLAGS_REG))])]
3411   ""
3412   "")
3413
3414 (define_insn "*zero_extendqihi2_and"
3415   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3416      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3417    (clobber (reg:CC FLAGS_REG))]
3418   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3419   "#"
3420   [(set_attr "type" "alu1")
3421    (set_attr "mode" "HI")])
3422
3423 (define_insn "*zero_extendqihi2_movzbw_and"
3424   [(set (match_operand:HI 0 "register_operand" "=r,r")
3425      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3426    (clobber (reg:CC FLAGS_REG))]
3427   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3428   "#"
3429   [(set_attr "type" "imovx,alu1")
3430    (set_attr "mode" "HI")])
3431
3432 ; zero extend to SImode here to avoid partial register stalls
3433 (define_insn "*zero_extendqihi2_movzbl"
3434   [(set (match_operand:HI 0 "register_operand" "=r")
3435      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3436   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3437   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3438   [(set_attr "type" "imovx")
3439    (set_attr "mode" "SI")])
3440
3441 ;; For the movzbw case strip only the clobber
3442 (define_split
3443   [(set (match_operand:HI 0 "register_operand" "")
3444         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "reload_completed
3447    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3448    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3449   [(set (match_operand:HI 0 "register_operand" "")
3450         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3451
3452 ;; When source and destination does not overlap, clear destination
3453 ;; first and then do the movb
3454 (define_split
3455   [(set (match_operand:HI 0 "register_operand" "")
3456         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3457    (clobber (reg:CC FLAGS_REG))]
3458   "reload_completed
3459    && ANY_QI_REG_P (operands[0])
3460    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3461    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3462   [(set (match_dup 0) (const_int 0))
3463    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3464   "operands[2] = gen_lowpart (QImode, operands[0]);")
3465
3466 ;; Rest is handled by single and.
3467 (define_split
3468   [(set (match_operand:HI 0 "register_operand" "")
3469         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3470    (clobber (reg:CC FLAGS_REG))]
3471   "reload_completed
3472    && true_regnum (operands[0]) == true_regnum (operands[1])"
3473   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3474               (clobber (reg:CC FLAGS_REG))])]
3475   "")
3476
3477 (define_expand "zero_extendqisi2"
3478   [(parallel
3479     [(set (match_operand:SI 0 "register_operand" "")
3480        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3481      (clobber (reg:CC FLAGS_REG))])]
3482   ""
3483   "")
3484
3485 (define_insn "*zero_extendqisi2_and"
3486   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3487      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488    (clobber (reg:CC FLAGS_REG))]
3489   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3490   "#"
3491   [(set_attr "type" "alu1")
3492    (set_attr "mode" "SI")])
3493
3494 (define_insn "*zero_extendqisi2_movzbw_and"
3495   [(set (match_operand:SI 0 "register_operand" "=r,r")
3496      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497    (clobber (reg:CC FLAGS_REG))]
3498   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3499   "#"
3500   [(set_attr "type" "imovx,alu1")
3501    (set_attr "mode" "SI")])
3502
3503 (define_insn "*zero_extendqisi2_movzbw"
3504   [(set (match_operand:SI 0 "register_operand" "=r")
3505      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3506   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3507   "movz{bl|x}\t{%1, %0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "SI")])
3510
3511 ;; For the movzbl case strip only the clobber
3512 (define_split
3513   [(set (match_operand:SI 0 "register_operand" "")
3514         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3515    (clobber (reg:CC FLAGS_REG))]
3516   "reload_completed
3517    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3518    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3519   [(set (match_dup 0)
3520         (zero_extend:SI (match_dup 1)))])
3521
3522 ;; When source and destination does not overlap, clear destination
3523 ;; first and then do the movb
3524 (define_split
3525   [(set (match_operand:SI 0 "register_operand" "")
3526         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "reload_completed
3529    && ANY_QI_REG_P (operands[0])
3530    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3531    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533   [(set (match_dup 0) (const_int 0))
3534    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535   "operands[2] = gen_lowpart (QImode, operands[0]);")
3536
3537 ;; Rest is handled by single and.
3538 (define_split
3539   [(set (match_operand:SI 0 "register_operand" "")
3540         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3541    (clobber (reg:CC FLAGS_REG))]
3542   "reload_completed
3543    && true_regnum (operands[0]) == true_regnum (operands[1])"
3544   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3545               (clobber (reg:CC FLAGS_REG))])]
3546   "")
3547
3548 ;; %%% Kill me once multi-word ops are sane.
3549 (define_expand "zero_extendsidi2"
3550   [(set (match_operand:DI 0 "register_operand" "")
3551      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3552   ""
3553 {
3554   if (!TARGET_64BIT)
3555     {
3556       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3557       DONE;
3558     }
3559 })
3560
3561 (define_insn "zero_extendsidi2_32"
3562   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3563         (zero_extend:DI
3564          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3565    (clobber (reg:CC FLAGS_REG))]
3566   "!TARGET_64BIT"
3567   "@
3568    #
3569    #
3570    #
3571    movd\t{%1, %0|%0, %1}
3572    movd\t{%1, %0|%0, %1}
3573    movd\t{%1, %0|%0, %1}
3574    movd\t{%1, %0|%0, %1}"
3575   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3576    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3577
3578 (define_insn "zero_extendsidi2_rex64"
3579   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3580      (zero_extend:DI
3581        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3582   "TARGET_64BIT"
3583   "@
3584    mov\t{%k1, %k0|%k0, %k1}
3585    #
3586    movd\t{%1, %0|%0, %1}
3587    movd\t{%1, %0|%0, %1}
3588    movd\t{%1, %0|%0, %1}
3589    movd\t{%1, %0|%0, %1}"
3590   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3591    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3592
3593 (define_split
3594   [(set (match_operand:DI 0 "memory_operand" "")
3595      (zero_extend:DI (match_dup 0)))]
3596   "TARGET_64BIT"
3597   [(set (match_dup 4) (const_int 0))]
3598   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3599
3600 (define_split
3601   [(set (match_operand:DI 0 "register_operand" "")
3602         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3603    (clobber (reg:CC FLAGS_REG))]
3604   "!TARGET_64BIT && reload_completed
3605    && true_regnum (operands[0]) == true_regnum (operands[1])"
3606   [(set (match_dup 4) (const_int 0))]
3607   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3608
3609 (define_split
3610   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3611         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "!TARGET_64BIT && reload_completed
3614    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3615   [(set (match_dup 3) (match_dup 1))
3616    (set (match_dup 4) (const_int 0))]
3617   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3618
3619 (define_insn "zero_extendhidi2"
3620   [(set (match_operand:DI 0 "register_operand" "=r")
3621      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3622   "TARGET_64BIT"
3623   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3624   [(set_attr "type" "imovx")
3625    (set_attr "mode" "DI")])
3626
3627 (define_insn "zero_extendqidi2"
3628   [(set (match_operand:DI 0 "register_operand" "=r")
3629      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3630   "TARGET_64BIT"
3631   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3632   [(set_attr "type" "imovx")
3633    (set_attr "mode" "DI")])
3634 \f
3635 ;; Sign extension instructions
3636
3637 (define_expand "extendsidi2"
3638   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3639                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3640               (clobber (reg:CC FLAGS_REG))
3641               (clobber (match_scratch:SI 2 ""))])]
3642   ""
3643 {
3644   if (TARGET_64BIT)
3645     {
3646       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3647       DONE;
3648     }
3649 })
3650
3651 (define_insn "*extendsidi2_1"
3652   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654    (clobber (reg:CC FLAGS_REG))
3655    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3656   "!TARGET_64BIT"
3657   "#")
3658
3659 (define_insn "extendsidi2_rex64"
3660   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3661         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3662   "TARGET_64BIT"
3663   "@
3664    {cltq|cdqe}
3665    movs{lq|x}\t{%1,%0|%0, %1}"
3666   [(set_attr "type" "imovx")
3667    (set_attr "mode" "DI")
3668    (set_attr "prefix_0f" "0")
3669    (set_attr "modrm" "0,1")])
3670
3671 (define_insn "extendhidi2"
3672   [(set (match_operand:DI 0 "register_operand" "=r")
3673         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3674   "TARGET_64BIT"
3675   "movs{wq|x}\t{%1,%0|%0, %1}"
3676   [(set_attr "type" "imovx")
3677    (set_attr "mode" "DI")])
3678
3679 (define_insn "extendqidi2"
3680   [(set (match_operand:DI 0 "register_operand" "=r")
3681         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3682   "TARGET_64BIT"
3683   "movs{bq|x}\t{%1,%0|%0, %1}"
3684    [(set_attr "type" "imovx")
3685     (set_attr "mode" "DI")])
3686
3687 ;; Extend to memory case when source register does die.
3688 (define_split
3689   [(set (match_operand:DI 0 "memory_operand" "")
3690         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3691    (clobber (reg:CC FLAGS_REG))
3692    (clobber (match_operand:SI 2 "register_operand" ""))]
3693   "(reload_completed
3694     && dead_or_set_p (insn, operands[1])
3695     && !reg_mentioned_p (operands[1], operands[0]))"
3696   [(set (match_dup 3) (match_dup 1))
3697    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3698               (clobber (reg:CC FLAGS_REG))])
3699    (set (match_dup 4) (match_dup 1))]
3700   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3701
3702 ;; Extend to memory case when source register does not die.
3703 (define_split
3704   [(set (match_operand:DI 0 "memory_operand" "")
3705         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3706    (clobber (reg:CC FLAGS_REG))
3707    (clobber (match_operand:SI 2 "register_operand" ""))]
3708   "reload_completed"
3709   [(const_int 0)]
3710 {
3711   split_di (&operands[0], 1, &operands[3], &operands[4]);
3712
3713   emit_move_insn (operands[3], operands[1]);
3714
3715   /* Generate a cltd if possible and doing so it profitable.  */
3716   if ((optimize_size || TARGET_USE_CLTD)
3717       && true_regnum (operands[1]) == 0
3718       && true_regnum (operands[2]) == 1)
3719     {
3720       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3721     }
3722   else
3723     {
3724       emit_move_insn (operands[2], operands[1]);
3725       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3726     }
3727   emit_move_insn (operands[4], operands[2]);
3728   DONE;
3729 })
3730
3731 ;; Extend to register case.  Optimize case where source and destination
3732 ;; registers match and cases where we can use cltd.
3733 (define_split
3734   [(set (match_operand:DI 0 "register_operand" "")
3735         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3736    (clobber (reg:CC FLAGS_REG))
3737    (clobber (match_scratch:SI 2 ""))]
3738   "reload_completed"
3739   [(const_int 0)]
3740 {
3741   split_di (&operands[0], 1, &operands[3], &operands[4]);
3742
3743   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3744     emit_move_insn (operands[3], operands[1]);
3745
3746   /* Generate a cltd if possible and doing so it profitable.  */
3747   if ((optimize_size || TARGET_USE_CLTD)
3748       && true_regnum (operands[3]) == 0)
3749     {
3750       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3751       DONE;
3752     }
3753
3754   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3755     emit_move_insn (operands[4], operands[1]);
3756
3757   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3758   DONE;
3759 })
3760
3761 (define_insn "extendhisi2"
3762   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3763         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3764   ""
3765 {
3766   switch (get_attr_prefix_0f (insn))
3767     {
3768     case 0:
3769       return "{cwtl|cwde}";
3770     default:
3771       return "movs{wl|x}\t{%1,%0|%0, %1}";
3772     }
3773 }
3774   [(set_attr "type" "imovx")
3775    (set_attr "mode" "SI")
3776    (set (attr "prefix_0f")
3777      ;; movsx is short decodable while cwtl is vector decoded.
3778      (if_then_else (and (eq_attr "cpu" "!k6")
3779                         (eq_attr "alternative" "0"))
3780         (const_string "0")
3781         (const_string "1")))
3782    (set (attr "modrm")
3783      (if_then_else (eq_attr "prefix_0f" "0")
3784         (const_string "0")
3785         (const_string "1")))])
3786
3787 (define_insn "*extendhisi2_zext"
3788   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3789         (zero_extend:DI
3790           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3791   "TARGET_64BIT"
3792 {
3793   switch (get_attr_prefix_0f (insn))
3794     {
3795     case 0:
3796       return "{cwtl|cwde}";
3797     default:
3798       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3799     }
3800 }
3801   [(set_attr "type" "imovx")
3802    (set_attr "mode" "SI")
3803    (set (attr "prefix_0f")
3804      ;; movsx is short decodable while cwtl is vector decoded.
3805      (if_then_else (and (eq_attr "cpu" "!k6")
3806                         (eq_attr "alternative" "0"))
3807         (const_string "0")
3808         (const_string "1")))
3809    (set (attr "modrm")
3810      (if_then_else (eq_attr "prefix_0f" "0")
3811         (const_string "0")
3812         (const_string "1")))])
3813
3814 (define_insn "extendqihi2"
3815   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3817   ""
3818 {
3819   switch (get_attr_prefix_0f (insn))
3820     {
3821     case 0:
3822       return "{cbtw|cbw}";
3823     default:
3824       return "movs{bw|x}\t{%1,%0|%0, %1}";
3825     }
3826 }
3827   [(set_attr "type" "imovx")
3828    (set_attr "mode" "HI")
3829    (set (attr "prefix_0f")
3830      ;; movsx is short decodable while cwtl is vector decoded.
3831      (if_then_else (and (eq_attr "cpu" "!k6")
3832                         (eq_attr "alternative" "0"))
3833         (const_string "0")
3834         (const_string "1")))
3835    (set (attr "modrm")
3836      (if_then_else (eq_attr "prefix_0f" "0")
3837         (const_string "0")
3838         (const_string "1")))])
3839
3840 (define_insn "extendqisi2"
3841   [(set (match_operand:SI 0 "register_operand" "=r")
3842         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3843   ""
3844   "movs{bl|x}\t{%1,%0|%0, %1}"
3845    [(set_attr "type" "imovx")
3846     (set_attr "mode" "SI")])
3847
3848 (define_insn "*extendqisi2_zext"
3849   [(set (match_operand:DI 0 "register_operand" "=r")
3850         (zero_extend:DI
3851           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3852   "TARGET_64BIT"
3853   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3854    [(set_attr "type" "imovx")
3855     (set_attr "mode" "SI")])
3856 \f
3857 ;; Conversions between float and double.
3858
3859 ;; These are all no-ops in the model used for the 80387.  So just
3860 ;; emit moves.
3861
3862 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3863 (define_insn "*dummy_extendsfdf2"
3864   [(set (match_operand:DF 0 "push_operand" "=<")
3865         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3866   "0"
3867   "#")
3868
3869 (define_split
3870   [(set (match_operand:DF 0 "push_operand" "")
3871         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3872   "!TARGET_64BIT"
3873   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3874    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3875
3876 (define_split
3877   [(set (match_operand:DF 0 "push_operand" "")
3878         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3879   "TARGET_64BIT"
3880   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3881    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3882
3883 (define_insn "*dummy_extendsfxf2"
3884   [(set (match_operand:XF 0 "push_operand" "=<")
3885         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3886   "0"
3887   "#")
3888
3889 (define_split
3890   [(set (match_operand:XF 0 "push_operand" "")
3891         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3892   ""
3893   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3894    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3895   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3896
3897 (define_split
3898   [(set (match_operand:XF 0 "push_operand" "")
3899         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3900   "TARGET_64BIT"
3901   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3902    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3903   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3904
3905 (define_split
3906   [(set (match_operand:XF 0 "push_operand" "")
3907         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3908   ""
3909   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3910    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3911   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3912
3913 (define_split
3914   [(set (match_operand:XF 0 "push_operand" "")
3915         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3916   "TARGET_64BIT"
3917   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3918    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3919   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3920
3921 (define_expand "extendsfdf2"
3922   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3924   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3925 {
3926   /* ??? Needed for compress_float_constant since all fp constants
3927      are LEGITIMATE_CONSTANT_P.  */
3928   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3929     {
3930       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3931           && standard_80387_constant_p (operands[1]) > 0)
3932         {
3933           operands[1] = simplify_const_unary_operation
3934             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3935           emit_move_insn_1 (operands[0], operands[1]);
3936           DONE;
3937         }
3938       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3939     }
3940 })
3941
3942 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3943    cvtss2sd:
3944       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3945       cvtps2pd xmm2,xmm1
3946    We do the conversion post reload to avoid producing of 128bit spills
3947    that might lead to ICE on 32bit target.  The sequence unlikely combine
3948    anyway.  */
3949 (define_split
3950   [(set (match_operand:DF 0 "register_operand" "")
3951         (float_extend:DF
3952           (match_operand:SF 1 "nonimmediate_operand" "")))]
3953   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size 
3954    && reload_completed && SSE_REG_P (operands[0])"
3955    [(set (match_dup 2)
3956          (float_extend:V2DF
3957            (vec_select:V2SF
3958              (match_dup 3)
3959              (parallel [(const_int 0) (const_int 1)]))))]
3960 {
3961   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3962   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3963   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3964      Try to avoid move when unpacking can be done in source.  */
3965   if (REG_P (operands[1]))
3966     {
3967       /* If it is unsafe to overwrite upper half of source, we need
3968          to move to destination and unpack there.  */
3969       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3970            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3971           && true_regnum (operands[0]) != true_regnum (operands[1]))
3972         {
3973           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3974           emit_move_insn (tmp, operands[1]);
3975         }
3976       else
3977         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3978       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3979     }
3980   else
3981     emit_insn (gen_vec_setv4sf_0 (operands[3], 
3982                                   CONST0_RTX (V4SFmode), operands[1]));
3983 })
3984
3985 (define_insn "*extendsfdf2_mixed"
3986   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3987         (float_extend:DF
3988           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3989   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3990 {
3991   switch (which_alternative)
3992     {
3993     case 0:
3994     case 1:
3995       return output_387_reg_move (insn, operands);
3996
3997     case 2:
3998       return "cvtss2sd\t{%1, %0|%0, %1}";
3999
4000     default:
4001       gcc_unreachable ();
4002     }
4003 }
4004   [(set_attr "type" "fmov,fmov,ssecvt")
4005    (set_attr "mode" "SF,XF,DF")])
4006
4007 (define_insn "*extendsfdf2_sse"
4008   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4009         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4010   "TARGET_SSE2 && TARGET_SSE_MATH"
4011   "cvtss2sd\t{%1, %0|%0, %1}"
4012   [(set_attr "type" "ssecvt")
4013    (set_attr "mode" "DF")])
4014
4015 (define_insn "*extendsfdf2_i387"
4016   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4017         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4018   "TARGET_80387"
4019   "* return output_387_reg_move (insn, operands);"
4020   [(set_attr "type" "fmov")
4021    (set_attr "mode" "SF,XF")])
4022
4023 (define_expand "extend<mode>xf2"
4024   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4025         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4026   "TARGET_80387"
4027 {
4028   /* ??? Needed for compress_float_constant since all fp constants
4029      are LEGITIMATE_CONSTANT_P.  */
4030   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4031     {
4032       if (standard_80387_constant_p (operands[1]) > 0)
4033         {
4034           operands[1] = simplify_const_unary_operation
4035             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4036           emit_move_insn_1 (operands[0], operands[1]);
4037           DONE;
4038         }
4039       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4040     }
4041 })
4042
4043 (define_insn "*extend<mode>xf2_i387"
4044   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4045         (float_extend:XF
4046           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4047   "TARGET_80387"
4048   "* return output_387_reg_move (insn, operands);"
4049   [(set_attr "type" "fmov")
4050    (set_attr "mode" "<MODE>,XF")])
4051
4052 ;; %%% This seems bad bad news.
4053 ;; This cannot output into an f-reg because there is no way to be sure
4054 ;; of truncating in that case.  Otherwise this is just like a simple move
4055 ;; insn.  So we pretend we can output to a reg in order to get better
4056 ;; register preferencing, but we really use a stack slot.
4057
4058 ;; Conversion from DFmode to SFmode.
4059
4060 (define_expand "truncdfsf2"
4061   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4062         (float_truncate:SF
4063           (match_operand:DF 1 "nonimmediate_operand" "")))]
4064   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4065 {
4066   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4067     ;
4068   else if (flag_unsafe_math_optimizations)
4069     ;
4070   else
4071     {
4072       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4073       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4074       DONE;
4075     }
4076 })
4077
4078 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4079    cvtsd2ss:
4080       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4081       cvtpd2ps xmm2,xmm1
4082    We do the conversion post reload to avoid producing of 128bit spills
4083    that might lead to ICE on 32bit target.  The sequence unlikely combine
4084    anyway.  */
4085 (define_split
4086   [(set (match_operand:SF 0 "register_operand" "")
4087         (float_truncate:SF
4088           (match_operand:DF 1 "nonimmediate_operand" "")))]
4089   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size 
4090    && reload_completed && SSE_REG_P (operands[0])"
4091    [(set (match_dup 2)
4092          (vec_concat:V4SF
4093            (float_truncate:V2SF
4094              (match_dup 4))
4095            (match_dup 3)))]
4096 {
4097   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4098   operands[3] = CONST0_RTX (V2SFmode);
4099   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4100   /* Use movsd for loading from memory, unpcklpd for registers.
4101      Try to avoid move when unpacking can be done in source, or SSE3
4102      movddup is available.  */
4103   if (REG_P (operands[1]))
4104     {
4105       if (!TARGET_SSE3
4106           && true_regnum (operands[0]) != true_regnum (operands[1])
4107           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4108               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4109         {
4110           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4111           emit_move_insn (tmp, operands[1]);
4112           operands[1] = tmp;
4113         }
4114       else if (!TARGET_SSE3)
4115         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4116       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4117     }
4118   else
4119     emit_insn (gen_sse2_loadlpd (operands[4],
4120                                  CONST0_RTX (V2DFmode), operands[1]));
4121 })
4122
4123 (define_expand "truncdfsf2_with_temp"
4124   [(parallel [(set (match_operand:SF 0 "" "")
4125                    (float_truncate:SF (match_operand:DF 1 "" "")))
4126               (clobber (match_operand:SF 2 "" ""))])]
4127   "")
4128
4129 (define_insn "*truncdfsf_fast_mixed"
4130   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4131         (float_truncate:SF
4132           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4133   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4134 {
4135   switch (which_alternative)
4136     {
4137     case 0:
4138     case 1:
4139       return output_387_reg_move (insn, operands);
4140     case 2:
4141       return "cvtsd2ss\t{%1, %0|%0, %1}";
4142     default:
4143       gcc_unreachable ();
4144     }
4145 }
4146   [(set_attr "type" "fmov,fmov,ssecvt")
4147    (set_attr "mode" "SF")])
4148
4149 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4150 ;; because nothing we do here is unsafe.
4151 (define_insn "*truncdfsf_fast_sse"
4152   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4153         (float_truncate:SF
4154           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4155   "TARGET_SSE2 && TARGET_SSE_MATH"
4156   "cvtsd2ss\t{%1, %0|%0, %1}"
4157   [(set_attr "type" "ssecvt")
4158    (set_attr "mode" "SF")])
4159
4160 (define_insn "*truncdfsf_fast_i387"
4161   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4162         (float_truncate:SF
4163           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4164   "TARGET_80387 && flag_unsafe_math_optimizations"
4165   "* return output_387_reg_move (insn, operands);"
4166   [(set_attr "type" "fmov")
4167    (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncdfsf_mixed"
4170   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Yt")
4171         (float_truncate:SF
4172           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ytm")))
4173    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4174   "TARGET_MIX_SSE_I387"
4175 {
4176   switch (which_alternative)
4177     {
4178     case 0:
4179       return output_387_reg_move (insn, operands);
4180
4181     case 1:
4182       return "#";
4183     case 2:
4184       return "cvtsd2ss\t{%1, %0|%0, %1}";
4185     default:
4186       gcc_unreachable ();
4187     }
4188 }
4189   [(set_attr "type" "fmov,multi,ssecvt")
4190    (set_attr "unit" "*,i387,*")
4191    (set_attr "mode" "SF")])
4192
4193 (define_insn "*truncdfsf_i387"
4194   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4195         (float_truncate:SF
4196           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4197    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4198   "TARGET_80387"
4199 {
4200   switch (which_alternative)
4201     {
4202     case 0:
4203       return output_387_reg_move (insn, operands);
4204
4205     case 1:
4206       return "#";
4207     default:
4208       gcc_unreachable ();
4209     }
4210 }
4211   [(set_attr "type" "fmov,multi")
4212    (set_attr "unit" "*,i387")
4213    (set_attr "mode" "SF")])
4214
4215 (define_insn "*truncdfsf2_i387_1"
4216   [(set (match_operand:SF 0 "memory_operand" "=m")
4217         (float_truncate:SF
4218           (match_operand:DF 1 "register_operand" "f")))]
4219   "TARGET_80387
4220    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4221    && !TARGET_MIX_SSE_I387"
4222   "* return output_387_reg_move (insn, operands);"
4223   [(set_attr "type" "fmov")
4224    (set_attr "mode" "SF")])
4225
4226 (define_split
4227   [(set (match_operand:SF 0 "register_operand" "")
4228         (float_truncate:SF
4229          (match_operand:DF 1 "fp_register_operand" "")))
4230    (clobber (match_operand 2 "" ""))]
4231   "reload_completed"
4232   [(set (match_dup 2) (match_dup 1))
4233    (set (match_dup 0) (match_dup 2))]
4234 {
4235   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4236 })
4237
4238 ;; Conversion from XFmode to {SF,DF}mode
4239
4240 (define_expand "truncxf<mode>2"
4241   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4242                    (float_truncate:MODEF
4243                      (match_operand:XF 1 "register_operand" "")))
4244               (clobber (match_dup 2))])]
4245   "TARGET_80387"
4246 {
4247   if (flag_unsafe_math_optimizations)
4248     {
4249       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4250       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4251       if (reg != operands[0])
4252         emit_move_insn (operands[0], reg);
4253       DONE;
4254     }
4255   else
4256     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4257 })
4258
4259 (define_insn "*truncxfsf2_mixed"
4260   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4261         (float_truncate:SF
4262           (match_operand:XF 1 "register_operand" "f,f")))
4263    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4264   "TARGET_80387"
4265 {
4266   gcc_assert (!which_alternative);
4267   return output_387_reg_move (insn, operands);
4268 }
4269   [(set_attr "type" "fmov,multi")
4270    (set_attr "unit" "*,i387")
4271    (set_attr "mode" "SF")])
4272
4273 (define_insn "*truncxfdf2_mixed"
4274   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4275         (float_truncate:DF
4276           (match_operand:XF 1 "register_operand" "f,f")))
4277    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4278   "TARGET_80387"
4279 {
4280   gcc_assert (!which_alternative);
4281   return output_387_reg_move (insn, operands);
4282 }
4283   [(set_attr "type" "fmov,multi")
4284    (set_attr "unit" "*,i387")
4285    (set_attr "mode" "DF")])
4286
4287 (define_insn "truncxf<mode>2_i387_noop"
4288   [(set (match_operand:MODEF 0 "register_operand" "=f")
4289         (float_truncate:MODEF
4290           (match_operand:XF 1 "register_operand" "f")))]
4291   "TARGET_80387 && flag_unsafe_math_optimizations"
4292   "* return output_387_reg_move (insn, operands);"
4293   [(set_attr "type" "fmov")
4294    (set_attr "mode" "<MODE>")])
4295
4296 (define_insn "*truncxf<mode>2_i387"
4297   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4298         (float_truncate:MODEF
4299           (match_operand:XF 1 "register_operand" "f")))]
4300   "TARGET_80387"
4301   "* return output_387_reg_move (insn, operands);"
4302   [(set_attr "type" "fmov")
4303    (set_attr "mode" "<MODE>")])
4304
4305 (define_split
4306   [(set (match_operand:MODEF 0 "register_operand" "")
4307         (float_truncate:MODEF
4308           (match_operand:XF 1 "register_operand" "")))
4309    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4310   "TARGET_80387 && reload_completed"
4311   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4312    (set (match_dup 0) (match_dup 2))]
4313   "")
4314
4315 (define_split
4316   [(set (match_operand:MODEF 0 "memory_operand" "")
4317         (float_truncate:MODEF
4318           (match_operand:XF 1 "register_operand" "")))
4319    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4320   "TARGET_80387"
4321   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4322   "")
4323 \f
4324 ;; Signed conversion to DImode.
4325
4326 (define_expand "fix_truncxfdi2"
4327   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4328                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4329               (clobber (reg:CC FLAGS_REG))])]
4330   "TARGET_80387"
4331 {
4332   if (TARGET_FISTTP)
4333    {
4334      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4335      DONE;
4336    }
4337 })
4338
4339 (define_expand "fix_trunc<mode>di2"
4340   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4341                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4342               (clobber (reg:CC FLAGS_REG))])]
4343   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4344 {
4345   if (TARGET_FISTTP
4346       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4347    {
4348      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4349      DONE;
4350    }
4351   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4352    {
4353      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4354      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4355      if (out != operands[0])
4356         emit_move_insn (operands[0], out);
4357      DONE;
4358    }
4359 })
4360
4361 ;; Signed conversion to SImode.
4362
4363 (define_expand "fix_truncxfsi2"
4364   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4365                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4366               (clobber (reg:CC FLAGS_REG))])]
4367   "TARGET_80387"
4368 {
4369   if (TARGET_FISTTP)
4370    {
4371      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4372      DONE;
4373    }
4374 })
4375
4376 (define_expand "fix_trunc<mode>si2"
4377   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4378                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4379               (clobber (reg:CC FLAGS_REG))])]
4380   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4381 {
4382   if (TARGET_FISTTP
4383       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4384    {
4385      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4386      DONE;
4387    }
4388   if (SSE_FLOAT_MODE_P (<MODE>mode))
4389    {
4390      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4391      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4392      if (out != operands[0])
4393         emit_move_insn (operands[0], out);
4394      DONE;
4395    }
4396 })
4397
4398 ;; Signed conversion to HImode.
4399
4400 (define_expand "fix_trunc<mode>hi2"
4401   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4402                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4403               (clobber (reg:CC FLAGS_REG))])]
4404   "TARGET_80387
4405    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4406 {
4407   if (TARGET_FISTTP)
4408    {
4409      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4410      DONE;
4411    }
4412 })
4413
4414 ;; Unsigned conversion to SImode.
4415
4416 (define_expand "fixuns_trunc<mode>si2"
4417   [(parallel
4418     [(set (match_operand:SI 0 "register_operand" "")
4419           (unsigned_fix:SI
4420             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4421      (use (match_dup 2))
4422      (clobber (match_scratch:<ssevecmode> 3 ""))
4423      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4424   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4425 {
4426   enum machine_mode mode = <MODE>mode;
4427   enum machine_mode vecmode = <ssevecmode>mode;
4428   REAL_VALUE_TYPE TWO31r;
4429   rtx two31;
4430
4431   real_ldexp (&TWO31r, &dconst1, 31);
4432   two31 = const_double_from_real_value (TWO31r, mode);
4433   two31 = ix86_build_const_vector (mode, true, two31);
4434   operands[2] = force_reg (vecmode, two31);
4435 })
4436
4437 (define_insn_and_split "*fixuns_trunc<mode>_1"
4438   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4439         (unsigned_fix:SI
4440           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4441    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4442    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4443    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4444   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4445   "#"
4446   "&& reload_completed"
4447   [(const_int 0)]
4448 {
4449   ix86_split_convert_uns_si_sse (operands);
4450   DONE;
4451 })
4452
4453 ;; Unsigned conversion to HImode.
4454 ;; Without these patterns, we'll try the unsigned SI conversion which
4455 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4456
4457 (define_expand "fixuns_trunc<mode>hi2"
4458   [(set (match_dup 2)
4459         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4460    (set (match_operand:HI 0 "nonimmediate_operand" "")
4461         (subreg:HI (match_dup 2) 0))]
4462   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4463   "operands[2] = gen_reg_rtx (SImode);")
4464
4465 ;; When SSE is available, it is always faster to use it!
4466 (define_insn "fix_trunc<mode>di_sse"
4467   [(set (match_operand:DI 0 "register_operand" "=r,r")
4468         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4469   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4470    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4471   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4472   [(set_attr "type" "sseicvt")
4473    (set_attr "mode" "<MODE>")
4474    (set_attr "athlon_decode" "double,vector")
4475    (set_attr "amdfam10_decode" "double,double")])
4476
4477 (define_insn "fix_trunc<mode>si_sse"
4478   [(set (match_operand:SI 0 "register_operand" "=r,r")
4479         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4480   "SSE_FLOAT_MODE_P (<MODE>mode)
4481    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4482   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4483   [(set_attr "type" "sseicvt")
4484    (set_attr "mode" "<MODE>")
4485    (set_attr "athlon_decode" "double,vector")
4486    (set_attr "amdfam10_decode" "double,double")])
4487
4488 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4489 (define_peephole2
4490   [(set (match_operand:MODEF 0 "register_operand" "")
4491         (match_operand:MODEF 1 "memory_operand" ""))
4492    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4493         (fix:SSEMODEI24 (match_dup 0)))]
4494   "TARGET_SHORTEN_X87_SSE
4495    && peep2_reg_dead_p (2, operands[0])"
4496   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4497   "")
4498
4499 ;; Avoid vector decoded forms of the instruction.
4500 (define_peephole2
4501   [(match_scratch:DF 2 "Yt")
4502    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4503         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4504   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4505   [(set (match_dup 2) (match_dup 1))
4506    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4507   "")
4508
4509 (define_peephole2
4510   [(match_scratch:SF 2 "x")
4511    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4512         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4513   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4514   [(set (match_dup 2) (match_dup 1))
4515    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4516   "")
4517
4518 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4519   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4520         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4521   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4522    && TARGET_FISTTP
4523    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4524          && (TARGET_64BIT || <MODE>mode != DImode))
4525         && TARGET_SSE_MATH)
4526    && !(reload_completed || reload_in_progress)"
4527   "#"
4528   "&& 1"
4529   [(const_int 0)]
4530 {
4531   if (memory_operand (operands[0], VOIDmode))
4532     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4533   else
4534     {
4535       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4536       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4537                                                             operands[1],
4538                                                             operands[2]));
4539     }
4540   DONE;
4541 }
4542   [(set_attr "type" "fisttp")
4543    (set_attr "mode" "<MODE>")])
4544
4545 (define_insn "fix_trunc<mode>_i387_fisttp"
4546   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4547         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4548    (clobber (match_scratch:XF 2 "=&1f"))]
4549   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4550    && TARGET_FISTTP
4551    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4552          && (TARGET_64BIT || <MODE>mode != DImode))
4553         && TARGET_SSE_MATH)"
4554   "* return output_fix_trunc (insn, operands, 1);"
4555   [(set_attr "type" "fisttp")
4556    (set_attr "mode" "<MODE>")])
4557
4558 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4559   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4560         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4561    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4562    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4563   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564    && TARGET_FISTTP
4565    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4566         && (TARGET_64BIT || <MODE>mode != DImode))
4567         && TARGET_SSE_MATH)"
4568   "#"
4569   [(set_attr "type" "fisttp")
4570    (set_attr "mode" "<MODE>")])
4571
4572 (define_split
4573   [(set (match_operand:X87MODEI 0 "register_operand" "")
4574         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4575    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4576    (clobber (match_scratch 3 ""))]
4577   "reload_completed"
4578   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4579               (clobber (match_dup 3))])
4580    (set (match_dup 0) (match_dup 2))]
4581   "")
4582
4583 (define_split
4584   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4585         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4586    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4587    (clobber (match_scratch 3 ""))]
4588   "reload_completed"
4589   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4590               (clobber (match_dup 3))])]
4591   "")
4592
4593 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4594 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4595 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4596 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4597 ;; function in i386.c.
4598 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4599   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4600         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4601    (clobber (reg:CC FLAGS_REG))]
4602   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4603    && !TARGET_FISTTP
4604    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605          && (TARGET_64BIT || <MODE>mode != DImode))
4606    && !(reload_completed || reload_in_progress)"
4607   "#"
4608   "&& 1"
4609   [(const_int 0)]
4610 {
4611   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4612
4613   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4614   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4615   if (memory_operand (operands[0], VOIDmode))
4616     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4617                                          operands[2], operands[3]));
4618   else
4619     {
4620       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4621       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4622                                                      operands[2], operands[3],
4623                                                      operands[4]));
4624     }
4625   DONE;
4626 }
4627   [(set_attr "type" "fistp")
4628    (set_attr "i387_cw" "trunc")
4629    (set_attr "mode" "<MODE>")])
4630
4631 (define_insn "fix_truncdi_i387"
4632   [(set (match_operand:DI 0 "memory_operand" "=m")
4633         (fix:DI (match_operand 1 "register_operand" "f")))
4634    (use (match_operand:HI 2 "memory_operand" "m"))
4635    (use (match_operand:HI 3 "memory_operand" "m"))
4636    (clobber (match_scratch:XF 4 "=&1f"))]
4637   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638    && !TARGET_FISTTP
4639    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4640   "* return output_fix_trunc (insn, operands, 0);"
4641   [(set_attr "type" "fistp")
4642    (set_attr "i387_cw" "trunc")
4643    (set_attr "mode" "DI")])
4644
4645 (define_insn "fix_truncdi_i387_with_temp"
4646   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4647         (fix:DI (match_operand 1 "register_operand" "f,f")))
4648    (use (match_operand:HI 2 "memory_operand" "m,m"))
4649    (use (match_operand:HI 3 "memory_operand" "m,m"))
4650    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4651    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4652   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4653    && !TARGET_FISTTP
4654    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4655   "#"
4656   [(set_attr "type" "fistp")
4657    (set_attr "i387_cw" "trunc")
4658    (set_attr "mode" "DI")])
4659
4660 (define_split
4661   [(set (match_operand:DI 0 "register_operand" "")
4662         (fix:DI (match_operand 1 "register_operand" "")))
4663    (use (match_operand:HI 2 "memory_operand" ""))
4664    (use (match_operand:HI 3 "memory_operand" ""))
4665    (clobber (match_operand:DI 4 "memory_operand" ""))
4666    (clobber (match_scratch 5 ""))]
4667   "reload_completed"
4668   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4669               (use (match_dup 2))
4670               (use (match_dup 3))
4671               (clobber (match_dup 5))])
4672    (set (match_dup 0) (match_dup 4))]
4673   "")
4674
4675 (define_split
4676   [(set (match_operand:DI 0 "memory_operand" "")
4677         (fix:DI (match_operand 1 "register_operand" "")))
4678    (use (match_operand:HI 2 "memory_operand" ""))
4679    (use (match_operand:HI 3 "memory_operand" ""))
4680    (clobber (match_operand:DI 4 "memory_operand" ""))
4681    (clobber (match_scratch 5 ""))]
4682   "reload_completed"
4683   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4684               (use (match_dup 2))
4685               (use (match_dup 3))
4686               (clobber (match_dup 5))])]
4687   "")
4688
4689 (define_insn "fix_trunc<mode>_i387"
4690   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4691         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4692    (use (match_operand:HI 2 "memory_operand" "m"))
4693    (use (match_operand:HI 3 "memory_operand" "m"))]
4694   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4695    && !TARGET_FISTTP
4696    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4697   "* return output_fix_trunc (insn, operands, 0);"
4698   [(set_attr "type" "fistp")
4699    (set_attr "i387_cw" "trunc")
4700    (set_attr "mode" "<MODE>")])
4701
4702 (define_insn "fix_trunc<mode>_i387_with_temp"
4703   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4704         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4705    (use (match_operand:HI 2 "memory_operand" "m,m"))
4706    (use (match_operand:HI 3 "memory_operand" "m,m"))
4707    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4708   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709    && !TARGET_FISTTP
4710    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4711   "#"
4712   [(set_attr "type" "fistp")
4713    (set_attr "i387_cw" "trunc")
4714    (set_attr "mode" "<MODE>")])
4715
4716 (define_split
4717   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4718         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4719    (use (match_operand:HI 2 "memory_operand" ""))
4720    (use (match_operand:HI 3 "memory_operand" ""))
4721    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4722   "reload_completed"
4723   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4724               (use (match_dup 2))
4725               (use (match_dup 3))])
4726    (set (match_dup 0) (match_dup 4))]
4727   "")
4728
4729 (define_split
4730   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4731         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4732    (use (match_operand:HI 2 "memory_operand" ""))
4733    (use (match_operand:HI 3 "memory_operand" ""))
4734    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4735   "reload_completed"
4736   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4737               (use (match_dup 2))
4738               (use (match_dup 3))])]
4739   "")
4740
4741 (define_insn "x86_fnstcw_1"
4742   [(set (match_operand:HI 0 "memory_operand" "=m")
4743         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4744   "TARGET_80387"
4745   "fnstcw\t%0"
4746   [(set_attr "length" "2")
4747    (set_attr "mode" "HI")
4748    (set_attr "unit" "i387")])
4749
4750 (define_insn "x86_fldcw_1"
4751   [(set (reg:HI FPCR_REG)
4752         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4753   "TARGET_80387"
4754   "fldcw\t%0"
4755   [(set_attr "length" "2")
4756    (set_attr "mode" "HI")
4757    (set_attr "unit" "i387")
4758    (set_attr "athlon_decode" "vector")
4759    (set_attr "amdfam10_decode" "vector")])   
4760 \f
4761 ;; Conversion between fixed point and floating point.
4762
4763 ;; Even though we only accept memory inputs, the backend _really_
4764 ;; wants to be able to do this between registers.
4765
4766 (define_expand "floathi<mode>2"
4767   [(set (match_operand:MODEF 0 "register_operand" "")
4768         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4769   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4770 {
4771   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4772     {
4773       emit_insn
4774         (gen_floatsi<mode>2 (operands[0],
4775                              convert_to_mode (SImode, operands[1], 0)));
4776       DONE;
4777     }
4778 })
4779
4780 (define_insn "*floathi<mode>2_i387"
4781   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4782         (float:MODEF
4783           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4784   "TARGET_80387
4785    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4786        || TARGET_MIX_SSE_I387)"
4787   "@
4788    fild%z1\t%1
4789    #"
4790   [(set_attr "type" "fmov,multi")
4791    (set_attr "mode" "<MODE>")
4792    (set_attr "unit" "*,i387")
4793    (set_attr "fp_int_src" "true")])
4794
4795 (define_expand "floatsi<mode>2"
4796   [(set (match_operand:MODEF 0 "register_operand" "")
4797         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4798   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4799   "
4800    /* When we use vector converts, we can't have input in memory.  */
4801    if (GET_MODE (operands[0]) == DFmode
4802        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4803        && SSE_FLOAT_MODE_P (DFmode))
4804      operands[1] = force_reg (SImode, operands[1]);
4805    else if (GET_MODE (operands[0]) == SFmode
4806             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4807             && SSE_FLOAT_MODE_P (SFmode))
4808      {
4809        /* When !flag_trapping_math, we handle SImode->SFmode vector
4810           conversions same way as SImode->DFmode.
4811
4812           For flat_trapping_math we can't safely use vector conversion without
4813           clearing upper half, otherwise precision exception might occur.
4814           However we can still generate the common sequence converting value
4815           from general register to XMM register as:
4816
4817             mov         reg32, mem32
4818             movd        mem32, xmm
4819             cvtdq2pd xmm,xmm
4820
4821           because we know that movd clears the upper half.
4822
4823           Sadly in this case we can't rely on reload moving the value to XMM
4824           register, since we need to know if upper half is OK, so we need
4825           to do reloading by hand.  We force operand to memory unless target
4826           supports inter unit moves.  */
4827        if (!flag_trapping_math)
4828          operands[1] = force_reg (SImode, operands[1]);
4829        else if (!MEM_P (operands[1]))
4830          {
4831            rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4832            emit_move_insn (tmp, operands[1]);
4833            operands[1] = tmp;
4834          }
4835      }
4836    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4837       !TARGET_INTER_UNIT_CONVERSIONS
4838       It is neccesary for the patterns to not accept nonemmory operands
4839       as we would optimize out later.  */
4840    else if (!TARGET_INTER_UNIT_CONVERSIONS
4841             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4842             && !optimize_size
4843             && !MEM_P (operands[1]))
4844      {
4845         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
4846         emit_move_insn (tmp, operands[1]);
4847         operands[1] = tmp;
4848      }
4849   ")
4850
4851 (define_insn "*floatsisf2_mixed_vector"
4852   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4853         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4854   "TARGET_MIX_SSE_I387 && !flag_trapping_math 
4855    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4856   "@
4857    cvtdq2ps\t{%1, %0|%0, %1}
4858    fild%z1\t%1
4859    #"
4860   [(set_attr "type" "sseicvt,fmov,multi")
4861    (set_attr "mode" "SF")
4862    (set_attr "unit" "*,i387,*")
4863    (set_attr "athlon_decode" "double,*,*")
4864    (set_attr "amdfam10_decode" "double,*,*")
4865    (set_attr "fp_int_src" "false,true,true")])
4866
4867 (define_insn "*floatsisf2_mixed"
4868   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4869         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4870   "TARGET_MIX_SSE_I387
4871    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4872        || optimize_size)"
4873   "@
4874    fild%z1\t%1
4875    #
4876    cvtsi2ss\t{%1, %0|%0, %1}
4877    cvtsi2ss\t{%1, %0|%0, %1}"
4878   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4879    (set_attr "mode" "SF")
4880    (set_attr "unit" "*,i387,*,*")
4881    (set_attr "athlon_decode" "*,*,vector,double")
4882    (set_attr "amdfam10_decode" "*,*,vector,double")
4883    (set_attr "fp_int_src" "true")])
4884
4885 (define_insn "*floatsisf2_mixed_memory"
4886   [(set (match_operand:SF 0 "register_operand" "=f,x")
4887         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4888   "TARGET_MIX_SSE_I387
4889    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4890   "@
4891    fild%z1\t%1
4892    cvtsi2ss\t{%1, %0|%0, %1}"
4893   [(set_attr "type" "fmov,sseicvt")
4894    (set_attr "mode" "SF")
4895    (set_attr "athlon_decode" "*,double")
4896    (set_attr "amdfam10_decode" "*,double")
4897    (set_attr "fp_int_src" "true")])
4898
4899 (define_insn "*floatsisf2_sse_vector_nointernunit"
4900   [(set (match_operand:SF 0 "register_operand" "=x")
4901         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4902   "TARGET_SSE_MATH && flag_trapping_math
4903    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4904    && !TARGET_INTER_UNIT_MOVES"
4905   "#"
4906   [(set_attr "type" "multi")])
4907
4908 (define_insn "*floatsisf2_sse_vector_internunit"
4909   [(set (match_operand:SF 0 "register_operand" "=x,x")
4910         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4911   "TARGET_SSE_MATH && flag_trapping_math
4912    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4913    && TARGET_INTER_UNIT_MOVES"
4914   "#"
4915   [(set_attr "type" "multi")])
4916
4917 (define_split 
4918   [(set (match_operand:SF 0 "register_operand" "")
4919         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4920   "flag_trapping_math
4921    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4922    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4923    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4924   [(set (match_dup 0)
4925         (float:V4SF (match_dup 2)))]
4926 {
4927   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4928   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4929   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4930 })
4931
4932 (define_split 
4933   [(set (match_operand:SF 0 "register_operand" "")
4934         (float:SF (match_operand:SI 1 "register_operand" "")))]
4935   "flag_trapping_math
4936    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4937    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4938   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4939    (set (match_dup 0)
4940         (float:V4SF (match_dup 2)))]
4941 {
4942   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4943   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4944 })
4945
4946 (define_insn "*floatsisf2_sse_vector"
4947   [(set (match_operand:SF 0 "register_operand" "=x")
4948         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4949   "TARGET_SSE_MATH && !flag_trapping_math
4950    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4951    && !TARGET_INTER_UNIT_MOVES"
4952   "cvtdq2ps\t{%1, %0|%0, %1}"
4953   [(set_attr "type" "sseicvt")
4954    (set_attr "mode" "SF")
4955    (set_attr "athlon_decode" "double")
4956    (set_attr "amdfam10_decode" "double")
4957    (set_attr "fp_int_src" "true")])
4958
4959 (define_insn "*floatsisf2_sse"
4960   [(set (match_operand:SF 0 "register_operand" "=x,x")
4961         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4962   "TARGET_SSE_MATH
4963    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4964        || optimize_size)"
4965   "cvtsi2ss\t{%1, %0|%0, %1}"
4966   [(set_attr "type" "sseicvt")
4967    (set_attr "mode" "SF")
4968    (set_attr "athlon_decode" "vector,double")
4969    (set_attr "amdfam10_decode" "vector,double")
4970    (set_attr "fp_int_src" "true")])
4971
4972 (define_insn "*floatsisf2_sse_memory"
4973   [(set (match_operand:SF 0 "register_operand" "=x")
4974         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4975   "TARGET_SSE_MATH
4976    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4977   "cvtsi2ss\t{%1, %0|%0, %1}"
4978   [(set_attr "type" "sseicvt")
4979    (set_attr "mode" "SF")
4980    (set_attr "athlon_decode" "double")
4981    (set_attr "amdfam10_decode" "double")
4982    (set_attr "fp_int_src" "true")])
4983
4984 (define_insn "*floatsidf2_mixed_vector"
4985   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4986         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4987   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4988    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4989   "@
4990    cvtdq2pd\t{%1, %0|%0, %1}
4991    fild%z1\t%1
4992    #"
4993   [(set_attr "type" "sseicvt,fmov,multi")
4994    (set_attr "mode" "V2DF,DF,DF")
4995    (set_attr "unit" "*,*,i387")
4996    (set_attr "athlon_decode" "double,*,*")
4997    (set_attr "amdfam10_decode" "double,*,*")
4998    (set_attr "fp_int_src" "false,true,true")])
4999
5000 (define_insn "*floatsidf2_mixed"
5001   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5002         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5003   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5004    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5005        || optimize_size)"
5006   "@
5007    fild%z1\t%1
5008    #
5009    cvtsi2sd\t{%1, %0|%0, %1}
5010    cvtsi2sd\t{%1, %0|%0, %1}
5011    cvtdq2pd\t{%1, %0|%0, %1}"
5012   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5013    (set_attr "mode" "DF,DF,DF,DF,V2DF")
5014    (set_attr "unit" "*,i387,*,*,*")
5015    (set_attr "athlon_decode" "*,*,double,direct,double")
5016    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5017    (set_attr "fp_int_src" "true,true,true,true,false")])
5018
5019 (define_insn "*floatsidf2_mixed_memory"
5020   [(set (match_operand:DF 0 "register_operand" "=f,x")
5021         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5022   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5023    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5024   "@
5025    fild%z1\t%1
5026    cvtsi2sd\t{%1, %0|%0, %1}"
5027   [(set_attr "type" "fmov,sseicvt")
5028    (set_attr "mode" "DF")
5029    (set_attr "athlon_decode" "*,direct")
5030    (set_attr "amdfam10_decode" "*,double")
5031    (set_attr "fp_int_src" "true")])
5032
5033 (define_insn "*floatsidf2_sse_vector"
5034   [(set (match_operand:DF 0 "register_operand" "=x")
5035         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5036   "TARGET_SSE2 && TARGET_SSE_MATH
5037    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5038   "cvtdq2pd\t{%1, %0|%0, %1}"
5039   [(set_attr "type" "sseicvt")
5040    (set_attr "mode" "V2DF")
5041    (set_attr "athlon_decode" "double")
5042    (set_attr "amdfam10_decode" "double")
5043    (set_attr "fp_int_src" "true")])
5044
5045 (define_split 
5046   [(set (match_operand:DF 0 "register_operand" "")
5047         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5048   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5049    && SSE_REG_P (operands[0])"
5050   [(set (match_dup 0)
5051         (float:V2DF
5052           (vec_select:V2SI
5053             (match_dup 2)
5054             (parallel [(const_int 0) (const_int 1)]))))]
5055 {
5056   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5057   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5058   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5059 })
5060
5061 (define_insn "*floatsidf2_sse"
5062   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5063         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5064   "TARGET_SSE2 && TARGET_SSE_MATH
5065    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5066        || optimize_size)"
5067   "@
5068    cvtsi2sd\t{%1, %0|%0, %1}
5069    cvtsi2sd\t{%1, %0|%0, %1}
5070    cvtdq2pd\t{%1, %0|%0, %1}"
5071   [(set_attr "type" "sseicvt")
5072    (set_attr "mode" "DF,DF,V2DF")
5073    (set_attr "athlon_decode" "double,direct,double")
5074    (set_attr "amdfam10_decode" "vector,double,double")
5075    (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*floatsidf2_memory"
5078   [(set (match_operand:DF 0 "register_operand" "=x")
5079         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5080   "TARGET_SSE2 && TARGET_SSE_MATH
5081    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5082        || optimize_size)"
5083   "cvtsi2sd\t{%1, %0|%0, %1}"
5084   [(set_attr "type" "sseicvt")
5085    (set_attr "mode" "DF")
5086    (set_attr "athlon_decode" "direct")
5087    (set_attr "amdfam10_decode" "double")
5088    (set_attr "fp_int_src" "true")])
5089
5090 (define_insn "*floatsi<mode>2_i387"
5091   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5092         (float:MODEF
5093           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5094   "TARGET_80387
5095    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5096   "@
5097    fild%z1\t%1
5098    #"
5099   [(set_attr "type" "fmov,multi")
5100    (set_attr "mode" "<MODE>")
5101    (set_attr "unit" "*,i387")
5102    (set_attr "fp_int_src" "true")])
5103
5104 (define_expand "floatdisf2"
5105   [(set (match_operand:SF 0 "register_operand" "")
5106         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5107   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5108 {
5109   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5110       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5111       && !optimize_size
5112       && !MEM_P (operands[1]))
5113     {
5114         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5115         emit_move_insn (tmp, operands[1]);
5116         operands[1] = tmp;
5117     }
5118 })
5119
5120 (define_insn "*floatdisf2_mixed"
5121   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5122         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5123   "TARGET_64BIT && TARGET_MIX_SSE_I387
5124    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5125   "@
5126    fild%z1\t%1
5127    #
5128    cvtsi2ss{q}\t{%1, %0|%0, %1}
5129    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5130   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5131    (set_attr "mode" "SF")
5132    (set_attr "unit" "*,i387,*,*")
5133    (set_attr "athlon_decode" "*,*,vector,double")
5134    (set_attr "amdfam10_decode" "*,*,vector,double")
5135    (set_attr "fp_int_src" "true")])
5136
5137 (define_insn "*floatdisf2_mixed"
5138   [(set (match_operand:SF 0 "register_operand" "=f,x")
5139         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5140   "TARGET_64BIT && TARGET_MIX_SSE_I387
5141    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5142   "@
5143    fild%z1\t%1
5144    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5145   [(set_attr "type" "fmov,sseicvt")
5146    (set_attr "mode" "SF")
5147    (set_attr "athlon_decode" "*,double")
5148    (set_attr "amdfam10_decode" "*,double")
5149    (set_attr "fp_int_src" "true")])
5150
5151 (define_insn "*floatdisf2_sse"
5152   [(set (match_operand:SF 0 "register_operand" "=x,x")
5153         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5154   "TARGET_64BIT && TARGET_SSE_MATH
5155    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5156   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5157   [(set_attr "type" "sseicvt")
5158    (set_attr "mode" "SF")
5159    (set_attr "athlon_decode" "vector,double")
5160    (set_attr "amdfam10_decode" "vector,double")
5161    (set_attr "fp_int_src" "true")])
5162
5163 (define_insn "*floatdisf2_memory"
5164   [(set (match_operand:SF 0 "register_operand" "=x")
5165         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5166   "TARGET_64BIT && TARGET_SSE_MATH
5167    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5168   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5169   [(set_attr "type" "sseicvt")
5170    (set_attr "mode" "SF")
5171    (set_attr "athlon_decode" "double")
5172    (set_attr "amdfam10_decode" "double")
5173    (set_attr "fp_int_src" "true")])
5174
5175 (define_expand "floatdidf2"
5176   [(set (match_operand:DF 0 "register_operand" "")
5177         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5178   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5179 {
5180   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5181     {
5182       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5183       DONE;
5184     }
5185   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5186       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5187       && !optimize_size
5188       && !MEM_P (operands[1]))
5189     {
5190         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5191         emit_move_insn (tmp, operands[1]);
5192         operands[1] = tmp;
5193     }
5194 })
5195
5196 (define_insn "*floatdidf2_mixed"
5197   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5198         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5199   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5200    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5201   "@
5202    fild%z1\t%1
5203    #
5204    cvtsi2sd{q}\t{%1, %0|%0, %1}
5205    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5206   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5207    (set_attr "mode" "DF")
5208    (set_attr "unit" "*,i387,*,*")
5209    (set_attr "athlon_decode" "*,*,double,direct")
5210    (set_attr "amdfam10_decode" "*,*,vector,double")
5211    (set_attr "fp_int_src" "true")])
5212
5213 (define_insn "*floatdidf2_mixed_memory"
5214   [(set (match_operand:DF 0 "register_operand" "=f,x")
5215         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5216   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5217    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5218   "@
5219    fild%z1\t%1
5220    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5221   [(set_attr "type" "fmov,sseicvt")
5222    (set_attr "mode" "DF")
5223    (set_attr "athlon_decode" "*,direct")
5224    (set_attr "amdfam10_decode" "*,double")
5225    (set_attr "fp_int_src" "true")])
5226
5227 (define_insn "*floatdidf2_sse"
5228   [(set (match_operand:DF 0 "register_operand" "=x,x")
5229         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5230   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5231    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5232   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5233   [(set_attr "type" "sseicvt")
5234    (set_attr "mode" "DF")
5235    (set_attr "athlon_decode" "double,direct")
5236    (set_attr "amdfam10_decode" "vector,double")
5237    (set_attr "fp_int_src" "true")])
5238
5239 (define_insn "*floatdidf2_sse_memory"
5240   [(set (match_operand:DF 0 "register_operand" "=x")
5241         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5242   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5243    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5244   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5245   [(set_attr "type" "sseicvt")
5246    (set_attr "mode" "DF")
5247    (set_attr "athlon_decode" "direct")
5248    (set_attr "amdfam10_decode" "double")
5249    (set_attr "fp_int_src" "true")])
5250
5251 (define_insn "*floatdi<mode>2_i387"
5252   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5253         (float:MODEF
5254           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5255   "TARGET_80387
5256    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5257   "@
5258    fild%z1\t%1
5259    #"
5260   [(set_attr "type" "fmov,multi")
5261    (set_attr "mode" "<MODE>")
5262    (set_attr "unit" "*,i387")
5263    (set_attr "fp_int_src" "true")])
5264
5265 (define_insn "float<mode>xf2"
5266   [(set (match_operand:XF 0 "register_operand" "=f,f")
5267         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5268   "TARGET_80387"
5269   "@
5270    fild%z1\t%1
5271    #"
5272   [(set_attr "type" "fmov,multi")
5273    (set_attr "mode" "XF")
5274    (set_attr "unit" "*,i387")
5275    (set_attr "fp_int_src" "true")])
5276
5277 ;; %%% Kill these when reload knows how to do it.
5278 (define_split
5279   [(set (match_operand 0 "fp_register_operand" "")
5280         (float (match_operand 1 "register_operand" "")))]
5281   "reload_completed
5282    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5283   [(const_int 0)]
5284 {
5285   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5286   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5287   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5288   ix86_free_from_memory (GET_MODE (operands[1]));
5289   DONE;
5290 })
5291
5292 (define_expand "floatunssisf2"
5293   [(use (match_operand:SF 0 "register_operand" ""))
5294    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5295   "!TARGET_64BIT"
5296 {
5297   if (TARGET_SSE_MATH && TARGET_SSE2)
5298     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5299   else
5300     x86_emit_floatuns (operands);
5301   DONE;
5302 })
5303
5304 (define_expand "floatunssidf2"
5305   [(use (match_operand:DF 0 "register_operand" ""))
5306    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5307   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5308   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5309
5310 (define_expand "floatunsdisf2"
5311   [(use (match_operand:SF 0 "register_operand" ""))
5312    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5313   "TARGET_64BIT && TARGET_SSE_MATH"
5314   "x86_emit_floatuns (operands); DONE;")
5315
5316 (define_expand "floatunsdidf2"
5317   [(use (match_operand:DF 0 "register_operand" ""))
5318    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5319   "TARGET_SSE_MATH && TARGET_SSE2
5320    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5321 {
5322   if (TARGET_64BIT)
5323     x86_emit_floatuns (operands);
5324   else
5325     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5326   DONE;
5327 })
5328 \f
5329 ;; Add instructions
5330
5331 ;; %%% splits for addditi3
5332
5333 (define_expand "addti3"
5334   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5335         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5336                  (match_operand:TI 2 "x86_64_general_operand" "")))
5337    (clobber (reg:CC FLAGS_REG))]
5338   "TARGET_64BIT"
5339   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5340
5341 (define_insn "*addti3_1"
5342   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5343         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5344                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5345    (clobber (reg:CC FLAGS_REG))]
5346   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5347   "#")
5348
5349 (define_split
5350   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5351         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5352                  (match_operand:TI 2 "x86_64_general_operand" "")))
5353    (clobber (reg:CC FLAGS_REG))]
5354   "TARGET_64BIT && reload_completed"
5355   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5356                                           UNSPEC_ADD_CARRY))
5357               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5358    (parallel [(set (match_dup 3)
5359                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5360                                      (match_dup 4))
5361                             (match_dup 5)))
5362               (clobber (reg:CC FLAGS_REG))])]
5363   "split_ti (operands+0, 1, operands+0, operands+3);
5364    split_ti (operands+1, 1, operands+1, operands+4);
5365    split_ti (operands+2, 1, operands+2, operands+5);")
5366
5367 ;; %%% splits for addsidi3
5368 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5369 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5370 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5371
5372 (define_expand "adddi3"
5373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5374         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5375                  (match_operand:DI 2 "x86_64_general_operand" "")))
5376    (clobber (reg:CC FLAGS_REG))]
5377   ""
5378   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5379
5380 (define_insn "*adddi3_1"
5381   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5382         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5383                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5384    (clobber (reg:CC FLAGS_REG))]
5385   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5386   "#")
5387
5388 (define_split
5389   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5390         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5391                  (match_operand:DI 2 "general_operand" "")))
5392    (clobber (reg:CC FLAGS_REG))]
5393   "!TARGET_64BIT && reload_completed"
5394   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5395                                           UNSPEC_ADD_CARRY))
5396               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5397    (parallel [(set (match_dup 3)
5398                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5399                                      (match_dup 4))
5400                             (match_dup 5)))
5401               (clobber (reg:CC FLAGS_REG))])]
5402   "split_di (operands+0, 1, operands+0, operands+3);
5403    split_di (operands+1, 1, operands+1, operands+4);
5404    split_di (operands+2, 1, operands+2, operands+5);")
5405
5406 (define_insn "adddi3_carry_rex64"
5407   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5408           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5409                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5410                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5411    (clobber (reg:CC FLAGS_REG))]
5412   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5413   "adc{q}\t{%2, %0|%0, %2}"
5414   [(set_attr "type" "alu")
5415    (set_attr "pent_pair" "pu")
5416    (set_attr "mode" "DI")])
5417
5418 (define_insn "*adddi3_cc_rex64"
5419   [(set (reg:CC FLAGS_REG)
5420         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5421                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5422                    UNSPEC_ADD_CARRY))
5423    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5424         (plus:DI (match_dup 1) (match_dup 2)))]
5425   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5426   "add{q}\t{%2, %0|%0, %2}"
5427   [(set_attr "type" "alu")
5428    (set_attr "mode" "DI")])
5429
5430 (define_insn "*<addsub><mode>3_cc_overflow"
5431   [(set (reg:CCC FLAGS_REG)
5432         (compare:CCC
5433             (plusminus:SWI
5434                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5435                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5436             (match_dup 1)))
5437    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5438         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5439   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5440   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "<MODE>")])
5443
5444 (define_insn "*add<mode>3_cconly_overflow"
5445   [(set (reg:CCC FLAGS_REG)
5446         (compare:CCC
5447                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5448                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5449                 (match_dup 1)))
5450    (clobber (match_scratch:SWI 0 "=<r>"))]
5451   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5452   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5453   [(set_attr "type" "alu")
5454    (set_attr "mode" "<MODE>")])
5455
5456 (define_insn "*sub<mode>3_cconly_overflow"
5457   [(set (reg:CCC FLAGS_REG)
5458         (compare:CCC
5459              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5460                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5461              (match_dup 0)))]
5462   ""
5463   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5464   [(set_attr "type" "icmp")
5465    (set_attr "mode" "<MODE>")])
5466
5467 (define_insn "*<addsub>si3_zext_cc_overflow"
5468   [(set (reg:CCC FLAGS_REG)
5469         (compare:CCC
5470             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5471                           (match_operand:SI 2 "general_operand" "g"))
5472             (match_dup 1)))
5473    (set (match_operand:DI 0 "register_operand" "=r")
5474         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5475   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5476   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5477   [(set_attr "type" "alu")
5478    (set_attr "mode" "SI")])
5479
5480 (define_insn "addqi3_carry"
5481   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5482           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5483                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5484                    (match_operand:QI 2 "general_operand" "qi,qm")))
5485    (clobber (reg:CC FLAGS_REG))]
5486   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5487   "adc{b}\t{%2, %0|%0, %2}"
5488   [(set_attr "type" "alu")
5489    (set_attr "pent_pair" "pu")
5490    (set_attr "mode" "QI")])
5491
5492 (define_insn "addhi3_carry"
5493   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5494           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5495                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5496                    (match_operand:HI 2 "general_operand" "ri,rm")))
5497    (clobber (reg:CC FLAGS_REG))]
5498   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5499   "adc{w}\t{%2, %0|%0, %2}"
5500   [(set_attr "type" "alu")
5501    (set_attr "pent_pair" "pu")
5502    (set_attr "mode" "HI")])
5503
5504 (define_insn "addsi3_carry"
5505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5506           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5507                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5508                    (match_operand:SI 2 "general_operand" "ri,rm")))
5509    (clobber (reg:CC FLAGS_REG))]
5510   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5511   "adc{l}\t{%2, %0|%0, %2}"
5512   [(set_attr "type" "alu")
5513    (set_attr "pent_pair" "pu")
5514    (set_attr "mode" "SI")])
5515
5516 (define_insn "*addsi3_carry_zext"
5517   [(set (match_operand:DI 0 "register_operand" "=r")
5518           (zero_extend:DI
5519             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5520                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5521                      (match_operand:SI 2 "general_operand" "g"))))
5522    (clobber (reg:CC FLAGS_REG))]
5523   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5524   "adc{l}\t{%2, %k0|%k0, %2}"
5525   [(set_attr "type" "alu")
5526    (set_attr "pent_pair" "pu")
5527    (set_attr "mode" "SI")])
5528
5529 (define_insn "*addsi3_cc"
5530   [(set (reg:CC FLAGS_REG)
5531         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5532                     (match_operand:SI 2 "general_operand" "ri,rm")]
5533                    UNSPEC_ADD_CARRY))
5534    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5535         (plus:SI (match_dup 1) (match_dup 2)))]
5536   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5537   "add{l}\t{%2, %0|%0, %2}"
5538   [(set_attr "type" "alu")
5539    (set_attr "mode" "SI")])
5540
5541 (define_insn "addqi3_cc"
5542   [(set (reg:CC FLAGS_REG)
5543         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5544                     (match_operand:QI 2 "general_operand" "qi,qm")]
5545                    UNSPEC_ADD_CARRY))
5546    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5547         (plus:QI (match_dup 1) (match_dup 2)))]
5548   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5549   "add{b}\t{%2, %0|%0, %2}"
5550   [(set_attr "type" "alu")
5551    (set_attr "mode" "QI")])
5552
5553 (define_expand "addsi3"
5554   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5555                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5556                             (match_operand:SI 2 "general_operand" "")))
5557               (clobber (reg:CC FLAGS_REG))])]
5558   ""
5559   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5560
5561 (define_insn "*lea_1"
5562   [(set (match_operand:SI 0 "register_operand" "=r")
5563         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5564   "!TARGET_64BIT"
5565   "lea{l}\t{%a1, %0|%0, %a1}"
5566   [(set_attr "type" "lea")
5567    (set_attr "mode" "SI")])
5568
5569 (define_insn "*lea_1_rex64"
5570   [(set (match_operand:SI 0 "register_operand" "=r")
5571         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5572   "TARGET_64BIT"
5573   "lea{l}\t{%a1, %0|%0, %a1}"
5574   [(set_attr "type" "lea")
5575    (set_attr "mode" "SI")])
5576
5577 (define_insn "*lea_1_zext"
5578   [(set (match_operand:DI 0 "register_operand" "=r")
5579         (zero_extend:DI
5580          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5581   "TARGET_64BIT"
5582   "lea{l}\t{%a1, %k0|%k0, %a1}"
5583   [(set_attr "type" "lea")
5584    (set_attr "mode" "SI")])
5585
5586 (define_insn "*lea_2_rex64"
5587   [(set (match_operand:DI 0 "register_operand" "=r")
5588         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5589   "TARGET_64BIT"
5590   "lea{q}\t{%a1, %0|%0, %a1}"
5591   [(set_attr "type" "lea")
5592    (set_attr "mode" "DI")])
5593
5594 ;; The lea patterns for non-Pmodes needs to be matched by several
5595 ;; insns converted to real lea by splitters.
5596
5597 (define_insn_and_split "*lea_general_1"
5598   [(set (match_operand 0 "register_operand" "=r")
5599         (plus (plus (match_operand 1 "index_register_operand" "l")
5600                     (match_operand 2 "register_operand" "r"))
5601               (match_operand 3 "immediate_operand" "i")))]
5602   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5603     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5604    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5605    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5606    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5607    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5608        || GET_MODE (operands[3]) == VOIDmode)"
5609   "#"
5610   "&& reload_completed"
5611   [(const_int 0)]
5612 {
5613   rtx pat;
5614   operands[0] = gen_lowpart (SImode, operands[0]);
5615   operands[1] = gen_lowpart (Pmode, operands[1]);
5616   operands[2] = gen_lowpart (Pmode, operands[2]);
5617   operands[3] = gen_lowpart (Pmode, operands[3]);
5618   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5619                       operands[3]);
5620   if (Pmode != SImode)
5621     pat = gen_rtx_SUBREG (SImode, pat, 0);
5622   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5623   DONE;
5624 }
5625   [(set_attr "type" "lea")
5626    (set_attr "mode" "SI")])
5627
5628 (define_insn_and_split "*lea_general_1_zext"
5629   [(set (match_operand:DI 0 "register_operand" "=r")
5630         (zero_extend:DI
5631           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5632                             (match_operand:SI 2 "register_operand" "r"))
5633                    (match_operand:SI 3 "immediate_operand" "i"))))]
5634   "TARGET_64BIT"
5635   "#"
5636   "&& reload_completed"
5637   [(set (match_dup 0)
5638         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5639                                                      (match_dup 2))
5640                                             (match_dup 3)) 0)))]
5641 {
5642   operands[1] = gen_lowpart (Pmode, operands[1]);
5643   operands[2] = gen_lowpart (Pmode, operands[2]);
5644   operands[3] = gen_lowpart (Pmode, operands[3]);
5645 }
5646   [(set_attr "type" "lea")
5647    (set_attr "mode" "SI")])
5648
5649 (define_insn_and_split "*lea_general_2"
5650   [(set (match_operand 0 "register_operand" "=r")
5651         (plus (mult (match_operand 1 "index_register_operand" "l")
5652                     (match_operand 2 "const248_operand" "i"))
5653               (match_operand 3 "nonmemory_operand" "ri")))]
5654   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5655     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5656    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5657    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5658    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5659        || GET_MODE (operands[3]) == VOIDmode)"
5660   "#"
5661   "&& reload_completed"
5662   [(const_int 0)]
5663 {
5664   rtx pat;
5665   operands[0] = gen_lowpart (SImode, operands[0]);
5666   operands[1] = gen_lowpart (Pmode, operands[1]);
5667   operands[3] = gen_lowpart (Pmode, operands[3]);
5668   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5669                       operands[3]);
5670   if (Pmode != SImode)
5671     pat = gen_rtx_SUBREG (SImode, pat, 0);
5672   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5673   DONE;
5674 }
5675   [(set_attr "type" "lea")
5676    (set_attr "mode" "SI")])
5677
5678 (define_insn_and_split "*lea_general_2_zext"
5679   [(set (match_operand:DI 0 "register_operand" "=r")
5680         (zero_extend:DI
5681           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5682                             (match_operand:SI 2 "const248_operand" "n"))
5683                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5684   "TARGET_64BIT"
5685   "#"
5686   "&& reload_completed"
5687   [(set (match_dup 0)
5688         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5689                                                      (match_dup 2))
5690                                             (match_dup 3)) 0)))]
5691 {
5692   operands[1] = gen_lowpart (Pmode, operands[1]);
5693   operands[3] = gen_lowpart (Pmode, operands[3]);
5694 }
5695   [(set_attr "type" "lea")
5696    (set_attr "mode" "SI")])
5697
5698 (define_insn_and_split "*lea_general_3"
5699   [(set (match_operand 0 "register_operand" "=r")
5700         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5701                           (match_operand 2 "const248_operand" "i"))
5702                     (match_operand 3 "register_operand" "r"))
5703               (match_operand 4 "immediate_operand" "i")))]
5704   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5705     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5706    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5707    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5708    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5709   "#"
5710   "&& reload_completed"
5711   [(const_int 0)]
5712 {
5713   rtx pat;
5714   operands[0] = gen_lowpart (SImode, operands[0]);
5715   operands[1] = gen_lowpart (Pmode, operands[1]);
5716   operands[3] = gen_lowpart (Pmode, operands[3]);
5717   operands[4] = gen_lowpart (Pmode, operands[4]);
5718   pat = gen_rtx_PLUS (Pmode,
5719                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5720                                                          operands[2]),
5721                                     operands[3]),
5722                       operands[4]);
5723   if (Pmode != SImode)
5724     pat = gen_rtx_SUBREG (SImode, pat, 0);
5725   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5726   DONE;
5727 }
5728   [(set_attr "type" "lea")
5729    (set_attr "mode" "SI")])
5730
5731 (define_insn_and_split "*lea_general_3_zext"
5732   [(set (match_operand:DI 0 "register_operand" "=r")
5733         (zero_extend:DI
5734           (plus:SI (plus:SI (mult:SI
5735                               (match_operand:SI 1 "index_register_operand" "l")
5736                               (match_operand:SI 2 "const248_operand" "n"))
5737                             (match_operand:SI 3 "register_operand" "r"))
5738                    (match_operand:SI 4 "immediate_operand" "i"))))]
5739   "TARGET_64BIT"
5740   "#"
5741   "&& reload_completed"
5742   [(set (match_dup 0)
5743         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5744                                                               (match_dup 2))
5745                                                      (match_dup 3))
5746                                             (match_dup 4)) 0)))]
5747 {
5748   operands[1] = gen_lowpart (Pmode, operands[1]);
5749   operands[3] = gen_lowpart (Pmode, operands[3]);
5750   operands[4] = gen_lowpart (Pmode, operands[4]);
5751 }
5752   [(set_attr "type" "lea")
5753    (set_attr "mode" "SI")])
5754
5755 (define_insn "*adddi_1_rex64"
5756   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5757         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5758                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5759    (clobber (reg:CC FLAGS_REG))]
5760   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5761 {
5762   switch (get_attr_type (insn))
5763     {
5764     case TYPE_LEA:
5765       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5766       return "lea{q}\t{%a2, %0|%0, %a2}";
5767
5768     case TYPE_INCDEC:
5769       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5770       if (operands[2] == const1_rtx)
5771         return "inc{q}\t%0";
5772       else
5773         {
5774           gcc_assert (operands[2] == constm1_rtx);
5775           return "dec{q}\t%0";
5776         }
5777
5778     default:
5779       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5780
5781       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5782          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5783       if (CONST_INT_P (operands[2])
5784           /* Avoid overflows.  */
5785           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5786           && (INTVAL (operands[2]) == 128
5787               || (INTVAL (operands[2]) < 0
5788                   && INTVAL (operands[2]) != -128)))
5789         {
5790           operands[2] = GEN_INT (-INTVAL (operands[2]));
5791           return "sub{q}\t{%2, %0|%0, %2}";
5792         }
5793       return "add{q}\t{%2, %0|%0, %2}";
5794     }
5795 }
5796   [(set (attr "type")
5797      (cond [(eq_attr "alternative" "2")
5798               (const_string "lea")
5799             ; Current assemblers are broken and do not allow @GOTOFF in
5800             ; ought but a memory context.
5801             (match_operand:DI 2 "pic_symbolic_operand" "")
5802               (const_string "lea")
5803             (match_operand:DI 2 "incdec_operand" "")
5804               (const_string "incdec")
5805            ]
5806            (const_string "alu")))
5807    (set_attr "mode" "DI")])
5808
5809 ;; Convert lea to the lea pattern to avoid flags dependency.
5810 (define_split
5811   [(set (match_operand:DI 0 "register_operand" "")
5812         (plus:DI (match_operand:DI 1 "register_operand" "")
5813                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "TARGET_64BIT && reload_completed
5816    && true_regnum (operands[0]) != true_regnum (operands[1])"
5817   [(set (match_dup 0)
5818         (plus:DI (match_dup 1)
5819                  (match_dup 2)))]
5820   "")
5821
5822 (define_insn "*adddi_2_rex64"
5823   [(set (reg FLAGS_REG)
5824         (compare
5825           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5826                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5827           (const_int 0)))
5828    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5829         (plus:DI (match_dup 1) (match_dup 2)))]
5830   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5831    && ix86_binary_operator_ok (PLUS, DImode, operands)
5832    /* Current assemblers are broken and do not allow @GOTOFF in
5833       ought but a memory context.  */
5834    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5835 {
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840       if (operands[2] == const1_rtx)
5841         return "inc{q}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return "dec{q}\t%0";
5846         }
5847
5848     default:
5849       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5850       /* ???? We ought to handle there the 32bit case too
5851          - do we need new constraint?  */
5852       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5853          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5854       if (CONST_INT_P (operands[2])
5855           /* Avoid overflows.  */
5856           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5857           && (INTVAL (operands[2]) == 128
5858               || (INTVAL (operands[2]) < 0
5859                   && INTVAL (operands[2]) != -128)))
5860         {
5861           operands[2] = GEN_INT (-INTVAL (operands[2]));
5862           return "sub{q}\t{%2, %0|%0, %2}";
5863         }
5864       return "add{q}\t{%2, %0|%0, %2}";
5865     }
5866 }
5867   [(set (attr "type")
5868      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5869         (const_string "incdec")
5870         (const_string "alu")))
5871    (set_attr "mode" "DI")])
5872
5873 (define_insn "*adddi_3_rex64"
5874   [(set (reg FLAGS_REG)
5875         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5876                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5877    (clobber (match_scratch:DI 0 "=r"))]
5878   "TARGET_64BIT
5879    && ix86_match_ccmode (insn, CCZmode)
5880    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5881    /* Current assemblers are broken and do not allow @GOTOFF in
5882       ought but a memory context.  */
5883    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5884 {
5885   switch (get_attr_type (insn))
5886     {
5887     case TYPE_INCDEC:
5888       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5889       if (operands[2] == const1_rtx)
5890         return "inc{q}\t%0";
5891       else
5892         {
5893           gcc_assert (operands[2] == constm1_rtx);
5894           return "dec{q}\t%0";
5895         }
5896
5897     default:
5898       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5899       /* ???? We ought to handle there the 32bit case too
5900          - do we need new constraint?  */
5901       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5902          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5903       if (CONST_INT_P (operands[2])
5904           /* Avoid overflows.  */
5905           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5906           && (INTVAL (operands[2]) == 128
5907               || (INTVAL (operands[2]) < 0
5908                   && INTVAL (operands[2]) != -128)))
5909         {
5910           operands[2] = GEN_INT (-INTVAL (operands[2]));
5911           return "sub{q}\t{%2, %0|%0, %2}";
5912         }
5913       return "add{q}\t{%2, %0|%0, %2}";
5914     }
5915 }
5916   [(set (attr "type")
5917      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5918         (const_string "incdec")
5919         (const_string "alu")))
5920    (set_attr "mode" "DI")])
5921
5922 ; For comparisons against 1, -1 and 128, we may generate better code
5923 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5924 ; is matched then.  We can't accept general immediate, because for
5925 ; case of overflows,  the result is messed up.
5926 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5927 ; when negated.
5928 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5929 ; only for comparisons not depending on it.
5930 (define_insn "*adddi_4_rex64"
5931   [(set (reg FLAGS_REG)
5932         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5933                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5934    (clobber (match_scratch:DI 0 "=rm"))]
5935   "TARGET_64BIT
5936    &&  ix86_match_ccmode (insn, CCGCmode)"
5937 {
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == constm1_rtx)
5942         return "inc{q}\t%0";
5943       else
5944         {
5945           gcc_assert (operands[2] == const1_rtx);
5946           return "dec{q}\t%0";
5947         }
5948
5949     default:
5950       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5951       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5953       if ((INTVAL (operands[2]) == -128
5954            || (INTVAL (operands[2]) > 0
5955                && INTVAL (operands[2]) != 128))
5956           /* Avoid overflows.  */
5957           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5958         return "sub{q}\t{%2, %0|%0, %2}";
5959       operands[2] = GEN_INT (-INTVAL (operands[2]));
5960       return "add{q}\t{%2, %0|%0, %2}";
5961     }
5962 }
5963   [(set (attr "type")
5964      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5965         (const_string "incdec")
5966         (const_string "alu")))
5967    (set_attr "mode" "DI")])
5968
5969 (define_insn "*adddi_5_rex64"
5970   [(set (reg FLAGS_REG)
5971         (compare
5972           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5973                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5974           (const_int 0)))
5975    (clobber (match_scratch:DI 0 "=r"))]
5976   "TARGET_64BIT
5977    && ix86_match_ccmode (insn, CCGOCmode)
5978    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5979    /* Current assemblers are broken and do not allow @GOTOFF in
5980       ought but a memory context.  */
5981    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5982 {
5983   switch (get_attr_type (insn))
5984     {
5985     case TYPE_INCDEC:
5986       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5987       if (operands[2] == const1_rtx)
5988         return "inc{q}\t%0";
5989       else
5990         {
5991           gcc_assert (operands[2] == constm1_rtx);
5992           return "dec{q}\t%0";
5993         }
5994
5995     default:
5996       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5999       if (CONST_INT_P (operands[2])
6000           /* Avoid overflows.  */
6001           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6002           && (INTVAL (operands[2]) == 128
6003               || (INTVAL (operands[2]) < 0
6004                   && INTVAL (operands[2]) != -128)))
6005         {
6006           operands[2] = GEN_INT (-INTVAL (operands[2]));
6007           return "sub{q}\t{%2, %0|%0, %2}";
6008         }
6009       return "add{q}\t{%2, %0|%0, %2}";
6010     }
6011 }
6012   [(set (attr "type")
6013      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6014         (const_string "incdec")
6015         (const_string "alu")))
6016    (set_attr "mode" "DI")])
6017
6018
6019 (define_insn "*addsi_1"
6020   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6021         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6022                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6023    (clobber (reg:CC FLAGS_REG))]
6024   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6025 {
6026   switch (get_attr_type (insn))
6027     {
6028     case TYPE_LEA:
6029       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6030       return "lea{l}\t{%a2, %0|%0, %a2}";
6031
6032     case TYPE_INCDEC:
6033       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6034       if (operands[2] == const1_rtx)
6035         return "inc{l}\t%0";
6036       else
6037         {
6038           gcc_assert (operands[2] == constm1_rtx);
6039           return "dec{l}\t%0";
6040         }
6041
6042     default:
6043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6044
6045       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6047       if (CONST_INT_P (operands[2])
6048           && (INTVAL (operands[2]) == 128
6049               || (INTVAL (operands[2]) < 0
6050                   && INTVAL (operands[2]) != -128)))
6051         {
6052           operands[2] = GEN_INT (-INTVAL (operands[2]));
6053           return "sub{l}\t{%2, %0|%0, %2}";
6054         }
6055       return "add{l}\t{%2, %0|%0, %2}";
6056     }
6057 }
6058   [(set (attr "type")
6059      (cond [(eq_attr "alternative" "2")
6060               (const_string "lea")
6061             ; Current assemblers are broken and do not allow @GOTOFF in
6062             ; ought but a memory context.
6063             (match_operand:SI 2 "pic_symbolic_operand" "")
6064               (const_string "lea")
6065             (match_operand:SI 2 "incdec_operand" "")
6066               (const_string "incdec")
6067            ]
6068            (const_string "alu")))
6069    (set_attr "mode" "SI")])
6070
6071 ;; Convert lea to the lea pattern to avoid flags dependency.
6072 (define_split
6073   [(set (match_operand 0 "register_operand" "")
6074         (plus (match_operand 1 "register_operand" "")
6075               (match_operand 2 "nonmemory_operand" "")))
6076    (clobber (reg:CC FLAGS_REG))]
6077   "reload_completed
6078    && true_regnum (operands[0]) != true_regnum (operands[1])"
6079   [(const_int 0)]
6080 {
6081   rtx pat;
6082   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6083      may confuse gen_lowpart.  */
6084   if (GET_MODE (operands[0]) != Pmode)
6085     {
6086       operands[1] = gen_lowpart (Pmode, operands[1]);
6087       operands[2] = gen_lowpart (Pmode, operands[2]);
6088     }
6089   operands[0] = gen_lowpart (SImode, operands[0]);
6090   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6091   if (Pmode != SImode)
6092     pat = gen_rtx_SUBREG (SImode, pat, 0);
6093   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6094   DONE;
6095 })
6096
6097 ;; It may seem that nonimmediate operand is proper one for operand 1.
6098 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6099 ;; we take care in ix86_binary_operator_ok to not allow two memory
6100 ;; operands so proper swapping will be done in reload.  This allow
6101 ;; patterns constructed from addsi_1 to match.
6102 (define_insn "addsi_1_zext"
6103   [(set (match_operand:DI 0 "register_operand" "=r,r")
6104         (zero_extend:DI
6105           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6106                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6107    (clobber (reg:CC FLAGS_REG))]
6108   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6109 {
6110   switch (get_attr_type (insn))
6111     {
6112     case TYPE_LEA:
6113       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6114       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6115
6116     case TYPE_INCDEC:
6117       if (operands[2] == const1_rtx)
6118         return "inc{l}\t%k0";
6119       else
6120         {
6121           gcc_assert (operands[2] == constm1_rtx);
6122           return "dec{l}\t%k0";
6123         }
6124
6125     default:
6126       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6127          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6128       if (CONST_INT_P (operands[2])
6129           && (INTVAL (operands[2]) == 128
6130               || (INTVAL (operands[2]) < 0
6131                   && INTVAL (operands[2]) != -128)))
6132         {
6133           operands[2] = GEN_INT (-INTVAL (operands[2]));
6134           return "sub{l}\t{%2, %k0|%k0, %2}";
6135         }
6136       return "add{l}\t{%2, %k0|%k0, %2}";
6137     }
6138 }
6139   [(set (attr "type")
6140      (cond [(eq_attr "alternative" "1")
6141               (const_string "lea")
6142             ; Current assemblers are broken and do not allow @GOTOFF in
6143             ; ought but a memory context.
6144             (match_operand:SI 2 "pic_symbolic_operand" "")
6145               (const_string "lea")
6146             (match_operand:SI 2 "incdec_operand" "")
6147               (const_string "incdec")
6148            ]
6149            (const_string "alu")))
6150    (set_attr "mode" "SI")])
6151
6152 ;; Convert lea to the lea pattern to avoid flags dependency.
6153 (define_split
6154   [(set (match_operand:DI 0 "register_operand" "")
6155         (zero_extend:DI
6156           (plus:SI (match_operand:SI 1 "register_operand" "")
6157                    (match_operand:SI 2 "nonmemory_operand" ""))))
6158    (clobber (reg:CC FLAGS_REG))]
6159   "TARGET_64BIT && reload_completed
6160    && true_regnum (operands[0]) != true_regnum (operands[1])"
6161   [(set (match_dup 0)
6162         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6163 {
6164   operands[1] = gen_lowpart (Pmode, operands[1]);
6165   operands[2] = gen_lowpart (Pmode, operands[2]);
6166 })
6167
6168 (define_insn "*addsi_2"
6169   [(set (reg FLAGS_REG)
6170         (compare
6171           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6172                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6173           (const_int 0)))
6174    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6175         (plus:SI (match_dup 1) (match_dup 2)))]
6176   "ix86_match_ccmode (insn, CCGOCmode)
6177    && ix86_binary_operator_ok (PLUS, SImode, operands)
6178    /* Current assemblers are broken and do not allow @GOTOFF in
6179       ought but a memory context.  */
6180    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6181 {
6182   switch (get_attr_type (insn))
6183     {
6184     case TYPE_INCDEC:
6185       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6186       if (operands[2] == const1_rtx)
6187         return "inc{l}\t%0";
6188       else
6189         {
6190           gcc_assert (operands[2] == constm1_rtx);
6191           return "dec{l}\t%0";
6192         }
6193
6194     default:
6195       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6196       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6197          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6198       if (CONST_INT_P (operands[2])
6199           && (INTVAL (operands[2]) == 128
6200               || (INTVAL (operands[2]) < 0
6201                   && INTVAL (operands[2]) != -128)))
6202         {
6203           operands[2] = GEN_INT (-INTVAL (operands[2]));
6204           return "sub{l}\t{%2, %0|%0, %2}";
6205         }
6206       return "add{l}\t{%2, %0|%0, %2}";
6207     }
6208 }
6209   [(set (attr "type")
6210      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6211         (const_string "incdec")
6212         (const_string "alu")))
6213    (set_attr "mode" "SI")])
6214
6215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6216 (define_insn "*addsi_2_zext"
6217   [(set (reg FLAGS_REG)
6218         (compare
6219           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6220                    (match_operand:SI 2 "general_operand" "rmni"))
6221           (const_int 0)))
6222    (set (match_operand:DI 0 "register_operand" "=r")
6223         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6224   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6225    && ix86_binary_operator_ok (PLUS, SImode, operands)
6226    /* Current assemblers are broken and do not allow @GOTOFF in
6227       ought but a memory context.  */
6228    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6229 {
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       if (operands[2] == const1_rtx)
6234         return "inc{l}\t%k0";
6235       else
6236         {
6237           gcc_assert (operands[2] == constm1_rtx);
6238           return "dec{l}\t%k0";
6239         }
6240
6241     default:
6242       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6243          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6244       if (CONST_INT_P (operands[2])
6245           && (INTVAL (operands[2]) == 128
6246               || (INTVAL (operands[2]) < 0
6247                   && INTVAL (operands[2]) != -128)))
6248         {
6249           operands[2] = GEN_INT (-INTVAL (operands[2]));
6250           return "sub{l}\t{%2, %k0|%k0, %2}";
6251         }
6252       return "add{l}\t{%2, %k0|%k0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6257         (const_string "incdec")
6258         (const_string "alu")))
6259    (set_attr "mode" "SI")])
6260
6261 (define_insn "*addsi_3"
6262   [(set (reg FLAGS_REG)
6263         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6264                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6265    (clobber (match_scratch:SI 0 "=r"))]
6266   "ix86_match_ccmode (insn, CCZmode)
6267    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6268    /* Current assemblers are broken and do not allow @GOTOFF in
6269       ought but a memory context.  */
6270    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6271 {
6272   switch (get_attr_type (insn))
6273     {
6274     case TYPE_INCDEC:
6275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276       if (operands[2] == const1_rtx)
6277         return "inc{l}\t%0";
6278       else
6279         {
6280           gcc_assert (operands[2] == constm1_rtx);
6281           return "dec{l}\t%0";
6282         }
6283
6284     default:
6285       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6286       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6287          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6288       if (CONST_INT_P (operands[2])
6289           && (INTVAL (operands[2]) == 128
6290               || (INTVAL (operands[2]) < 0
6291                   && INTVAL (operands[2]) != -128)))
6292         {
6293           operands[2] = GEN_INT (-INTVAL (operands[2]));
6294           return "sub{l}\t{%2, %0|%0, %2}";
6295         }
6296       return "add{l}\t{%2, %0|%0, %2}";
6297     }
6298 }
6299   [(set (attr "type")
6300      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6301         (const_string "incdec")
6302         (const_string "alu")))
6303    (set_attr "mode" "SI")])
6304
6305 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6306 (define_insn "*addsi_3_zext"
6307   [(set (reg FLAGS_REG)
6308         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6309                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6310    (set (match_operand:DI 0 "register_operand" "=r")
6311         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6312   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6313    && ix86_binary_operator_ok (PLUS, SImode, operands)
6314    /* Current assemblers are broken and do not allow @GOTOFF in
6315       ought but a memory context.  */
6316    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6317 {
6318   switch (get_attr_type (insn))
6319     {
6320     case TYPE_INCDEC:
6321       if (operands[2] == const1_rtx)
6322         return "inc{l}\t%k0";
6323       else
6324         {
6325           gcc_assert (operands[2] == constm1_rtx);
6326           return "dec{l}\t%k0";
6327         }
6328
6329     default:
6330       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6331          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6332       if (CONST_INT_P (operands[2])
6333           && (INTVAL (operands[2]) == 128
6334               || (INTVAL (operands[2]) < 0
6335                   && INTVAL (operands[2]) != -128)))
6336         {
6337           operands[2] = GEN_INT (-INTVAL (operands[2]));
6338           return "sub{l}\t{%2, %k0|%k0, %2}";
6339         }
6340       return "add{l}\t{%2, %k0|%k0, %2}";
6341     }
6342 }
6343   [(set (attr "type")
6344      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6345         (const_string "incdec")
6346         (const_string "alu")))
6347    (set_attr "mode" "SI")])
6348
6349 ; For comparisons against 1, -1 and 128, we may generate better code
6350 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6351 ; is matched then.  We can't accept general immediate, because for
6352 ; case of overflows,  the result is messed up.
6353 ; This pattern also don't hold of 0x80000000, since the value overflows
6354 ; when negated.
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6357 (define_insn "*addsi_4"
6358   [(set (reg FLAGS_REG)
6359         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6360                  (match_operand:SI 2 "const_int_operand" "n")))
6361    (clobber (match_scratch:SI 0 "=rm"))]
6362   "ix86_match_ccmode (insn, CCGCmode)
6363    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6364 {
6365   switch (get_attr_type (insn))
6366     {
6367     case TYPE_INCDEC:
6368       if (operands[2] == constm1_rtx)
6369         return "inc{l}\t%0";
6370       else
6371         {
6372           gcc_assert (operands[2] == const1_rtx);
6373           return "dec{l}\t%0";
6374         }
6375
6376     default:
6377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6378       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6379          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6380       if ((INTVAL (operands[2]) == -128
6381            || (INTVAL (operands[2]) > 0
6382                && INTVAL (operands[2]) != 128)))
6383         return "sub{l}\t{%2, %0|%0, %2}";
6384       operands[2] = GEN_INT (-INTVAL (operands[2]));
6385       return "add{l}\t{%2, %0|%0, %2}";
6386     }
6387 }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu")))
6392    (set_attr "mode" "SI")])
6393
6394 (define_insn "*addsi_5"
6395   [(set (reg FLAGS_REG)
6396         (compare
6397           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6398                    (match_operand:SI 2 "general_operand" "rmni"))
6399           (const_int 0)))
6400    (clobber (match_scratch:SI 0 "=r"))]
6401   "ix86_match_ccmode (insn, CCGOCmode)
6402    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6403    /* Current assemblers are broken and do not allow @GOTOFF in
6404       ought but a memory context.  */
6405    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6406 {
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_INCDEC:
6410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411       if (operands[2] == const1_rtx)
6412         return "inc{l}\t%0";
6413       else
6414         {
6415           gcc_assert (operands[2] == constm1_rtx);
6416           return "dec{l}\t%0";
6417         }
6418
6419     default:
6420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6422          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6423       if (CONST_INT_P (operands[2])
6424           && (INTVAL (operands[2]) == 128
6425               || (INTVAL (operands[2]) < 0
6426                   && INTVAL (operands[2]) != -128)))
6427         {
6428           operands[2] = GEN_INT (-INTVAL (operands[2]));
6429           return "sub{l}\t{%2, %0|%0, %2}";
6430         }
6431       return "add{l}\t{%2, %0|%0, %2}";
6432     }
6433 }
6434   [(set (attr "type")
6435      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6436         (const_string "incdec")
6437         (const_string "alu")))
6438    (set_attr "mode" "SI")])
6439
6440 (define_expand "addhi3"
6441   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6442                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6443                             (match_operand:HI 2 "general_operand" "")))
6444               (clobber (reg:CC FLAGS_REG))])]
6445   "TARGET_HIMODE_MATH"
6446   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6447
6448 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6449 ;; type optimizations enabled by define-splits.  This is not important
6450 ;; for PII, and in fact harmful because of partial register stalls.
6451
6452 (define_insn "*addhi_1_lea"
6453   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6454         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6455                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6456    (clobber (reg:CC FLAGS_REG))]
6457   "!TARGET_PARTIAL_REG_STALL
6458    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6459 {
6460   switch (get_attr_type (insn))
6461     {
6462     case TYPE_LEA:
6463       return "#";
6464     case TYPE_INCDEC:
6465       if (operands[2] == const1_rtx)
6466         return "inc{w}\t%0";
6467       else
6468         {
6469           gcc_assert (operands[2] == constm1_rtx);
6470           return "dec{w}\t%0";
6471         }
6472
6473     default:
6474       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6475          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6476       if (CONST_INT_P (operands[2])
6477           && (INTVAL (operands[2]) == 128
6478               || (INTVAL (operands[2]) < 0
6479                   && INTVAL (operands[2]) != -128)))
6480         {
6481           operands[2] = GEN_INT (-INTVAL (operands[2]));
6482           return "sub{w}\t{%2, %0|%0, %2}";
6483         }
6484       return "add{w}\t{%2, %0|%0, %2}";
6485     }
6486 }
6487   [(set (attr "type")
6488      (if_then_else (eq_attr "alternative" "2")
6489         (const_string "lea")
6490         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6491            (const_string "incdec")
6492            (const_string "alu"))))
6493    (set_attr "mode" "HI,HI,SI")])
6494
6495 (define_insn "*addhi_1"
6496   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6497         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6498                  (match_operand:HI 2 "general_operand" "ri,rm")))
6499    (clobber (reg:CC FLAGS_REG))]
6500   "TARGET_PARTIAL_REG_STALL
6501    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6502 {
6503   switch (get_attr_type (insn))
6504     {
6505     case TYPE_INCDEC:
6506       if (operands[2] == const1_rtx)
6507         return "inc{w}\t%0";
6508       else
6509         {
6510           gcc_assert (operands[2] == constm1_rtx);
6511           return "dec{w}\t%0";
6512         }
6513
6514     default:
6515       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6516          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6517       if (CONST_INT_P (operands[2])
6518           && (INTVAL (operands[2]) == 128
6519               || (INTVAL (operands[2]) < 0
6520                   && INTVAL (operands[2]) != -128)))
6521         {
6522           operands[2] = GEN_INT (-INTVAL (operands[2]));
6523           return "sub{w}\t{%2, %0|%0, %2}";
6524         }
6525       return "add{w}\t{%2, %0|%0, %2}";
6526     }
6527 }
6528   [(set (attr "type")
6529      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6530         (const_string "incdec")
6531         (const_string "alu")))
6532    (set_attr "mode" "HI")])
6533
6534 (define_insn "*addhi_2"
6535   [(set (reg FLAGS_REG)
6536         (compare
6537           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6538                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6539           (const_int 0)))
6540    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6541         (plus:HI (match_dup 1) (match_dup 2)))]
6542   "ix86_match_ccmode (insn, CCGOCmode)
6543    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6544 {
6545   switch (get_attr_type (insn))
6546     {
6547     case TYPE_INCDEC:
6548       if (operands[2] == const1_rtx)
6549         return "inc{w}\t%0";
6550       else
6551         {
6552           gcc_assert (operands[2] == constm1_rtx);
6553           return "dec{w}\t%0";
6554         }
6555
6556     default:
6557       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6559       if (CONST_INT_P (operands[2])
6560           && (INTVAL (operands[2]) == 128
6561               || (INTVAL (operands[2]) < 0
6562                   && INTVAL (operands[2]) != -128)))
6563         {
6564           operands[2] = GEN_INT (-INTVAL (operands[2]));
6565           return "sub{w}\t{%2, %0|%0, %2}";
6566         }
6567       return "add{w}\t{%2, %0|%0, %2}";
6568     }
6569 }
6570   [(set (attr "type")
6571      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6572         (const_string "incdec")
6573         (const_string "alu")))
6574    (set_attr "mode" "HI")])
6575
6576 (define_insn "*addhi_3"
6577   [(set (reg FLAGS_REG)
6578         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6579                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6580    (clobber (match_scratch:HI 0 "=r"))]
6581   "ix86_match_ccmode (insn, CCZmode)
6582    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6583 {
6584   switch (get_attr_type (insn))
6585     {
6586     case TYPE_INCDEC:
6587       if (operands[2] == const1_rtx)
6588         return "inc{w}\t%0";
6589       else
6590         {
6591           gcc_assert (operands[2] == constm1_rtx);
6592           return "dec{w}\t%0";
6593         }
6594
6595     default:
6596       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6597          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6598       if (CONST_INT_P (operands[2])
6599           && (INTVAL (operands[2]) == 128
6600               || (INTVAL (operands[2]) < 0
6601                   && INTVAL (operands[2]) != -128)))
6602         {
6603           operands[2] = GEN_INT (-INTVAL (operands[2]));
6604           return "sub{w}\t{%2, %0|%0, %2}";
6605         }
6606       return "add{w}\t{%2, %0|%0, %2}";
6607     }
6608 }
6609   [(set (attr "type")
6610      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6611         (const_string "incdec")
6612         (const_string "alu")))
6613    (set_attr "mode" "HI")])
6614
6615 ; See comments above addsi_4 for details.
6616 (define_insn "*addhi_4"
6617   [(set (reg FLAGS_REG)
6618         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6619                  (match_operand:HI 2 "const_int_operand" "n")))
6620    (clobber (match_scratch:HI 0 "=rm"))]
6621   "ix86_match_ccmode (insn, CCGCmode)
6622    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6623 {
6624   switch (get_attr_type (insn))
6625     {
6626     case TYPE_INCDEC:
6627       if (operands[2] == constm1_rtx)
6628         return "inc{w}\t%0";
6629       else
6630         {
6631           gcc_assert (operands[2] == const1_rtx);
6632           return "dec{w}\t%0";
6633         }
6634
6635     default:
6636       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6638          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6639       if ((INTVAL (operands[2]) == -128
6640            || (INTVAL (operands[2]) > 0
6641                && INTVAL (operands[2]) != 128)))
6642         return "sub{w}\t{%2, %0|%0, %2}";
6643       operands[2] = GEN_INT (-INTVAL (operands[2]));
6644       return "add{w}\t{%2, %0|%0, %2}";
6645     }
6646 }
6647   [(set (attr "type")
6648      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6649         (const_string "incdec")
6650         (const_string "alu")))
6651    (set_attr "mode" "SI")])
6652
6653
6654 (define_insn "*addhi_5"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6658                    (match_operand:HI 2 "general_operand" "rmni"))
6659           (const_int 0)))
6660    (clobber (match_scratch:HI 0 "=r"))]
6661   "ix86_match_ccmode (insn, CCGOCmode)
6662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6663 {
6664   switch (get_attr_type (insn))
6665     {
6666     case TYPE_INCDEC:
6667       if (operands[2] == const1_rtx)
6668         return "inc{w}\t%0";
6669       else
6670         {
6671           gcc_assert (operands[2] == constm1_rtx);
6672           return "dec{w}\t%0";
6673         }
6674
6675     default:
6676       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6677          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6678       if (CONST_INT_P (operands[2])
6679           && (INTVAL (operands[2]) == 128
6680               || (INTVAL (operands[2]) < 0
6681                   && INTVAL (operands[2]) != -128)))
6682         {
6683           operands[2] = GEN_INT (-INTVAL (operands[2]));
6684           return "sub{w}\t{%2, %0|%0, %2}";
6685         }
6686       return "add{w}\t{%2, %0|%0, %2}";
6687     }
6688 }
6689   [(set (attr "type")
6690      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6691         (const_string "incdec")
6692         (const_string "alu")))
6693    (set_attr "mode" "HI")])
6694
6695 (define_expand "addqi3"
6696   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6697                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6698                             (match_operand:QI 2 "general_operand" "")))
6699               (clobber (reg:CC FLAGS_REG))])]
6700   "TARGET_QIMODE_MATH"
6701   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6702
6703 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6704 (define_insn "*addqi_1_lea"
6705   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6706         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6707                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6708    (clobber (reg:CC FLAGS_REG))]
6709   "!TARGET_PARTIAL_REG_STALL
6710    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6711 {
6712   int widen = (which_alternative == 2);
6713   switch (get_attr_type (insn))
6714     {
6715     case TYPE_LEA:
6716       return "#";
6717     case TYPE_INCDEC:
6718       if (operands[2] == const1_rtx)
6719         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6720       else
6721         {
6722           gcc_assert (operands[2] == constm1_rtx);
6723           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6724         }
6725
6726     default:
6727       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6728          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6729       if (CONST_INT_P (operands[2])
6730           && (INTVAL (operands[2]) == 128
6731               || (INTVAL (operands[2]) < 0
6732                   && INTVAL (operands[2]) != -128)))
6733         {
6734           operands[2] = GEN_INT (-INTVAL (operands[2]));
6735           if (widen)
6736             return "sub{l}\t{%2, %k0|%k0, %2}";
6737           else
6738             return "sub{b}\t{%2, %0|%0, %2}";
6739         }
6740       if (widen)
6741         return "add{l}\t{%k2, %k0|%k0, %k2}";
6742       else
6743         return "add{b}\t{%2, %0|%0, %2}";
6744     }
6745 }
6746   [(set (attr "type")
6747      (if_then_else (eq_attr "alternative" "3")
6748         (const_string "lea")
6749         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6750            (const_string "incdec")
6751            (const_string "alu"))))
6752    (set_attr "mode" "QI,QI,SI,SI")])
6753
6754 (define_insn "*addqi_1"
6755   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6756         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6757                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6758    (clobber (reg:CC FLAGS_REG))]
6759   "TARGET_PARTIAL_REG_STALL
6760    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6761 {
6762   int widen = (which_alternative == 2);
6763   switch (get_attr_type (insn))
6764     {
6765     case TYPE_INCDEC:
6766       if (operands[2] == const1_rtx)
6767         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6768       else
6769         {
6770           gcc_assert (operands[2] == constm1_rtx);
6771           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6772         }
6773
6774     default:
6775       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6776          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6777       if (CONST_INT_P (operands[2])
6778           && (INTVAL (operands[2]) == 128
6779               || (INTVAL (operands[2]) < 0
6780                   && INTVAL (operands[2]) != -128)))
6781         {
6782           operands[2] = GEN_INT (-INTVAL (operands[2]));
6783           if (widen)
6784             return "sub{l}\t{%2, %k0|%k0, %2}";
6785           else
6786             return "sub{b}\t{%2, %0|%0, %2}";
6787         }
6788       if (widen)
6789         return "add{l}\t{%k2, %k0|%k0, %k2}";
6790       else
6791         return "add{b}\t{%2, %0|%0, %2}";
6792     }
6793 }
6794   [(set (attr "type")
6795      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6796         (const_string "incdec")
6797         (const_string "alu")))
6798    (set_attr "mode" "QI,QI,SI")])
6799
6800 (define_insn "*addqi_1_slp"
6801   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6802         (plus:QI (match_dup 0)
6803                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6804    (clobber (reg:CC FLAGS_REG))]
6805   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6806    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6807 {
6808   switch (get_attr_type (insn))
6809     {
6810     case TYPE_INCDEC:
6811       if (operands[1] == const1_rtx)
6812         return "inc{b}\t%0";
6813       else
6814         {
6815           gcc_assert (operands[1] == constm1_rtx);
6816           return "dec{b}\t%0";
6817         }
6818
6819     default:
6820       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6821       if (CONST_INT_P (operands[1])
6822           && INTVAL (operands[1]) < 0)
6823         {
6824           operands[1] = GEN_INT (-INTVAL (operands[1]));
6825           return "sub{b}\t{%1, %0|%0, %1}";
6826         }
6827       return "add{b}\t{%1, %0|%0, %1}";
6828     }
6829 }
6830   [(set (attr "type")
6831      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6832         (const_string "incdec")
6833         (const_string "alu1")))
6834    (set (attr "memory")
6835      (if_then_else (match_operand 1 "memory_operand" "")
6836         (const_string "load")
6837         (const_string "none")))
6838    (set_attr "mode" "QI")])
6839
6840 (define_insn "*addqi_2"
6841   [(set (reg FLAGS_REG)
6842         (compare
6843           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6844                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6845           (const_int 0)))
6846    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6847         (plus:QI (match_dup 1) (match_dup 2)))]
6848   "ix86_match_ccmode (insn, CCGOCmode)
6849    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6850 {
6851   switch (get_attr_type (insn))
6852     {
6853     case TYPE_INCDEC:
6854       if (operands[2] == const1_rtx)
6855         return "inc{b}\t%0";
6856       else
6857         {
6858           gcc_assert (operands[2] == constm1_rtx
6859                       || (CONST_INT_P (operands[2])
6860                           && INTVAL (operands[2]) == 255));
6861           return "dec{b}\t%0";
6862         }
6863
6864     default:
6865       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6866       if (CONST_INT_P (operands[2])
6867           && INTVAL (operands[2]) < 0)
6868         {
6869           operands[2] = GEN_INT (-INTVAL (operands[2]));
6870           return "sub{b}\t{%2, %0|%0, %2}";
6871         }
6872       return "add{b}\t{%2, %0|%0, %2}";
6873     }
6874 }
6875   [(set (attr "type")
6876      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6877         (const_string "incdec")
6878         (const_string "alu")))
6879    (set_attr "mode" "QI")])
6880
6881 (define_insn "*addqi_3"
6882   [(set (reg FLAGS_REG)
6883         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6884                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6885    (clobber (match_scratch:QI 0 "=q"))]
6886   "ix86_match_ccmode (insn, CCZmode)
6887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 {
6889   switch (get_attr_type (insn))
6890     {
6891     case TYPE_INCDEC:
6892       if (operands[2] == const1_rtx)
6893         return "inc{b}\t%0";
6894       else
6895         {
6896           gcc_assert (operands[2] == constm1_rtx
6897                       || (CONST_INT_P (operands[2])
6898                           && INTVAL (operands[2]) == 255));
6899           return "dec{b}\t%0";
6900         }
6901
6902     default:
6903       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6904       if (CONST_INT_P (operands[2])
6905           && INTVAL (operands[2]) < 0)
6906         {
6907           operands[2] = GEN_INT (-INTVAL (operands[2]));
6908           return "sub{b}\t{%2, %0|%0, %2}";
6909         }
6910       return "add{b}\t{%2, %0|%0, %2}";
6911     }
6912 }
6913   [(set (attr "type")
6914      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6915         (const_string "incdec")
6916         (const_string "alu")))
6917    (set_attr "mode" "QI")])
6918
6919 ; See comments above addsi_4 for details.
6920 (define_insn "*addqi_4"
6921   [(set (reg FLAGS_REG)
6922         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6923                  (match_operand:QI 2 "const_int_operand" "n")))
6924    (clobber (match_scratch:QI 0 "=qm"))]
6925   "ix86_match_ccmode (insn, CCGCmode)
6926    && (INTVAL (operands[2]) & 0xff) != 0x80"
6927 {
6928   switch (get_attr_type (insn))
6929     {
6930     case TYPE_INCDEC:
6931       if (operands[2] == constm1_rtx
6932           || (CONST_INT_P (operands[2])
6933               && INTVAL (operands[2]) == 255))
6934         return "inc{b}\t%0";
6935       else
6936         {
6937           gcc_assert (operands[2] == const1_rtx);
6938           return "dec{b}\t%0";
6939         }
6940
6941     default:
6942       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6943       if (INTVAL (operands[2]) < 0)
6944         {
6945           operands[2] = GEN_INT (-INTVAL (operands[2]));
6946           return "add{b}\t{%2, %0|%0, %2}";
6947         }
6948       return "sub{b}\t{%2, %0|%0, %2}";
6949     }
6950 }
6951   [(set (attr "type")
6952      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6953         (const_string "incdec")
6954         (const_string "alu")))
6955    (set_attr "mode" "QI")])
6956
6957
6958 (define_insn "*addqi_5"
6959   [(set (reg FLAGS_REG)
6960         (compare
6961           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6962                    (match_operand:QI 2 "general_operand" "qmni"))
6963           (const_int 0)))
6964    (clobber (match_scratch:QI 0 "=q"))]
6965   "ix86_match_ccmode (insn, CCGOCmode)
6966    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6967 {
6968   switch (get_attr_type (insn))
6969     {
6970     case TYPE_INCDEC:
6971       if (operands[2] == const1_rtx)
6972         return "inc{b}\t%0";
6973       else
6974         {
6975           gcc_assert (operands[2] == constm1_rtx
6976                       || (CONST_INT_P (operands[2])
6977                           && INTVAL (operands[2]) == 255));
6978           return "dec{b}\t%0";
6979         }
6980
6981     default:
6982       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6983       if (CONST_INT_P (operands[2])
6984           && INTVAL (operands[2]) < 0)
6985         {
6986           operands[2] = GEN_INT (-INTVAL (operands[2]));
6987           return "sub{b}\t{%2, %0|%0, %2}";
6988         }
6989       return "add{b}\t{%2, %0|%0, %2}";
6990     }
6991 }
6992   [(set (attr "type")
6993      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6994         (const_string "incdec")
6995         (const_string "alu")))
6996    (set_attr "mode" "QI")])
6997
6998
6999 (define_insn "addqi_ext_1"
7000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7001                          (const_int 8)
7002                          (const_int 8))
7003         (plus:SI
7004           (zero_extract:SI
7005             (match_operand 1 "ext_register_operand" "0")
7006             (const_int 8)
7007             (const_int 8))
7008           (match_operand:QI 2 "general_operand" "Qmn")))
7009    (clobber (reg:CC FLAGS_REG))]
7010   "!TARGET_64BIT"
7011 {
7012   switch (get_attr_type (insn))
7013     {
7014     case TYPE_INCDEC:
7015       if (operands[2] == const1_rtx)
7016         return "inc{b}\t%h0";
7017       else
7018         {
7019           gcc_assert (operands[2] == constm1_rtx
7020                       || (CONST_INT_P (operands[2])
7021                           && INTVAL (operands[2]) == 255));
7022           return "dec{b}\t%h0";
7023         }
7024
7025     default:
7026       return "add{b}\t{%2, %h0|%h0, %2}";
7027     }
7028 }
7029   [(set (attr "type")
7030      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7031         (const_string "incdec")
7032         (const_string "alu")))
7033    (set_attr "mode" "QI")])
7034
7035 (define_insn "*addqi_ext_1_rex64"
7036   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7037                          (const_int 8)
7038                          (const_int 8))
7039         (plus:SI
7040           (zero_extract:SI
7041             (match_operand 1 "ext_register_operand" "0")
7042             (const_int 8)
7043             (const_int 8))
7044           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "TARGET_64BIT"
7047 {
7048   switch (get_attr_type (insn))
7049     {
7050     case TYPE_INCDEC:
7051       if (operands[2] == const1_rtx)
7052         return "inc{b}\t%h0";
7053       else
7054         {
7055           gcc_assert (operands[2] == constm1_rtx
7056                       || (CONST_INT_P (operands[2])
7057                           && INTVAL (operands[2]) == 255));
7058           return "dec{b}\t%h0";
7059         }
7060
7061     default:
7062       return "add{b}\t{%2, %h0|%h0, %2}";
7063     }
7064 }
7065   [(set (attr "type")
7066      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7067         (const_string "incdec")
7068         (const_string "alu")))
7069    (set_attr "mode" "QI")])
7070
7071 (define_insn "*addqi_ext_2"
7072   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7073                          (const_int 8)
7074                          (const_int 8))
7075         (plus:SI
7076           (zero_extract:SI
7077             (match_operand 1 "ext_register_operand" "%0")
7078             (const_int 8)
7079             (const_int 8))
7080           (zero_extract:SI
7081             (match_operand 2 "ext_register_operand" "Q")
7082             (const_int 8)
7083             (const_int 8))))
7084    (clobber (reg:CC FLAGS_REG))]
7085   ""
7086   "add{b}\t{%h2, %h0|%h0, %h2}"
7087   [(set_attr "type" "alu")
7088    (set_attr "mode" "QI")])
7089
7090 ;; The patterns that match these are at the end of this file.
7091
7092 (define_expand "addxf3"
7093   [(set (match_operand:XF 0 "register_operand" "")
7094         (plus:XF (match_operand:XF 1 "register_operand" "")
7095                  (match_operand:XF 2 "register_operand" "")))]
7096   "TARGET_80387"
7097   "")
7098
7099 (define_expand "add<mode>3"
7100   [(set (match_operand:MODEF 0 "register_operand" "")
7101         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7102                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7103   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7104   "")
7105 \f
7106 ;; Subtract instructions
7107
7108 ;; %%% splits for subditi3
7109
7110 (define_expand "subti3"
7111   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7112                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7113                              (match_operand:TI 2 "x86_64_general_operand" "")))
7114               (clobber (reg:CC FLAGS_REG))])]
7115   "TARGET_64BIT"
7116   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7117
7118 (define_insn "*subti3_1"
7119   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7120         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7121                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7122    (clobber (reg:CC FLAGS_REG))]
7123   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7124   "#")
7125
7126 (define_split
7127   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7128         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7129                   (match_operand:TI 2 "x86_64_general_operand" "")))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_64BIT && reload_completed"
7132   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7133               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7134    (parallel [(set (match_dup 3)
7135                    (minus:DI (match_dup 4)
7136                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7137                                       (match_dup 5))))
7138               (clobber (reg:CC FLAGS_REG))])]
7139   "split_ti (operands+0, 1, operands+0, operands+3);
7140    split_ti (operands+1, 1, operands+1, operands+4);
7141    split_ti (operands+2, 1, operands+2, operands+5);")
7142
7143 ;; %%% splits for subsidi3
7144
7145 (define_expand "subdi3"
7146   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7147                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7148                              (match_operand:DI 2 "x86_64_general_operand" "")))
7149               (clobber (reg:CC FLAGS_REG))])]
7150   ""
7151   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7152
7153 (define_insn "*subdi3_1"
7154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7155         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7156                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7157    (clobber (reg:CC FLAGS_REG))]
7158   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7159   "#")
7160
7161 (define_split
7162   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7163         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7164                   (match_operand:DI 2 "general_operand" "")))
7165    (clobber (reg:CC FLAGS_REG))]
7166   "!TARGET_64BIT && reload_completed"
7167   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7168               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7169    (parallel [(set (match_dup 3)
7170                    (minus:SI (match_dup 4)
7171                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7172                                       (match_dup 5))))
7173               (clobber (reg:CC FLAGS_REG))])]
7174   "split_di (operands+0, 1, operands+0, operands+3);
7175    split_di (operands+1, 1, operands+1, operands+4);
7176    split_di (operands+2, 1, operands+2, operands+5);")
7177
7178 (define_insn "subdi3_carry_rex64"
7179   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7180           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7181             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7182                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7185   "sbb{q}\t{%2, %0|%0, %2}"
7186   [(set_attr "type" "alu")
7187    (set_attr "pent_pair" "pu")
7188    (set_attr "mode" "DI")])
7189
7190 (define_insn "*subdi_1_rex64"
7191   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7192         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7193                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7194    (clobber (reg:CC FLAGS_REG))]
7195   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7196   "sub{q}\t{%2, %0|%0, %2}"
7197   [(set_attr "type" "alu")
7198    (set_attr "mode" "DI")])
7199
7200 (define_insn "*subdi_2_rex64"
7201   [(set (reg FLAGS_REG)
7202         (compare
7203           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7204                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7205           (const_int 0)))
7206    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7207         (minus:DI (match_dup 1) (match_dup 2)))]
7208   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7209    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7210   "sub{q}\t{%2, %0|%0, %2}"
7211   [(set_attr "type" "alu")
7212    (set_attr "mode" "DI")])
7213
7214 (define_insn "*subdi_3_rex63"
7215   [(set (reg FLAGS_REG)
7216         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7217                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7218    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7219         (minus:DI (match_dup 1) (match_dup 2)))]
7220   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7221    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7222   "sub{q}\t{%2, %0|%0, %2}"
7223   [(set_attr "type" "alu")
7224    (set_attr "mode" "DI")])
7225
7226 (define_insn "subqi3_carry"
7227   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7228           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7229             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7230                (match_operand:QI 2 "general_operand" "qi,qm"))))
7231    (clobber (reg:CC FLAGS_REG))]
7232   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7233   "sbb{b}\t{%2, %0|%0, %2}"
7234   [(set_attr "type" "alu")
7235    (set_attr "pent_pair" "pu")
7236    (set_attr "mode" "QI")])
7237
7238 (define_insn "subhi3_carry"
7239   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7240           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7241             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7242                (match_operand:HI 2 "general_operand" "ri,rm"))))
7243    (clobber (reg:CC FLAGS_REG))]
7244   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7245   "sbb{w}\t{%2, %0|%0, %2}"
7246   [(set_attr "type" "alu")
7247    (set_attr "pent_pair" "pu")
7248    (set_attr "mode" "HI")])
7249
7250 (define_insn "subsi3_carry"
7251   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7252           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7253             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7254                (match_operand:SI 2 "general_operand" "ri,rm"))))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7257   "sbb{l}\t{%2, %0|%0, %2}"
7258   [(set_attr "type" "alu")
7259    (set_attr "pent_pair" "pu")
7260    (set_attr "mode" "SI")])
7261
7262 (define_insn "subsi3_carry_zext"
7263   [(set (match_operand:DI 0 "register_operand" "=r")
7264           (zero_extend:DI
7265             (minus:SI (match_operand:SI 1 "register_operand" "0")
7266               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7267                  (match_operand:SI 2 "general_operand" "g")))))
7268    (clobber (reg:CC FLAGS_REG))]
7269   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7270   "sbb{l}\t{%2, %k0|%k0, %2}"
7271   [(set_attr "type" "alu")
7272    (set_attr "pent_pair" "pu")
7273    (set_attr "mode" "SI")])
7274
7275 (define_expand "subsi3"
7276   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7277                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7278                              (match_operand:SI 2 "general_operand" "")))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7282
7283 (define_insn "*subsi_1"
7284   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7285         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7286                   (match_operand:SI 2 "general_operand" "ri,rm")))
7287    (clobber (reg:CC FLAGS_REG))]
7288   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7289   "sub{l}\t{%2, %0|%0, %2}"
7290   [(set_attr "type" "alu")
7291    (set_attr "mode" "SI")])
7292
7293 (define_insn "*subsi_1_zext"
7294   [(set (match_operand:DI 0 "register_operand" "=r")
7295         (zero_extend:DI
7296           (minus:SI (match_operand:SI 1 "register_operand" "0")
7297                     (match_operand:SI 2 "general_operand" "g"))))
7298    (clobber (reg:CC FLAGS_REG))]
7299   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7300   "sub{l}\t{%2, %k0|%k0, %2}"
7301   [(set_attr "type" "alu")
7302    (set_attr "mode" "SI")])
7303
7304 (define_insn "*subsi_2"
7305   [(set (reg FLAGS_REG)
7306         (compare
7307           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7308                     (match_operand:SI 2 "general_operand" "ri,rm"))
7309           (const_int 0)))
7310    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7311         (minus:SI (match_dup 1) (match_dup 2)))]
7312   "ix86_match_ccmode (insn, CCGOCmode)
7313    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7314   "sub{l}\t{%2, %0|%0, %2}"
7315   [(set_attr "type" "alu")
7316    (set_attr "mode" "SI")])
7317
7318 (define_insn "*subsi_2_zext"
7319   [(set (reg FLAGS_REG)
7320         (compare
7321           (minus:SI (match_operand:SI 1 "register_operand" "0")
7322                     (match_operand:SI 2 "general_operand" "g"))
7323           (const_int 0)))
7324    (set (match_operand:DI 0 "register_operand" "=r")
7325         (zero_extend:DI
7326           (minus:SI (match_dup 1)
7327                     (match_dup 2))))]
7328   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7329    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7330   "sub{l}\t{%2, %k0|%k0, %2}"
7331   [(set_attr "type" "alu")
7332    (set_attr "mode" "SI")])
7333
7334 (define_insn "*subsi_3"
7335   [(set (reg FLAGS_REG)
7336         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7337                  (match_operand:SI 2 "general_operand" "ri,rm")))
7338    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7339         (minus:SI (match_dup 1) (match_dup 2)))]
7340   "ix86_match_ccmode (insn, CCmode)
7341    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7342   "sub{l}\t{%2, %0|%0, %2}"
7343   [(set_attr "type" "alu")
7344    (set_attr "mode" "SI")])
7345
7346 (define_insn "*subsi_3_zext"
7347   [(set (reg FLAGS_REG)
7348         (compare (match_operand:SI 1 "register_operand" "0")
7349                  (match_operand:SI 2 "general_operand" "g")))
7350    (set (match_operand:DI 0 "register_operand" "=r")
7351         (zero_extend:DI
7352           (minus:SI (match_dup 1)
7353                     (match_dup 2))))]
7354   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7355    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7356   "sub{l}\t{%2, %1|%1, %2}"
7357   [(set_attr "type" "alu")
7358    (set_attr "mode" "DI")])
7359
7360 (define_expand "subhi3"
7361   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7362                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7363                              (match_operand:HI 2 "general_operand" "")))
7364               (clobber (reg:CC FLAGS_REG))])]
7365   "TARGET_HIMODE_MATH"
7366   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7367
7368 (define_insn "*subhi_1"
7369   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7370         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7371                   (match_operand:HI 2 "general_operand" "ri,rm")))
7372    (clobber (reg:CC FLAGS_REG))]
7373   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7374   "sub{w}\t{%2, %0|%0, %2}"
7375   [(set_attr "type" "alu")
7376    (set_attr "mode" "HI")])
7377
7378 (define_insn "*subhi_2"
7379   [(set (reg FLAGS_REG)
7380         (compare
7381           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7382                     (match_operand:HI 2 "general_operand" "ri,rm"))
7383           (const_int 0)))
7384    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7385         (minus:HI (match_dup 1) (match_dup 2)))]
7386   "ix86_match_ccmode (insn, CCGOCmode)
7387    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7388   "sub{w}\t{%2, %0|%0, %2}"
7389   [(set_attr "type" "alu")
7390    (set_attr "mode" "HI")])
7391
7392 (define_insn "*subhi_3"
7393   [(set (reg FLAGS_REG)
7394         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7395                  (match_operand:HI 2 "general_operand" "ri,rm")))
7396    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7397         (minus:HI (match_dup 1) (match_dup 2)))]
7398   "ix86_match_ccmode (insn, CCmode)
7399    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7400   "sub{w}\t{%2, %0|%0, %2}"
7401   [(set_attr "type" "alu")
7402    (set_attr "mode" "HI")])
7403
7404 (define_expand "subqi3"
7405   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7406                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7407                              (match_operand:QI 2 "general_operand" "")))
7408               (clobber (reg:CC FLAGS_REG))])]
7409   "TARGET_QIMODE_MATH"
7410   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7411
7412 (define_insn "*subqi_1"
7413   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7414         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7415                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7418   "sub{b}\t{%2, %0|%0, %2}"
7419   [(set_attr "type" "alu")
7420    (set_attr "mode" "QI")])
7421
7422 (define_insn "*subqi_1_slp"
7423   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7424         (minus:QI (match_dup 0)
7425                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7426    (clobber (reg:CC FLAGS_REG))]
7427   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7428    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7429   "sub{b}\t{%1, %0|%0, %1}"
7430   [(set_attr "type" "alu1")
7431    (set_attr "mode" "QI")])
7432
7433 (define_insn "*subqi_2"
7434   [(set (reg FLAGS_REG)
7435         (compare
7436           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7437                     (match_operand:QI 2 "general_operand" "qi,qm"))
7438           (const_int 0)))
7439    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7440         (minus:HI (match_dup 1) (match_dup 2)))]
7441   "ix86_match_ccmode (insn, CCGOCmode)
7442    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7443   "sub{b}\t{%2, %0|%0, %2}"
7444   [(set_attr "type" "alu")
7445    (set_attr "mode" "QI")])
7446
7447 (define_insn "*subqi_3"
7448   [(set (reg FLAGS_REG)
7449         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7450                  (match_operand:QI 2 "general_operand" "qi,qm")))
7451    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7452         (minus:HI (match_dup 1) (match_dup 2)))]
7453   "ix86_match_ccmode (insn, CCmode)
7454    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7455   "sub{b}\t{%2, %0|%0, %2}"
7456   [(set_attr "type" "alu")
7457    (set_attr "mode" "QI")])
7458
7459 ;; The patterns that match these are at the end of this file.
7460
7461 (define_expand "subxf3"
7462   [(set (match_operand:XF 0 "register_operand" "")
7463         (minus:XF (match_operand:XF 1 "register_operand" "")
7464                   (match_operand:XF 2 "register_operand" "")))]
7465   "TARGET_80387"
7466   "")
7467
7468 (define_expand "sub<mode>3"
7469   [(set (match_operand:MODEF 0 "register_operand" "")
7470         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7471                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7472   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7473   "")
7474 \f
7475 ;; Multiply instructions
7476
7477 (define_expand "muldi3"
7478   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7479                    (mult:DI (match_operand:DI 1 "register_operand" "")
7480                             (match_operand:DI 2 "x86_64_general_operand" "")))
7481               (clobber (reg:CC FLAGS_REG))])]
7482   "TARGET_64BIT"
7483   "")
7484
7485 ;; On AMDFAM10 
7486 ;; IMUL reg64, reg64, imm8      Direct
7487 ;; IMUL reg64, mem64, imm8      VectorPath
7488 ;; IMUL reg64, reg64, imm32     Direct
7489 ;; IMUL reg64, mem64, imm32     VectorPath 
7490 ;; IMUL reg64, reg64            Direct
7491 ;; IMUL reg64, mem64            Direct
7492
7493 (define_insn "*muldi3_1_rex64"
7494   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7495         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7496                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7497    (clobber (reg:CC FLAGS_REG))]
7498   "TARGET_64BIT
7499    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7500   "@
7501    imul{q}\t{%2, %1, %0|%0, %1, %2}
7502    imul{q}\t{%2, %1, %0|%0, %1, %2}
7503    imul{q}\t{%2, %0|%0, %2}"
7504   [(set_attr "type" "imul")
7505    (set_attr "prefix_0f" "0,0,1")
7506    (set (attr "athlon_decode")
7507         (cond [(eq_attr "cpu" "athlon")
7508                   (const_string "vector")
7509                (eq_attr "alternative" "1")
7510                   (const_string "vector")
7511                (and (eq_attr "alternative" "2")
7512                     (match_operand 1 "memory_operand" ""))
7513                   (const_string "vector")]
7514               (const_string "direct")))
7515    (set (attr "amdfam10_decode")
7516         (cond [(and (eq_attr "alternative" "0,1")
7517                     (match_operand 1 "memory_operand" ""))
7518                   (const_string "vector")]
7519               (const_string "direct")))       
7520    (set_attr "mode" "DI")])
7521
7522 (define_expand "mulsi3"
7523   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7524                    (mult:SI (match_operand:SI 1 "register_operand" "")
7525                             (match_operand:SI 2 "general_operand" "")))
7526               (clobber (reg:CC FLAGS_REG))])]
7527   ""
7528   "")
7529
7530 ;; On AMDFAM10 
7531 ;; IMUL reg32, reg32, imm8      Direct
7532 ;; IMUL reg32, mem32, imm8      VectorPath
7533 ;; IMUL reg32, reg32, imm32     Direct
7534 ;; IMUL reg32, mem32, imm32     VectorPath
7535 ;; IMUL reg32, reg32            Direct
7536 ;; IMUL reg32, mem32            Direct
7537
7538 (define_insn "*mulsi3_1"
7539   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7540         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7541                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7542    (clobber (reg:CC FLAGS_REG))]
7543   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7544   "@
7545    imul{l}\t{%2, %1, %0|%0, %1, %2}
7546    imul{l}\t{%2, %1, %0|%0, %1, %2}
7547    imul{l}\t{%2, %0|%0, %2}"
7548   [(set_attr "type" "imul")
7549    (set_attr "prefix_0f" "0,0,1")
7550    (set (attr "athlon_decode")
7551         (cond [(eq_attr "cpu" "athlon")
7552                   (const_string "vector")
7553                (eq_attr "alternative" "1")
7554                   (const_string "vector")
7555                (and (eq_attr "alternative" "2")
7556                     (match_operand 1 "memory_operand" ""))
7557                   (const_string "vector")]
7558               (const_string "direct")))
7559    (set (attr "amdfam10_decode")
7560         (cond [(and (eq_attr "alternative" "0,1")
7561                     (match_operand 1 "memory_operand" ""))
7562                   (const_string "vector")]
7563               (const_string "direct")))       
7564    (set_attr "mode" "SI")])
7565
7566 (define_insn "*mulsi3_1_zext"
7567   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7568         (zero_extend:DI
7569           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7570                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "TARGET_64BIT
7573    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7574   "@
7575    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7576    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7577    imul{l}\t{%2, %k0|%k0, %2}"
7578   [(set_attr "type" "imul")
7579    (set_attr "prefix_0f" "0,0,1")
7580    (set (attr "athlon_decode")
7581         (cond [(eq_attr "cpu" "athlon")
7582                   (const_string "vector")
7583                (eq_attr "alternative" "1")
7584                   (const_string "vector")
7585                (and (eq_attr "alternative" "2")
7586                     (match_operand 1 "memory_operand" ""))
7587                   (const_string "vector")]
7588               (const_string "direct")))
7589    (set (attr "amdfam10_decode")
7590         (cond [(and (eq_attr "alternative" "0,1")
7591                     (match_operand 1 "memory_operand" ""))
7592                   (const_string "vector")]
7593               (const_string "direct")))       
7594    (set_attr "mode" "SI")])
7595
7596 (define_expand "mulhi3"
7597   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7598                    (mult:HI (match_operand:HI 1 "register_operand" "")
7599                             (match_operand:HI 2 "general_operand" "")))
7600               (clobber (reg:CC FLAGS_REG))])]
7601   "TARGET_HIMODE_MATH"
7602   "")
7603
7604 ;; On AMDFAM10
7605 ;; IMUL reg16, reg16, imm8      VectorPath
7606 ;; IMUL reg16, mem16, imm8      VectorPath
7607 ;; IMUL reg16, reg16, imm16     VectorPath
7608 ;; IMUL reg16, mem16, imm16     VectorPath
7609 ;; IMUL reg16, reg16            Direct
7610 ;; IMUL reg16, mem16            Direct
7611 (define_insn "*mulhi3_1"
7612   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7613         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7614                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7615    (clobber (reg:CC FLAGS_REG))]
7616   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7617   "@
7618    imul{w}\t{%2, %1, %0|%0, %1, %2}
7619    imul{w}\t{%2, %1, %0|%0, %1, %2}
7620    imul{w}\t{%2, %0|%0, %2}"
7621   [(set_attr "type" "imul")
7622    (set_attr "prefix_0f" "0,0,1")
7623    (set (attr "athlon_decode")
7624         (cond [(eq_attr "cpu" "athlon")
7625                   (const_string "vector")
7626                (eq_attr "alternative" "1,2")
7627                   (const_string "vector")]
7628               (const_string "direct")))
7629    (set (attr "amdfam10_decode")
7630         (cond [(eq_attr "alternative" "0,1")
7631                   (const_string "vector")]
7632               (const_string "direct")))
7633    (set_attr "mode" "HI")])
7634
7635 (define_expand "mulqi3"
7636   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7637                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7638                             (match_operand:QI 2 "register_operand" "")))
7639               (clobber (reg:CC FLAGS_REG))])]
7640   "TARGET_QIMODE_MATH"
7641   "")
7642
7643 ;;On AMDFAM10
7644 ;; MUL reg8     Direct
7645 ;; MUL mem8     Direct
7646
7647 (define_insn "*mulqi3_1"
7648   [(set (match_operand:QI 0 "register_operand" "=a")
7649         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7650                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "TARGET_QIMODE_MATH
7653    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654   "mul{b}\t%2"
7655   [(set_attr "type" "imul")
7656    (set_attr "length_immediate" "0")
7657    (set (attr "athlon_decode")
7658      (if_then_else (eq_attr "cpu" "athlon")
7659         (const_string "vector")
7660         (const_string "direct")))
7661    (set_attr "amdfam10_decode" "direct")        
7662    (set_attr "mode" "QI")])
7663
7664 (define_expand "umulqihi3"
7665   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7666                    (mult:HI (zero_extend:HI
7667                               (match_operand:QI 1 "nonimmediate_operand" ""))
7668                             (zero_extend:HI
7669                               (match_operand:QI 2 "register_operand" ""))))
7670               (clobber (reg:CC FLAGS_REG))])]
7671   "TARGET_QIMODE_MATH"
7672   "")
7673
7674 (define_insn "*umulqihi3_1"
7675   [(set (match_operand:HI 0 "register_operand" "=a")
7676         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7677                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "TARGET_QIMODE_MATH
7680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7681   "mul{b}\t%2"
7682   [(set_attr "type" "imul")
7683    (set_attr "length_immediate" "0")
7684    (set (attr "athlon_decode")
7685      (if_then_else (eq_attr "cpu" "athlon")
7686         (const_string "vector")
7687         (const_string "direct")))
7688    (set_attr "amdfam10_decode" "direct")
7689    (set_attr "mode" "QI")])
7690
7691 (define_expand "mulqihi3"
7692   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7693                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7694                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7695               (clobber (reg:CC FLAGS_REG))])]
7696   "TARGET_QIMODE_MATH"
7697   "")
7698
7699 (define_insn "*mulqihi3_insn"
7700   [(set (match_operand:HI 0 "register_operand" "=a")
7701         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7702                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7703    (clobber (reg:CC FLAGS_REG))]
7704   "TARGET_QIMODE_MATH
7705    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7706   "imul{b}\t%2"
7707   [(set_attr "type" "imul")
7708    (set_attr "length_immediate" "0")
7709    (set (attr "athlon_decode")
7710      (if_then_else (eq_attr "cpu" "athlon")
7711         (const_string "vector")
7712         (const_string "direct")))
7713    (set_attr "amdfam10_decode" "direct")        
7714    (set_attr "mode" "QI")])
7715
7716 (define_expand "umulditi3"
7717   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7718                    (mult:TI (zero_extend:TI
7719                               (match_operand:DI 1 "nonimmediate_operand" ""))
7720                             (zero_extend:TI
7721                               (match_operand:DI 2 "register_operand" ""))))
7722               (clobber (reg:CC FLAGS_REG))])]
7723   "TARGET_64BIT"
7724   "")
7725
7726 (define_insn "*umulditi3_insn"
7727   [(set (match_operand:TI 0 "register_operand" "=A")
7728         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7729                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7730    (clobber (reg:CC FLAGS_REG))]
7731   "TARGET_64BIT
7732    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7733   "mul{q}\t%2"
7734   [(set_attr "type" "imul")
7735    (set_attr "length_immediate" "0")
7736    (set (attr "athlon_decode")
7737      (if_then_else (eq_attr "cpu" "athlon")
7738         (const_string "vector")
7739         (const_string "double")))
7740    (set_attr "amdfam10_decode" "double")        
7741    (set_attr "mode" "DI")])
7742
7743 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7744 (define_expand "umulsidi3"
7745   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7746                    (mult:DI (zero_extend:DI
7747                               (match_operand:SI 1 "nonimmediate_operand" ""))
7748                             (zero_extend:DI
7749                               (match_operand:SI 2 "register_operand" ""))))
7750               (clobber (reg:CC FLAGS_REG))])]
7751   "!TARGET_64BIT"
7752   "")
7753
7754 (define_insn "*umulsidi3_insn"
7755   [(set (match_operand:DI 0 "register_operand" "=A")
7756         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7757                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7758    (clobber (reg:CC FLAGS_REG))]
7759   "!TARGET_64BIT
7760    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7761   "mul{l}\t%2"
7762   [(set_attr "type" "imul")
7763    (set_attr "length_immediate" "0")
7764    (set (attr "athlon_decode")
7765      (if_then_else (eq_attr "cpu" "athlon")
7766         (const_string "vector")
7767         (const_string "double")))
7768    (set_attr "amdfam10_decode" "double")        
7769    (set_attr "mode" "SI")])
7770
7771 (define_expand "mulditi3"
7772   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7773                    (mult:TI (sign_extend:TI
7774                               (match_operand:DI 1 "nonimmediate_operand" ""))
7775                             (sign_extend:TI
7776                               (match_operand:DI 2 "register_operand" ""))))
7777               (clobber (reg:CC FLAGS_REG))])]
7778   "TARGET_64BIT"
7779   "")
7780
7781 (define_insn "*mulditi3_insn"
7782   [(set (match_operand:TI 0 "register_operand" "=A")
7783         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7784                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7785    (clobber (reg:CC FLAGS_REG))]
7786   "TARGET_64BIT
7787    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7788   "imul{q}\t%2"
7789   [(set_attr "type" "imul")
7790    (set_attr "length_immediate" "0")
7791    (set (attr "athlon_decode")
7792      (if_then_else (eq_attr "cpu" "athlon")
7793         (const_string "vector")
7794         (const_string "double")))
7795    (set_attr "amdfam10_decode" "double")
7796    (set_attr "mode" "DI")])
7797
7798 (define_expand "mulsidi3"
7799   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7800                    (mult:DI (sign_extend:DI
7801                               (match_operand:SI 1 "nonimmediate_operand" ""))
7802                             (sign_extend:DI
7803                               (match_operand:SI 2 "register_operand" ""))))
7804               (clobber (reg:CC FLAGS_REG))])]
7805   "!TARGET_64BIT"
7806   "")
7807
7808 (define_insn "*mulsidi3_insn"
7809   [(set (match_operand:DI 0 "register_operand" "=A")
7810         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7811                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7812    (clobber (reg:CC FLAGS_REG))]
7813   "!TARGET_64BIT
7814    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7815   "imul{l}\t%2"
7816   [(set_attr "type" "imul")
7817    (set_attr "length_immediate" "0")
7818    (set (attr "athlon_decode")
7819      (if_then_else (eq_attr "cpu" "athlon")
7820         (const_string "vector")
7821         (const_string "double")))
7822    (set_attr "amdfam10_decode" "double")        
7823    (set_attr "mode" "SI")])
7824
7825 (define_expand "umuldi3_highpart"
7826   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7827                    (truncate:DI
7828                      (lshiftrt:TI
7829                        (mult:TI (zero_extend:TI
7830                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7831                                 (zero_extend:TI
7832                                   (match_operand:DI 2 "register_operand" "")))
7833                        (const_int 64))))
7834               (clobber (match_scratch:DI 3 ""))
7835               (clobber (reg:CC FLAGS_REG))])]
7836   "TARGET_64BIT"
7837   "")
7838
7839 (define_insn "*umuldi3_highpart_rex64"
7840   [(set (match_operand:DI 0 "register_operand" "=d")
7841         (truncate:DI
7842           (lshiftrt:TI
7843             (mult:TI (zero_extend:TI
7844                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7845                      (zero_extend:TI
7846                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7847             (const_int 64))))
7848    (clobber (match_scratch:DI 3 "=1"))
7849    (clobber (reg:CC FLAGS_REG))]
7850   "TARGET_64BIT
7851    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7852   "mul{q}\t%2"
7853   [(set_attr "type" "imul")
7854    (set_attr "length_immediate" "0")
7855    (set (attr "athlon_decode")
7856      (if_then_else (eq_attr "cpu" "athlon")
7857         (const_string "vector")
7858         (const_string "double")))
7859    (set_attr "amdfam10_decode" "double")        
7860    (set_attr "mode" "DI")])
7861
7862 (define_expand "umulsi3_highpart"
7863   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7864                    (truncate:SI
7865                      (lshiftrt:DI
7866                        (mult:DI (zero_extend:DI
7867                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7868                                 (zero_extend:DI
7869                                   (match_operand:SI 2 "register_operand" "")))
7870                        (const_int 32))))
7871               (clobber (match_scratch:SI 3 ""))
7872               (clobber (reg:CC FLAGS_REG))])]
7873   ""
7874   "")
7875
7876 (define_insn "*umulsi3_highpart_insn"
7877   [(set (match_operand:SI 0 "register_operand" "=d")
7878         (truncate:SI
7879           (lshiftrt:DI
7880             (mult:DI (zero_extend:DI
7881                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7882                      (zero_extend:DI
7883                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7884             (const_int 32))))
7885    (clobber (match_scratch:SI 3 "=1"))
7886    (clobber (reg:CC FLAGS_REG))]
7887   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7888   "mul{l}\t%2"
7889   [(set_attr "type" "imul")
7890    (set_attr "length_immediate" "0")
7891    (set (attr "athlon_decode")
7892      (if_then_else (eq_attr "cpu" "athlon")
7893         (const_string "vector")
7894         (const_string "double")))
7895    (set_attr "amdfam10_decode" "double")
7896    (set_attr "mode" "SI")])
7897
7898 (define_insn "*umulsi3_highpart_zext"
7899   [(set (match_operand:DI 0 "register_operand" "=d")
7900         (zero_extend:DI (truncate:SI
7901           (lshiftrt:DI
7902             (mult:DI (zero_extend:DI
7903                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7904                      (zero_extend:DI
7905                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7906             (const_int 32)))))
7907    (clobber (match_scratch:SI 3 "=1"))
7908    (clobber (reg:CC FLAGS_REG))]
7909   "TARGET_64BIT
7910    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7911   "mul{l}\t%2"
7912   [(set_attr "type" "imul")
7913    (set_attr "length_immediate" "0")
7914    (set (attr "athlon_decode")
7915      (if_then_else (eq_attr "cpu" "athlon")
7916         (const_string "vector")
7917         (const_string "double")))
7918    (set_attr "amdfam10_decode" "double")
7919    (set_attr "mode" "SI")])
7920
7921 (define_expand "smuldi3_highpart"
7922   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7923                    (truncate:DI
7924                      (lshiftrt:TI
7925                        (mult:TI (sign_extend:TI
7926                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7927                                 (sign_extend:TI
7928                                   (match_operand:DI 2 "register_operand" "")))
7929                        (const_int 64))))
7930               (clobber (match_scratch:DI 3 ""))
7931               (clobber (reg:CC FLAGS_REG))])]
7932   "TARGET_64BIT"
7933   "")
7934
7935 (define_insn "*smuldi3_highpart_rex64"
7936   [(set (match_operand:DI 0 "register_operand" "=d")
7937         (truncate:DI
7938           (lshiftrt:TI
7939             (mult:TI (sign_extend:TI
7940                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7941                      (sign_extend:TI
7942                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7943             (const_int 64))))
7944    (clobber (match_scratch:DI 3 "=1"))
7945    (clobber (reg:CC FLAGS_REG))]
7946   "TARGET_64BIT
7947    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7948   "imul{q}\t%2"
7949   [(set_attr "type" "imul")
7950    (set (attr "athlon_decode")
7951      (if_then_else (eq_attr "cpu" "athlon")
7952         (const_string "vector")
7953         (const_string "double")))
7954    (set_attr "amdfam10_decode" "double")
7955    (set_attr "mode" "DI")])
7956
7957 (define_expand "smulsi3_highpart"
7958   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7959                    (truncate:SI
7960                      (lshiftrt:DI
7961                        (mult:DI (sign_extend:DI
7962                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7963                                 (sign_extend:DI
7964                                   (match_operand:SI 2 "register_operand" "")))
7965                        (const_int 32))))
7966               (clobber (match_scratch:SI 3 ""))
7967               (clobber (reg:CC FLAGS_REG))])]
7968   ""
7969   "")
7970
7971 (define_insn "*smulsi3_highpart_insn"
7972   [(set (match_operand:SI 0 "register_operand" "=d")
7973         (truncate:SI
7974           (lshiftrt:DI
7975             (mult:DI (sign_extend:DI
7976                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7977                      (sign_extend:DI
7978                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7979             (const_int 32))))
7980    (clobber (match_scratch:SI 3 "=1"))
7981    (clobber (reg:CC FLAGS_REG))]
7982   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7983   "imul{l}\t%2"
7984   [(set_attr "type" "imul")
7985    (set (attr "athlon_decode")
7986      (if_then_else (eq_attr "cpu" "athlon")
7987         (const_string "vector")
7988         (const_string "double")))
7989    (set_attr "amdfam10_decode" "double")
7990    (set_attr "mode" "SI")])
7991
7992 (define_insn "*smulsi3_highpart_zext"
7993   [(set (match_operand:DI 0 "register_operand" "=d")
7994         (zero_extend:DI (truncate:SI
7995           (lshiftrt:DI
7996             (mult:DI (sign_extend:DI
7997                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7998                      (sign_extend:DI
7999                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8000             (const_int 32)))))
8001    (clobber (match_scratch:SI 3 "=1"))
8002    (clobber (reg:CC FLAGS_REG))]
8003   "TARGET_64BIT
8004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005   "imul{l}\t%2"
8006   [(set_attr "type" "imul")
8007    (set (attr "athlon_decode")
8008      (if_then_else (eq_attr "cpu" "athlon")
8009         (const_string "vector")
8010         (const_string "double")))
8011    (set_attr "amdfam10_decode" "double")
8012    (set_attr "mode" "SI")])
8013
8014 ;; The patterns that match these are at the end of this file.
8015
8016 (define_expand "mulxf3"
8017   [(set (match_operand:XF 0 "register_operand" "")
8018         (mult:XF (match_operand:XF 1 "register_operand" "")
8019                  (match_operand:XF 2 "register_operand" "")))]
8020   "TARGET_80387"
8021   "")
8022
8023 (define_expand "mul<mode>3"
8024   [(set (match_operand:MODEF 0 "register_operand" "")
8025         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8026                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8027   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8028   "")
8029
8030 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8031
8032 \f
8033 ;; Divide instructions
8034
8035 (define_insn "divqi3"
8036   [(set (match_operand:QI 0 "register_operand" "=a")
8037         (div:QI (match_operand:HI 1 "register_operand" "0")
8038                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8039    (clobber (reg:CC FLAGS_REG))]
8040   "TARGET_QIMODE_MATH"
8041   "idiv{b}\t%2"
8042   [(set_attr "type" "idiv")
8043    (set_attr "mode" "QI")])
8044
8045 (define_insn "udivqi3"
8046   [(set (match_operand:QI 0 "register_operand" "=a")
8047         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8048                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8049    (clobber (reg:CC FLAGS_REG))]
8050   "TARGET_QIMODE_MATH"
8051   "div{b}\t%2"
8052   [(set_attr "type" "idiv")
8053    (set_attr "mode" "QI")])
8054
8055 ;; The patterns that match these are at the end of this file.
8056
8057 (define_expand "divxf3"
8058   [(set (match_operand:XF 0 "register_operand" "")
8059         (div:XF (match_operand:XF 1 "register_operand" "")
8060                 (match_operand:XF 2 "register_operand" "")))]
8061   "TARGET_80387"
8062   "")
8063
8064 (define_expand "divdf3"
8065   [(set (match_operand:DF 0 "register_operand" "")
8066         (div:DF (match_operand:DF 1 "register_operand" "")
8067                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8068    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8069    "")
8070
8071 (define_expand "divsf3"
8072   [(set (match_operand:SF 0 "register_operand" "")
8073         (div:SF (match_operand:SF 1 "register_operand" "")
8074                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8075   "TARGET_80387 || TARGET_SSE_MATH"
8076 {
8077   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8078       && flag_finite_math_only && !flag_trapping_math
8079       && flag_unsafe_math_optimizations)
8080     {
8081       ix86_emit_swdivsf (operands[0], operands[1],
8082                          operands[2], SFmode);
8083       DONE;
8084     }
8085 })
8086 \f
8087 ;; Remainder instructions.
8088
8089 (define_expand "divmoddi4"
8090   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8091                    (div:DI (match_operand:DI 1 "register_operand" "")
8092                            (match_operand:DI 2 "nonimmediate_operand" "")))
8093               (set (match_operand:DI 3 "register_operand" "")
8094                    (mod:DI (match_dup 1) (match_dup 2)))
8095               (clobber (reg:CC FLAGS_REG))])]
8096   "TARGET_64BIT"
8097   "")
8098
8099 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8100 ;; Penalize eax case slightly because it results in worse scheduling
8101 ;; of code.
8102 (define_insn "*divmoddi4_nocltd_rex64"
8103   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8104         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8105                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8106    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8107         (mod:DI (match_dup 2) (match_dup 3)))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8110   "#"
8111   [(set_attr "type" "multi")])
8112
8113 (define_insn "*divmoddi4_cltd_rex64"
8114   [(set (match_operand:DI 0 "register_operand" "=a")
8115         (div:DI (match_operand:DI 2 "register_operand" "a")
8116                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8117    (set (match_operand:DI 1 "register_operand" "=&d")
8118         (mod:DI (match_dup 2) (match_dup 3)))
8119    (clobber (reg:CC FLAGS_REG))]
8120   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8121   "#"
8122   [(set_attr "type" "multi")])
8123
8124 (define_insn "*divmoddi_noext_rex64"
8125   [(set (match_operand:DI 0 "register_operand" "=a")
8126         (div:DI (match_operand:DI 1 "register_operand" "0")
8127                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8128    (set (match_operand:DI 3 "register_operand" "=d")
8129         (mod:DI (match_dup 1) (match_dup 2)))
8130    (use (match_operand:DI 4 "register_operand" "3"))
8131    (clobber (reg:CC FLAGS_REG))]
8132   "TARGET_64BIT"
8133   "idiv{q}\t%2"
8134   [(set_attr "type" "idiv")
8135    (set_attr "mode" "DI")])
8136
8137 (define_split
8138   [(set (match_operand:DI 0 "register_operand" "")
8139         (div:DI (match_operand:DI 1 "register_operand" "")
8140                 (match_operand:DI 2 "nonimmediate_operand" "")))
8141    (set (match_operand:DI 3 "register_operand" "")
8142         (mod:DI (match_dup 1) (match_dup 2)))
8143    (clobber (reg:CC FLAGS_REG))]
8144   "TARGET_64BIT && reload_completed"
8145   [(parallel [(set (match_dup 3)
8146                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8147               (clobber (reg:CC FLAGS_REG))])
8148    (parallel [(set (match_dup 0)
8149                    (div:DI (reg:DI 0) (match_dup 2)))
8150               (set (match_dup 3)
8151                    (mod:DI (reg:DI 0) (match_dup 2)))
8152               (use (match_dup 3))
8153               (clobber (reg:CC FLAGS_REG))])]
8154 {
8155   /* Avoid use of cltd in favor of a mov+shift.  */
8156   if (!TARGET_USE_CLTD && !optimize_size)
8157     {
8158       if (true_regnum (operands[1]))
8159         emit_move_insn (operands[0], operands[1]);
8160       else
8161         emit_move_insn (operands[3], operands[1]);
8162       operands[4] = operands[3];
8163     }
8164   else
8165     {
8166       gcc_assert (!true_regnum (operands[1]));
8167       operands[4] = operands[1];
8168     }
8169 })
8170
8171
8172 (define_expand "divmodsi4"
8173   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8174                    (div:SI (match_operand:SI 1 "register_operand" "")
8175                            (match_operand:SI 2 "nonimmediate_operand" "")))
8176               (set (match_operand:SI 3 "register_operand" "")
8177                    (mod:SI (match_dup 1) (match_dup 2)))
8178               (clobber (reg:CC FLAGS_REG))])]
8179   ""
8180   "")
8181
8182 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8183 ;; Penalize eax case slightly because it results in worse scheduling
8184 ;; of code.
8185 (define_insn "*divmodsi4_nocltd"
8186   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8187         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8188                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8189    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8190         (mod:SI (match_dup 2) (match_dup 3)))
8191    (clobber (reg:CC FLAGS_REG))]
8192   "!optimize_size && !TARGET_USE_CLTD"
8193   "#"
8194   [(set_attr "type" "multi")])
8195
8196 (define_insn "*divmodsi4_cltd"
8197   [(set (match_operand:SI 0 "register_operand" "=a")
8198         (div:SI (match_operand:SI 2 "register_operand" "a")
8199                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8200    (set (match_operand:SI 1 "register_operand" "=&d")
8201         (mod:SI (match_dup 2) (match_dup 3)))
8202    (clobber (reg:CC FLAGS_REG))]
8203   "optimize_size || TARGET_USE_CLTD"
8204   "#"
8205   [(set_attr "type" "multi")])
8206
8207 (define_insn "*divmodsi_noext"
8208   [(set (match_operand:SI 0 "register_operand" "=a")
8209         (div:SI (match_operand:SI 1 "register_operand" "0")
8210                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8211    (set (match_operand:SI 3 "register_operand" "=d")
8212         (mod:SI (match_dup 1) (match_dup 2)))
8213    (use (match_operand:SI 4 "register_operand" "3"))
8214    (clobber (reg:CC FLAGS_REG))]
8215   ""
8216   "idiv{l}\t%2"
8217   [(set_attr "type" "idiv")
8218    (set_attr "mode" "SI")])
8219
8220 (define_split
8221   [(set (match_operand:SI 0 "register_operand" "")
8222         (div:SI (match_operand:SI 1 "register_operand" "")
8223                 (match_operand:SI 2 "nonimmediate_operand" "")))
8224    (set (match_operand:SI 3 "register_operand" "")
8225         (mod:SI (match_dup 1) (match_dup 2)))
8226    (clobber (reg:CC FLAGS_REG))]
8227   "reload_completed"
8228   [(parallel [(set (match_dup 3)
8229                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8230               (clobber (reg:CC FLAGS_REG))])
8231    (parallel [(set (match_dup 0)
8232                    (div:SI (reg:SI 0) (match_dup 2)))
8233               (set (match_dup 3)
8234                    (mod:SI (reg:SI 0) (match_dup 2)))
8235               (use (match_dup 3))
8236               (clobber (reg:CC FLAGS_REG))])]
8237 {
8238   /* Avoid use of cltd in favor of a mov+shift.  */
8239   if (!TARGET_USE_CLTD && !optimize_size)
8240     {
8241       if (true_regnum (operands[1]))
8242         emit_move_insn (operands[0], operands[1]);
8243       else
8244         emit_move_insn (operands[3], operands[1]);
8245       operands[4] = operands[3];
8246     }
8247   else
8248     {
8249       gcc_assert (!true_regnum (operands[1]));
8250       operands[4] = operands[1];
8251     }
8252 })
8253 ;; %%% Split me.
8254 (define_insn "divmodhi4"
8255   [(set (match_operand:HI 0 "register_operand" "=a")
8256         (div:HI (match_operand:HI 1 "register_operand" "0")
8257                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8258    (set (match_operand:HI 3 "register_operand" "=&d")
8259         (mod:HI (match_dup 1) (match_dup 2)))
8260    (clobber (reg:CC FLAGS_REG))]
8261   "TARGET_HIMODE_MATH"
8262   "cwtd\;idiv{w}\t%2"
8263   [(set_attr "type" "multi")
8264    (set_attr "length_immediate" "0")
8265    (set_attr "mode" "SI")])
8266
8267 (define_insn "udivmoddi4"
8268   [(set (match_operand:DI 0 "register_operand" "=a")
8269         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8270                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8271    (set (match_operand:DI 3 "register_operand" "=&d")
8272         (umod:DI (match_dup 1) (match_dup 2)))
8273    (clobber (reg:CC FLAGS_REG))]
8274   "TARGET_64BIT"
8275   "xor{q}\t%3, %3\;div{q}\t%2"
8276   [(set_attr "type" "multi")
8277    (set_attr "length_immediate" "0")
8278    (set_attr "mode" "DI")])
8279
8280 (define_insn "*udivmoddi4_noext"
8281   [(set (match_operand:DI 0 "register_operand" "=a")
8282         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8283                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8284    (set (match_operand:DI 3 "register_operand" "=d")
8285         (umod:DI (match_dup 1) (match_dup 2)))
8286    (use (match_dup 3))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_64BIT"
8289   "div{q}\t%2"
8290   [(set_attr "type" "idiv")
8291    (set_attr "mode" "DI")])
8292
8293 (define_split
8294   [(set (match_operand:DI 0 "register_operand" "")
8295         (udiv:DI (match_operand:DI 1 "register_operand" "")
8296                  (match_operand:DI 2 "nonimmediate_operand" "")))
8297    (set (match_operand:DI 3 "register_operand" "")
8298         (umod:DI (match_dup 1) (match_dup 2)))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "TARGET_64BIT && reload_completed"
8301   [(set (match_dup 3) (const_int 0))
8302    (parallel [(set (match_dup 0)
8303                    (udiv:DI (match_dup 1) (match_dup 2)))
8304               (set (match_dup 3)
8305                    (umod:DI (match_dup 1) (match_dup 2)))
8306               (use (match_dup 3))
8307               (clobber (reg:CC FLAGS_REG))])]
8308   "")
8309
8310 (define_insn "udivmodsi4"
8311   [(set (match_operand:SI 0 "register_operand" "=a")
8312         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8313                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8314    (set (match_operand:SI 3 "register_operand" "=&d")
8315         (umod:SI (match_dup 1) (match_dup 2)))
8316    (clobber (reg:CC FLAGS_REG))]
8317   ""
8318   "xor{l}\t%3, %3\;div{l}\t%2"
8319   [(set_attr "type" "multi")
8320    (set_attr "length_immediate" "0")
8321    (set_attr "mode" "SI")])
8322
8323 (define_insn "*udivmodsi4_noext"
8324   [(set (match_operand:SI 0 "register_operand" "=a")
8325         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8326                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8327    (set (match_operand:SI 3 "register_operand" "=d")
8328         (umod:SI (match_dup 1) (match_dup 2)))
8329    (use (match_dup 3))
8330    (clobber (reg:CC FLAGS_REG))]
8331   ""
8332   "div{l}\t%2"
8333   [(set_attr "type" "idiv")
8334    (set_attr "mode" "SI")])
8335
8336 (define_split
8337   [(set (match_operand:SI 0 "register_operand" "")
8338         (udiv:SI (match_operand:SI 1 "register_operand" "")
8339                  (match_operand:SI 2 "nonimmediate_operand" "")))
8340    (set (match_operand:SI 3 "register_operand" "")
8341         (umod:SI (match_dup 1) (match_dup 2)))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "reload_completed"
8344   [(set (match_dup 3) (const_int 0))
8345    (parallel [(set (match_dup 0)
8346                    (udiv:SI (match_dup 1) (match_dup 2)))
8347               (set (match_dup 3)
8348                    (umod:SI (match_dup 1) (match_dup 2)))
8349               (use (match_dup 3))
8350               (clobber (reg:CC FLAGS_REG))])]
8351   "")
8352
8353 (define_expand "udivmodhi4"
8354   [(set (match_dup 4) (const_int 0))
8355    (parallel [(set (match_operand:HI 0 "register_operand" "")
8356                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8357                             (match_operand:HI 2 "nonimmediate_operand" "")))
8358               (set (match_operand:HI 3 "register_operand" "")
8359                    (umod:HI (match_dup 1) (match_dup 2)))
8360               (use (match_dup 4))
8361               (clobber (reg:CC FLAGS_REG))])]
8362   "TARGET_HIMODE_MATH"
8363   "operands[4] = gen_reg_rtx (HImode);")
8364
8365 (define_insn "*udivmodhi_noext"
8366   [(set (match_operand:HI 0 "register_operand" "=a")
8367         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8368                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8369    (set (match_operand:HI 3 "register_operand" "=d")
8370         (umod:HI (match_dup 1) (match_dup 2)))
8371    (use (match_operand:HI 4 "register_operand" "3"))
8372    (clobber (reg:CC FLAGS_REG))]
8373   ""
8374   "div{w}\t%2"
8375   [(set_attr "type" "idiv")
8376    (set_attr "mode" "HI")])
8377
8378 ;; We cannot use div/idiv for double division, because it causes
8379 ;; "division by zero" on the overflow and that's not what we expect
8380 ;; from truncate.  Because true (non truncating) double division is
8381 ;; never generated, we can't create this insn anyway.
8382 ;
8383 ;(define_insn ""
8384 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8385 ;       (truncate:SI
8386 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8387 ;                  (zero_extend:DI
8388 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8389 ;   (set (match_operand:SI 3 "register_operand" "=d")
8390 ;       (truncate:SI
8391 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8392 ;   (clobber (reg:CC FLAGS_REG))]
8393 ;  ""
8394 ;  "div{l}\t{%2, %0|%0, %2}"
8395 ;  [(set_attr "type" "idiv")])
8396 \f
8397 ;;- Logical AND instructions
8398
8399 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8400 ;; Note that this excludes ah.
8401
8402 (define_insn "*testdi_1_rex64"
8403   [(set (reg FLAGS_REG)
8404         (compare
8405           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8406                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8407           (const_int 0)))]
8408   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8409    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8410   "@
8411    test{l}\t{%k1, %k0|%k0, %k1}
8412    test{l}\t{%k1, %k0|%k0, %k1}
8413    test{q}\t{%1, %0|%0, %1}
8414    test{q}\t{%1, %0|%0, %1}
8415    test{q}\t{%1, %0|%0, %1}"
8416   [(set_attr "type" "test")
8417    (set_attr "modrm" "0,1,0,1,1")
8418    (set_attr "mode" "SI,SI,DI,DI,DI")
8419    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8420
8421 (define_insn "testsi_1"
8422   [(set (reg FLAGS_REG)
8423         (compare
8424           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8425                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8426           (const_int 0)))]
8427   "ix86_match_ccmode (insn, CCNOmode)
8428    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8429   "test{l}\t{%1, %0|%0, %1}"
8430   [(set_attr "type" "test")
8431    (set_attr "modrm" "0,1,1")
8432    (set_attr "mode" "SI")
8433    (set_attr "pent_pair" "uv,np,uv")])
8434
8435 (define_expand "testsi_ccno_1"
8436   [(set (reg:CCNO FLAGS_REG)
8437         (compare:CCNO
8438           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8439                   (match_operand:SI 1 "nonmemory_operand" ""))
8440           (const_int 0)))]
8441   ""
8442   "")
8443
8444 (define_insn "*testhi_1"
8445   [(set (reg FLAGS_REG)
8446         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8447                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8448                  (const_int 0)))]
8449   "ix86_match_ccmode (insn, CCNOmode)
8450    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8451   "test{w}\t{%1, %0|%0, %1}"
8452   [(set_attr "type" "test")
8453    (set_attr "modrm" "0,1,1")
8454    (set_attr "mode" "HI")
8455    (set_attr "pent_pair" "uv,np,uv")])
8456
8457 (define_expand "testqi_ccz_1"
8458   [(set (reg:CCZ FLAGS_REG)
8459         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8460                              (match_operand:QI 1 "nonmemory_operand" ""))
8461                  (const_int 0)))]
8462   ""
8463   "")
8464
8465 (define_insn "*testqi_1_maybe_si"
8466   [(set (reg FLAGS_REG)
8467         (compare
8468           (and:QI
8469             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8470             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8471           (const_int 0)))]
8472    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8473     && ix86_match_ccmode (insn,
8474                          CONST_INT_P (operands[1])
8475                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8476 {
8477   if (which_alternative == 3)
8478     {
8479       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8480         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8481       return "test{l}\t{%1, %k0|%k0, %1}";
8482     }
8483   return "test{b}\t{%1, %0|%0, %1}";
8484 }
8485   [(set_attr "type" "test")
8486    (set_attr "modrm" "0,1,1,1")
8487    (set_attr "mode" "QI,QI,QI,SI")
8488    (set_attr "pent_pair" "uv,np,uv,np")])
8489
8490 (define_insn "*testqi_1"
8491   [(set (reg FLAGS_REG)
8492         (compare
8493           (and:QI
8494             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8495             (match_operand:QI 1 "general_operand" "n,n,qn"))
8496           (const_int 0)))]
8497   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8498    && ix86_match_ccmode (insn, CCNOmode)"
8499   "test{b}\t{%1, %0|%0, %1}"
8500   [(set_attr "type" "test")
8501    (set_attr "modrm" "0,1,1")
8502    (set_attr "mode" "QI")
8503    (set_attr "pent_pair" "uv,np,uv")])
8504
8505 (define_expand "testqi_ext_ccno_0"
8506   [(set (reg:CCNO FLAGS_REG)
8507         (compare:CCNO
8508           (and:SI
8509             (zero_extract:SI
8510               (match_operand 0 "ext_register_operand" "")
8511               (const_int 8)
8512               (const_int 8))
8513             (match_operand 1 "const_int_operand" ""))
8514           (const_int 0)))]
8515   ""
8516   "")
8517
8518 (define_insn "*testqi_ext_0"
8519   [(set (reg FLAGS_REG)
8520         (compare
8521           (and:SI
8522             (zero_extract:SI
8523               (match_operand 0 "ext_register_operand" "Q")
8524               (const_int 8)
8525               (const_int 8))
8526             (match_operand 1 "const_int_operand" "n"))
8527           (const_int 0)))]
8528   "ix86_match_ccmode (insn, CCNOmode)"
8529   "test{b}\t{%1, %h0|%h0, %1}"
8530   [(set_attr "type" "test")
8531    (set_attr "mode" "QI")
8532    (set_attr "length_immediate" "1")
8533    (set_attr "pent_pair" "np")])
8534
8535 (define_insn "*testqi_ext_1"
8536   [(set (reg FLAGS_REG)
8537         (compare
8538           (and:SI
8539             (zero_extract:SI
8540               (match_operand 0 "ext_register_operand" "Q")
8541               (const_int 8)
8542               (const_int 8))
8543             (zero_extend:SI
8544               (match_operand:QI 1 "general_operand" "Qm")))
8545           (const_int 0)))]
8546   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8548   "test{b}\t{%1, %h0|%h0, %1}"
8549   [(set_attr "type" "test")
8550    (set_attr "mode" "QI")])
8551
8552 (define_insn "*testqi_ext_1_rex64"
8553   [(set (reg FLAGS_REG)
8554         (compare
8555           (and:SI
8556             (zero_extract:SI
8557               (match_operand 0 "ext_register_operand" "Q")
8558               (const_int 8)
8559               (const_int 8))
8560             (zero_extend:SI
8561               (match_operand:QI 1 "register_operand" "Q")))
8562           (const_int 0)))]
8563   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8564   "test{b}\t{%1, %h0|%h0, %1}"
8565   [(set_attr "type" "test")
8566    (set_attr "mode" "QI")])
8567
8568 (define_insn "*testqi_ext_2"
8569   [(set (reg FLAGS_REG)
8570         (compare
8571           (and:SI
8572             (zero_extract:SI
8573               (match_operand 0 "ext_register_operand" "Q")
8574               (const_int 8)
8575               (const_int 8))
8576             (zero_extract:SI
8577               (match_operand 1 "ext_register_operand" "Q")
8578               (const_int 8)
8579               (const_int 8)))
8580           (const_int 0)))]
8581   "ix86_match_ccmode (insn, CCNOmode)"
8582   "test{b}\t{%h1, %h0|%h0, %h1}"
8583   [(set_attr "type" "test")
8584    (set_attr "mode" "QI")])
8585
8586 ;; Combine likes to form bit extractions for some tests.  Humor it.
8587 (define_insn "*testqi_ext_3"
8588   [(set (reg FLAGS_REG)
8589         (compare (zero_extract:SI
8590                    (match_operand 0 "nonimmediate_operand" "rm")
8591                    (match_operand:SI 1 "const_int_operand" "")
8592                    (match_operand:SI 2 "const_int_operand" ""))
8593                  (const_int 0)))]
8594   "ix86_match_ccmode (insn, CCNOmode)
8595    && INTVAL (operands[1]) > 0
8596    && INTVAL (operands[2]) >= 0
8597    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8598    && (GET_MODE (operands[0]) == SImode
8599        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8600        || GET_MODE (operands[0]) == HImode
8601        || GET_MODE (operands[0]) == QImode)"
8602   "#")
8603
8604 (define_insn "*testqi_ext_3_rex64"
8605   [(set (reg FLAGS_REG)
8606         (compare (zero_extract:DI
8607                    (match_operand 0 "nonimmediate_operand" "rm")
8608                    (match_operand:DI 1 "const_int_operand" "")
8609                    (match_operand:DI 2 "const_int_operand" ""))
8610                  (const_int 0)))]
8611   "TARGET_64BIT
8612    && ix86_match_ccmode (insn, CCNOmode)
8613    && INTVAL (operands[1]) > 0
8614    && INTVAL (operands[2]) >= 0
8615    /* Ensure that resulting mask is zero or sign extended operand.  */
8616    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8617        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8618            && INTVAL (operands[1]) > 32))
8619    && (GET_MODE (operands[0]) == SImode
8620        || GET_MODE (operands[0]) == DImode
8621        || GET_MODE (operands[0]) == HImode
8622        || GET_MODE (operands[0]) == QImode)"
8623   "#")
8624
8625 (define_split
8626   [(set (match_operand 0 "flags_reg_operand" "")
8627         (match_operator 1 "compare_operator"
8628           [(zero_extract
8629              (match_operand 2 "nonimmediate_operand" "")
8630              (match_operand 3 "const_int_operand" "")
8631              (match_operand 4 "const_int_operand" ""))
8632            (const_int 0)]))]
8633   "ix86_match_ccmode (insn, CCNOmode)"
8634   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8635 {
8636   rtx val = operands[2];
8637   HOST_WIDE_INT len = INTVAL (operands[3]);
8638   HOST_WIDE_INT pos = INTVAL (operands[4]);
8639   HOST_WIDE_INT mask;
8640   enum machine_mode mode, submode;
8641
8642   mode = GET_MODE (val);
8643   if (MEM_P (val))
8644     {
8645       /* ??? Combine likes to put non-volatile mem extractions in QImode
8646          no matter the size of the test.  So find a mode that works.  */
8647       if (! MEM_VOLATILE_P (val))
8648         {
8649           mode = smallest_mode_for_size (pos + len, MODE_INT);
8650           val = adjust_address (val, mode, 0);
8651         }
8652     }
8653   else if (GET_CODE (val) == SUBREG
8654            && (submode = GET_MODE (SUBREG_REG (val)),
8655                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8656            && pos + len <= GET_MODE_BITSIZE (submode))
8657     {
8658       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8659       mode = submode;
8660       val = SUBREG_REG (val);
8661     }
8662   else if (mode == HImode && pos + len <= 8)
8663     {
8664       /* Small HImode tests can be converted to QImode.  */
8665       mode = QImode;
8666       val = gen_lowpart (QImode, val);
8667     }
8668
8669   if (len == HOST_BITS_PER_WIDE_INT)
8670     mask = -1;
8671   else
8672     mask = ((HOST_WIDE_INT)1 << len) - 1;
8673   mask <<= pos;
8674
8675   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8676 })
8677
8678 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8679 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8680 ;; this is relatively important trick.
8681 ;; Do the conversion only post-reload to avoid limiting of the register class
8682 ;; to QI regs.
8683 (define_split
8684   [(set (match_operand 0 "flags_reg_operand" "")
8685         (match_operator 1 "compare_operator"
8686           [(and (match_operand 2 "register_operand" "")
8687                 (match_operand 3 "const_int_operand" ""))
8688            (const_int 0)]))]
8689    "reload_completed
8690     && QI_REG_P (operands[2])
8691     && GET_MODE (operands[2]) != QImode
8692     && ((ix86_match_ccmode (insn, CCZmode)
8693          && !(INTVAL (operands[3]) & ~(255 << 8)))
8694         || (ix86_match_ccmode (insn, CCNOmode)
8695             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8696   [(set (match_dup 0)
8697         (match_op_dup 1
8698           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8699                    (match_dup 3))
8700            (const_int 0)]))]
8701   "operands[2] = gen_lowpart (SImode, operands[2]);
8702    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8703
8704 (define_split
8705   [(set (match_operand 0 "flags_reg_operand" "")
8706         (match_operator 1 "compare_operator"
8707           [(and (match_operand 2 "nonimmediate_operand" "")
8708                 (match_operand 3 "const_int_operand" ""))
8709            (const_int 0)]))]
8710    "reload_completed
8711     && GET_MODE (operands[2]) != QImode
8712     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8713     && ((ix86_match_ccmode (insn, CCZmode)
8714          && !(INTVAL (operands[3]) & ~255))
8715         || (ix86_match_ccmode (insn, CCNOmode)
8716             && !(INTVAL (operands[3]) & ~127)))"
8717   [(set (match_dup 0)
8718         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8719                          (const_int 0)]))]
8720   "operands[2] = gen_lowpart (QImode, operands[2]);
8721    operands[3] = gen_lowpart (QImode, operands[3]);")
8722
8723
8724 ;; %%% This used to optimize known byte-wide and operations to memory,
8725 ;; and sometimes to QImode registers.  If this is considered useful,
8726 ;; it should be done with splitters.
8727
8728 (define_expand "anddi3"
8729   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8730         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8731                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8732    (clobber (reg:CC FLAGS_REG))]
8733   "TARGET_64BIT"
8734   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8735
8736 (define_insn "*anddi_1_rex64"
8737   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8738         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8739                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8742 {
8743   switch (get_attr_type (insn))
8744     {
8745     case TYPE_IMOVX:
8746       {
8747         enum machine_mode mode;
8748
8749         gcc_assert (CONST_INT_P (operands[2]));
8750         if (INTVAL (operands[2]) == 0xff)
8751           mode = QImode;
8752         else
8753           {
8754             gcc_assert (INTVAL (operands[2]) == 0xffff);
8755             mode = HImode;
8756           }
8757
8758         operands[1] = gen_lowpart (mode, operands[1]);
8759         if (mode == QImode)
8760           return "movz{bq|x}\t{%1,%0|%0, %1}";
8761         else
8762           return "movz{wq|x}\t{%1,%0|%0, %1}";
8763       }
8764
8765     default:
8766       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8767       if (get_attr_mode (insn) == MODE_SI)
8768         return "and{l}\t{%k2, %k0|%k0, %k2}";
8769       else
8770         return "and{q}\t{%2, %0|%0, %2}";
8771     }
8772 }
8773   [(set_attr "type" "alu,alu,alu,imovx")
8774    (set_attr "length_immediate" "*,*,*,0")
8775    (set_attr "mode" "SI,DI,DI,DI")])
8776
8777 (define_insn "*anddi_2"
8778   [(set (reg FLAGS_REG)
8779         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8780                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8781                  (const_int 0)))
8782    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8783         (and:DI (match_dup 1) (match_dup 2)))]
8784   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8785    && ix86_binary_operator_ok (AND, DImode, operands)"
8786   "@
8787    and{l}\t{%k2, %k0|%k0, %k2}
8788    and{q}\t{%2, %0|%0, %2}
8789    and{q}\t{%2, %0|%0, %2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "SI,DI,DI")])
8792
8793 (define_expand "andsi3"
8794   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8795         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8796                 (match_operand:SI 2 "general_operand" "")))
8797    (clobber (reg:CC FLAGS_REG))]
8798   ""
8799   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8800
8801 (define_insn "*andsi_1"
8802   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8803         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8804                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8805    (clobber (reg:CC FLAGS_REG))]
8806   "ix86_binary_operator_ok (AND, SImode, operands)"
8807 {
8808   switch (get_attr_type (insn))
8809     {
8810     case TYPE_IMOVX:
8811       {
8812         enum machine_mode mode;
8813
8814         gcc_assert (CONST_INT_P (operands[2]));
8815         if (INTVAL (operands[2]) == 0xff)
8816           mode = QImode;
8817         else
8818           {
8819             gcc_assert (INTVAL (operands[2]) == 0xffff);
8820             mode = HImode;
8821           }
8822
8823         operands[1] = gen_lowpart (mode, operands[1]);
8824         if (mode == QImode)
8825           return "movz{bl|x}\t{%1,%0|%0, %1}";
8826         else
8827           return "movz{wl|x}\t{%1,%0|%0, %1}";
8828       }
8829
8830     default:
8831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8832       return "and{l}\t{%2, %0|%0, %2}";
8833     }
8834 }
8835   [(set_attr "type" "alu,alu,imovx")
8836    (set_attr "length_immediate" "*,*,0")
8837    (set_attr "mode" "SI")])
8838
8839 (define_split
8840   [(set (match_operand 0 "register_operand" "")
8841         (and (match_dup 0)
8842              (const_int -65536)))
8843    (clobber (reg:CC FLAGS_REG))]
8844   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8845   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8846   "operands[1] = gen_lowpart (HImode, operands[0]);")
8847
8848 (define_split
8849   [(set (match_operand 0 "ext_register_operand" "")
8850         (and (match_dup 0)
8851              (const_int -256)))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8854   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8855   "operands[1] = gen_lowpart (QImode, operands[0]);")
8856
8857 (define_split
8858   [(set (match_operand 0 "ext_register_operand" "")
8859         (and (match_dup 0)
8860              (const_int -65281)))
8861    (clobber (reg:CC FLAGS_REG))]
8862   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8863   [(parallel [(set (zero_extract:SI (match_dup 0)
8864                                     (const_int 8)
8865                                     (const_int 8))
8866                    (xor:SI
8867                      (zero_extract:SI (match_dup 0)
8868                                       (const_int 8)
8869                                       (const_int 8))
8870                      (zero_extract:SI (match_dup 0)
8871                                       (const_int 8)
8872                                       (const_int 8))))
8873               (clobber (reg:CC FLAGS_REG))])]
8874   "operands[0] = gen_lowpart (SImode, operands[0]);")
8875
8876 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8877 (define_insn "*andsi_1_zext"
8878   [(set (match_operand:DI 0 "register_operand" "=r")
8879         (zero_extend:DI
8880           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8881                   (match_operand:SI 2 "general_operand" "g"))))
8882    (clobber (reg:CC FLAGS_REG))]
8883   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8884   "and{l}\t{%2, %k0|%k0, %2}"
8885   [(set_attr "type" "alu")
8886    (set_attr "mode" "SI")])
8887
8888 (define_insn "*andsi_2"
8889   [(set (reg FLAGS_REG)
8890         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8891                          (match_operand:SI 2 "general_operand" "g,ri"))
8892                  (const_int 0)))
8893    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8894         (and:SI (match_dup 1) (match_dup 2)))]
8895   "ix86_match_ccmode (insn, CCNOmode)
8896    && ix86_binary_operator_ok (AND, SImode, operands)"
8897   "and{l}\t{%2, %0|%0, %2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "SI")])
8900
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 (define_insn "*andsi_2_zext"
8903   [(set (reg FLAGS_REG)
8904         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8905                          (match_operand:SI 2 "general_operand" "g"))
8906                  (const_int 0)))
8907    (set (match_operand:DI 0 "register_operand" "=r")
8908         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8909   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8910    && ix86_binary_operator_ok (AND, SImode, operands)"
8911   "and{l}\t{%2, %k0|%k0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8914
8915 (define_expand "andhi3"
8916   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8917         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8918                 (match_operand:HI 2 "general_operand" "")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   "TARGET_HIMODE_MATH"
8921   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8922
8923 (define_insn "*andhi_1"
8924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8925         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8926                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8927    (clobber (reg:CC FLAGS_REG))]
8928   "ix86_binary_operator_ok (AND, HImode, operands)"
8929 {
8930   switch (get_attr_type (insn))
8931     {
8932     case TYPE_IMOVX:
8933       gcc_assert (CONST_INT_P (operands[2]));
8934       gcc_assert (INTVAL (operands[2]) == 0xff);
8935       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8936
8937     default:
8938       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8939
8940       return "and{w}\t{%2, %0|%0, %2}";
8941     }
8942 }
8943   [(set_attr "type" "alu,alu,imovx")
8944    (set_attr "length_immediate" "*,*,0")
8945    (set_attr "mode" "HI,HI,SI")])
8946
8947 (define_insn "*andhi_2"
8948   [(set (reg FLAGS_REG)
8949         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8950                          (match_operand:HI 2 "general_operand" "g,ri"))
8951                  (const_int 0)))
8952    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8953         (and:HI (match_dup 1) (match_dup 2)))]
8954   "ix86_match_ccmode (insn, CCNOmode)
8955    && ix86_binary_operator_ok (AND, HImode, operands)"
8956   "and{w}\t{%2, %0|%0, %2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "HI")])
8959
8960 (define_expand "andqi3"
8961   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8962         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8963                 (match_operand:QI 2 "general_operand" "")))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "TARGET_QIMODE_MATH"
8966   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8967
8968 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8969 (define_insn "*andqi_1"
8970   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8971         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8972                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "ix86_binary_operator_ok (AND, QImode, operands)"
8975   "@
8976    and{b}\t{%2, %0|%0, %2}
8977    and{b}\t{%2, %0|%0, %2}
8978    and{l}\t{%k2, %k0|%k0, %k2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "QI,QI,SI")])
8981
8982 (define_insn "*andqi_1_slp"
8983   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8984         (and:QI (match_dup 0)
8985                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8986    (clobber (reg:CC FLAGS_REG))]
8987   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8988    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8989   "and{b}\t{%1, %0|%0, %1}"
8990   [(set_attr "type" "alu1")
8991    (set_attr "mode" "QI")])
8992
8993 (define_insn "*andqi_2_maybe_si"
8994   [(set (reg FLAGS_REG)
8995         (compare (and:QI
8996                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8997                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8998                  (const_int 0)))
8999    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9000         (and:QI (match_dup 1) (match_dup 2)))]
9001   "ix86_binary_operator_ok (AND, QImode, operands)
9002    && ix86_match_ccmode (insn,
9003                          CONST_INT_P (operands[2])
9004                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9005 {
9006   if (which_alternative == 2)
9007     {
9008       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9009         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9010       return "and{l}\t{%2, %k0|%k0, %2}";
9011     }
9012   return "and{b}\t{%2, %0|%0, %2}";
9013 }
9014   [(set_attr "type" "alu")
9015    (set_attr "mode" "QI,QI,SI")])
9016
9017 (define_insn "*andqi_2"
9018   [(set (reg FLAGS_REG)
9019         (compare (and:QI
9020                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9021                    (match_operand:QI 2 "general_operand" "qim,qi"))
9022                  (const_int 0)))
9023    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9024         (and:QI (match_dup 1) (match_dup 2)))]
9025   "ix86_match_ccmode (insn, CCNOmode)
9026    && ix86_binary_operator_ok (AND, QImode, operands)"
9027   "and{b}\t{%2, %0|%0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "QI")])
9030
9031 (define_insn "*andqi_2_slp"
9032   [(set (reg FLAGS_REG)
9033         (compare (and:QI
9034                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9035                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9036                  (const_int 0)))
9037    (set (strict_low_part (match_dup 0))
9038         (and:QI (match_dup 0) (match_dup 1)))]
9039   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9040    && ix86_match_ccmode (insn, CCNOmode)
9041    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9042   "and{b}\t{%1, %0|%0, %1}"
9043   [(set_attr "type" "alu1")
9044    (set_attr "mode" "QI")])
9045
9046 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9047 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9048 ;; for a QImode operand, which of course failed.
9049
9050 (define_insn "andqi_ext_0"
9051   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9052                          (const_int 8)
9053                          (const_int 8))
9054         (and:SI
9055           (zero_extract:SI
9056             (match_operand 1 "ext_register_operand" "0")
9057             (const_int 8)
9058             (const_int 8))
9059           (match_operand 2 "const_int_operand" "n")))
9060    (clobber (reg:CC FLAGS_REG))]
9061   ""
9062   "and{b}\t{%2, %h0|%h0, %2}"
9063   [(set_attr "type" "alu")
9064    (set_attr "length_immediate" "1")
9065    (set_attr "mode" "QI")])
9066
9067 ;; Generated by peephole translating test to and.  This shows up
9068 ;; often in fp comparisons.
9069
9070 (define_insn "*andqi_ext_0_cc"
9071   [(set (reg FLAGS_REG)
9072         (compare
9073           (and:SI
9074             (zero_extract:SI
9075               (match_operand 1 "ext_register_operand" "0")
9076               (const_int 8)
9077               (const_int 8))
9078             (match_operand 2 "const_int_operand" "n"))
9079           (const_int 0)))
9080    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9081                          (const_int 8)
9082                          (const_int 8))
9083         (and:SI
9084           (zero_extract:SI
9085             (match_dup 1)
9086             (const_int 8)
9087             (const_int 8))
9088           (match_dup 2)))]
9089   "ix86_match_ccmode (insn, CCNOmode)"
9090   "and{b}\t{%2, %h0|%h0, %2}"
9091   [(set_attr "type" "alu")
9092    (set_attr "length_immediate" "1")
9093    (set_attr "mode" "QI")])
9094
9095 (define_insn "*andqi_ext_1"
9096   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9097                          (const_int 8)
9098                          (const_int 8))
9099         (and:SI
9100           (zero_extract:SI
9101             (match_operand 1 "ext_register_operand" "0")
9102             (const_int 8)
9103             (const_int 8))
9104           (zero_extend:SI
9105             (match_operand:QI 2 "general_operand" "Qm"))))
9106    (clobber (reg:CC FLAGS_REG))]
9107   "!TARGET_64BIT"
9108   "and{b}\t{%2, %h0|%h0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "length_immediate" "0")
9111    (set_attr "mode" "QI")])
9112
9113 (define_insn "*andqi_ext_1_rex64"
9114   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115                          (const_int 8)
9116                          (const_int 8))
9117         (and:SI
9118           (zero_extract:SI
9119             (match_operand 1 "ext_register_operand" "0")
9120             (const_int 8)
9121             (const_int 8))
9122           (zero_extend:SI
9123             (match_operand 2 "ext_register_operand" "Q"))))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "TARGET_64BIT"
9126   "and{b}\t{%2, %h0|%h0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "length_immediate" "0")
9129    (set_attr "mode" "QI")])
9130
9131 (define_insn "*andqi_ext_2"
9132   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9133                          (const_int 8)
9134                          (const_int 8))
9135         (and:SI
9136           (zero_extract:SI
9137             (match_operand 1 "ext_register_operand" "%0")
9138             (const_int 8)
9139             (const_int 8))
9140           (zero_extract:SI
9141             (match_operand 2 "ext_register_operand" "Q")
9142             (const_int 8)
9143             (const_int 8))))
9144    (clobber (reg:CC FLAGS_REG))]
9145   ""
9146   "and{b}\t{%h2, %h0|%h0, %h2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "length_immediate" "0")
9149    (set_attr "mode" "QI")])
9150
9151 ;; Convert wide AND instructions with immediate operand to shorter QImode
9152 ;; equivalents when possible.
9153 ;; Don't do the splitting with memory operands, since it introduces risk
9154 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9155 ;; for size, but that can (should?) be handled by generic code instead.
9156 (define_split
9157   [(set (match_operand 0 "register_operand" "")
9158         (and (match_operand 1 "register_operand" "")
9159              (match_operand 2 "const_int_operand" "")))
9160    (clobber (reg:CC FLAGS_REG))]
9161    "reload_completed
9162     && QI_REG_P (operands[0])
9163     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9164     && !(~INTVAL (operands[2]) & ~(255 << 8))
9165     && GET_MODE (operands[0]) != QImode"
9166   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9167                    (and:SI (zero_extract:SI (match_dup 1)
9168                                             (const_int 8) (const_int 8))
9169                            (match_dup 2)))
9170               (clobber (reg:CC FLAGS_REG))])]
9171   "operands[0] = gen_lowpart (SImode, operands[0]);
9172    operands[1] = gen_lowpart (SImode, operands[1]);
9173    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9174
9175 ;; Since AND can be encoded with sign extended immediate, this is only
9176 ;; profitable when 7th bit is not set.
9177 (define_split
9178   [(set (match_operand 0 "register_operand" "")
9179         (and (match_operand 1 "general_operand" "")
9180              (match_operand 2 "const_int_operand" "")))
9181    (clobber (reg:CC FLAGS_REG))]
9182    "reload_completed
9183     && ANY_QI_REG_P (operands[0])
9184     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9185     && !(~INTVAL (operands[2]) & ~255)
9186     && !(INTVAL (operands[2]) & 128)
9187     && GET_MODE (operands[0]) != QImode"
9188   [(parallel [(set (strict_low_part (match_dup 0))
9189                    (and:QI (match_dup 1)
9190                            (match_dup 2)))
9191               (clobber (reg:CC FLAGS_REG))])]
9192   "operands[0] = gen_lowpart (QImode, operands[0]);
9193    operands[1] = gen_lowpart (QImode, operands[1]);
9194    operands[2] = gen_lowpart (QImode, operands[2]);")
9195 \f
9196 ;; Logical inclusive OR instructions
9197
9198 ;; %%% This used to optimize known byte-wide and operations to memory.
9199 ;; If this is considered useful, it should be done with splitters.
9200
9201 (define_expand "iordi3"
9202   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9203         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9204                 (match_operand:DI 2 "x86_64_general_operand" "")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "TARGET_64BIT"
9207   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9208
9209 (define_insn "*iordi_1_rex64"
9210   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9211         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9212                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "TARGET_64BIT
9215    && ix86_binary_operator_ok (IOR, DImode, operands)"
9216   "or{q}\t{%2, %0|%0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "mode" "DI")])
9219
9220 (define_insn "*iordi_2_rex64"
9221   [(set (reg FLAGS_REG)
9222         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9223                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9224                  (const_int 0)))
9225    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9226         (ior:DI (match_dup 1) (match_dup 2)))]
9227   "TARGET_64BIT
9228    && ix86_match_ccmode (insn, CCNOmode)
9229    && ix86_binary_operator_ok (IOR, DImode, operands)"
9230   "or{q}\t{%2, %0|%0, %2}"
9231   [(set_attr "type" "alu")
9232    (set_attr "mode" "DI")])
9233
9234 (define_insn "*iordi_3_rex64"
9235   [(set (reg FLAGS_REG)
9236         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9237                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9238                  (const_int 0)))
9239    (clobber (match_scratch:DI 0 "=r"))]
9240   "TARGET_64BIT
9241    && ix86_match_ccmode (insn, CCNOmode)
9242    && ix86_binary_operator_ok (IOR, DImode, operands)"
9243   "or{q}\t{%2, %0|%0, %2}"
9244   [(set_attr "type" "alu")
9245    (set_attr "mode" "DI")])
9246
9247
9248 (define_expand "iorsi3"
9249   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9250         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9251                 (match_operand:SI 2 "general_operand" "")))
9252    (clobber (reg:CC FLAGS_REG))]
9253   ""
9254   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9255
9256 (define_insn "*iorsi_1"
9257   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9258         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9259                 (match_operand:SI 2 "general_operand" "ri,g")))
9260    (clobber (reg:CC FLAGS_REG))]
9261   "ix86_binary_operator_ok (IOR, SImode, operands)"
9262   "or{l}\t{%2, %0|%0, %2}"
9263   [(set_attr "type" "alu")
9264    (set_attr "mode" "SI")])
9265
9266 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9267 (define_insn "*iorsi_1_zext"
9268   [(set (match_operand:DI 0 "register_operand" "=r")
9269         (zero_extend:DI
9270           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9271                   (match_operand:SI 2 "general_operand" "g"))))
9272    (clobber (reg:CC FLAGS_REG))]
9273   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9274   "or{l}\t{%2, %k0|%k0, %2}"
9275   [(set_attr "type" "alu")
9276    (set_attr "mode" "SI")])
9277
9278 (define_insn "*iorsi_1_zext_imm"
9279   [(set (match_operand:DI 0 "register_operand" "=r")
9280         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9281                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9282    (clobber (reg:CC FLAGS_REG))]
9283   "TARGET_64BIT"
9284   "or{l}\t{%2, %k0|%k0, %2}"
9285   [(set_attr "type" "alu")
9286    (set_attr "mode" "SI")])
9287
9288 (define_insn "*iorsi_2"
9289   [(set (reg FLAGS_REG)
9290         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9291                          (match_operand:SI 2 "general_operand" "g,ri"))
9292                  (const_int 0)))
9293    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9294         (ior:SI (match_dup 1) (match_dup 2)))]
9295   "ix86_match_ccmode (insn, CCNOmode)
9296    && ix86_binary_operator_ok (IOR, SImode, operands)"
9297   "or{l}\t{%2, %0|%0, %2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "mode" "SI")])
9300
9301 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9302 ;; ??? Special case for immediate operand is missing - it is tricky.
9303 (define_insn "*iorsi_2_zext"
9304   [(set (reg FLAGS_REG)
9305         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306                          (match_operand:SI 2 "general_operand" "g"))
9307                  (const_int 0)))
9308    (set (match_operand:DI 0 "register_operand" "=r")
9309         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9310   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9311    && ix86_binary_operator_ok (IOR, SImode, operands)"
9312   "or{l}\t{%2, %k0|%k0, %2}"
9313   [(set_attr "type" "alu")
9314    (set_attr "mode" "SI")])
9315
9316 (define_insn "*iorsi_2_zext_imm"
9317   [(set (reg FLAGS_REG)
9318         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9319                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9320                  (const_int 0)))
9321    (set (match_operand:DI 0 "register_operand" "=r")
9322         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9323   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9324    && ix86_binary_operator_ok (IOR, SImode, operands)"
9325   "or{l}\t{%2, %k0|%k0, %2}"
9326   [(set_attr "type" "alu")
9327    (set_attr "mode" "SI")])
9328
9329 (define_insn "*iorsi_3"
9330   [(set (reg FLAGS_REG)
9331         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9332                          (match_operand:SI 2 "general_operand" "g"))
9333                  (const_int 0)))
9334    (clobber (match_scratch:SI 0 "=r"))]
9335   "ix86_match_ccmode (insn, CCNOmode)
9336    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9337   "or{l}\t{%2, %0|%0, %2}"
9338   [(set_attr "type" "alu")
9339    (set_attr "mode" "SI")])
9340
9341 (define_expand "iorhi3"
9342   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9343         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9344                 (match_operand:HI 2 "general_operand" "")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "TARGET_HIMODE_MATH"
9347   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9348
9349 (define_insn "*iorhi_1"
9350   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9351         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9352                 (match_operand:HI 2 "general_operand" "g,ri")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "ix86_binary_operator_ok (IOR, HImode, operands)"
9355   "or{w}\t{%2, %0|%0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "HI")])
9358
9359 (define_insn "*iorhi_2"
9360   [(set (reg FLAGS_REG)
9361         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9362                          (match_operand:HI 2 "general_operand" "g,ri"))
9363                  (const_int 0)))
9364    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9365         (ior:HI (match_dup 1) (match_dup 2)))]
9366   "ix86_match_ccmode (insn, CCNOmode)
9367    && ix86_binary_operator_ok (IOR, HImode, operands)"
9368   "or{w}\t{%2, %0|%0, %2}"
9369   [(set_attr "type" "alu")
9370    (set_attr "mode" "HI")])
9371
9372 (define_insn "*iorhi_3"
9373   [(set (reg FLAGS_REG)
9374         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9375                          (match_operand:HI 2 "general_operand" "g"))
9376                  (const_int 0)))
9377    (clobber (match_scratch:HI 0 "=r"))]
9378   "ix86_match_ccmode (insn, CCNOmode)
9379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9380   "or{w}\t{%2, %0|%0, %2}"
9381   [(set_attr "type" "alu")
9382    (set_attr "mode" "HI")])
9383
9384 (define_expand "iorqi3"
9385   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9386         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9387                 (match_operand:QI 2 "general_operand" "")))
9388    (clobber (reg:CC FLAGS_REG))]
9389   "TARGET_QIMODE_MATH"
9390   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9391
9392 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9393 (define_insn "*iorqi_1"
9394   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9395         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9396                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "ix86_binary_operator_ok (IOR, QImode, operands)"
9399   "@
9400    or{b}\t{%2, %0|%0, %2}
9401    or{b}\t{%2, %0|%0, %2}
9402    or{l}\t{%k2, %k0|%k0, %k2}"
9403   [(set_attr "type" "alu")
9404    (set_attr "mode" "QI,QI,SI")])
9405
9406 (define_insn "*iorqi_1_slp"
9407   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9408         (ior:QI (match_dup 0)
9409                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9412    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9413   "or{b}\t{%1, %0|%0, %1}"
9414   [(set_attr "type" "alu1")
9415    (set_attr "mode" "QI")])
9416
9417 (define_insn "*iorqi_2"
9418   [(set (reg FLAGS_REG)
9419         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9420                          (match_operand:QI 2 "general_operand" "qim,qi"))
9421                  (const_int 0)))
9422    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9423         (ior:QI (match_dup 1) (match_dup 2)))]
9424   "ix86_match_ccmode (insn, CCNOmode)
9425    && ix86_binary_operator_ok (IOR, QImode, operands)"
9426   "or{b}\t{%2, %0|%0, %2}"
9427   [(set_attr "type" "alu")
9428    (set_attr "mode" "QI")])
9429
9430 (define_insn "*iorqi_2_slp"
9431   [(set (reg FLAGS_REG)
9432         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9433                          (match_operand:QI 1 "general_operand" "qim,qi"))
9434                  (const_int 0)))
9435    (set (strict_low_part (match_dup 0))
9436         (ior:QI (match_dup 0) (match_dup 1)))]
9437   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9438    && ix86_match_ccmode (insn, CCNOmode)
9439    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9440   "or{b}\t{%1, %0|%0, %1}"
9441   [(set_attr "type" "alu1")
9442    (set_attr "mode" "QI")])
9443
9444 (define_insn "*iorqi_3"
9445   [(set (reg FLAGS_REG)
9446         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9447                          (match_operand:QI 2 "general_operand" "qim"))
9448                  (const_int 0)))
9449    (clobber (match_scratch:QI 0 "=q"))]
9450   "ix86_match_ccmode (insn, CCNOmode)
9451    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9452   "or{b}\t{%2, %0|%0, %2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "mode" "QI")])
9455
9456 (define_insn "iorqi_ext_0"
9457   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9458                          (const_int 8)
9459                          (const_int 8))
9460         (ior:SI
9461           (zero_extract:SI
9462             (match_operand 1 "ext_register_operand" "0")
9463             (const_int 8)
9464             (const_int 8))
9465           (match_operand 2 "const_int_operand" "n")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9468   "or{b}\t{%2, %h0|%h0, %2}"
9469   [(set_attr "type" "alu")
9470    (set_attr "length_immediate" "1")
9471    (set_attr "mode" "QI")])
9472
9473 (define_insn "*iorqi_ext_1"
9474   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9475                          (const_int 8)
9476                          (const_int 8))
9477         (ior:SI
9478           (zero_extract:SI
9479             (match_operand 1 "ext_register_operand" "0")
9480             (const_int 8)
9481             (const_int 8))
9482           (zero_extend:SI
9483             (match_operand:QI 2 "general_operand" "Qm"))))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "!TARGET_64BIT
9486    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9487   "or{b}\t{%2, %h0|%h0, %2}"
9488   [(set_attr "type" "alu")
9489    (set_attr "length_immediate" "0")
9490    (set_attr "mode" "QI")])
9491
9492 (define_insn "*iorqi_ext_1_rex64"
9493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9494                          (const_int 8)
9495                          (const_int 8))
9496         (ior:SI
9497           (zero_extract:SI
9498             (match_operand 1 "ext_register_operand" "0")
9499             (const_int 8)
9500             (const_int 8))
9501           (zero_extend:SI
9502             (match_operand 2 "ext_register_operand" "Q"))))
9503    (clobber (reg:CC FLAGS_REG))]
9504   "TARGET_64BIT
9505    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9506   "or{b}\t{%2, %h0|%h0, %2}"
9507   [(set_attr "type" "alu")
9508    (set_attr "length_immediate" "0")
9509    (set_attr "mode" "QI")])
9510
9511 (define_insn "*iorqi_ext_2"
9512   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9513                          (const_int 8)
9514                          (const_int 8))
9515         (ior:SI
9516           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9517                            (const_int 8)
9518                            (const_int 8))
9519           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9520                            (const_int 8)
9521                            (const_int 8))))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524   "ior{b}\t{%h2, %h0|%h0, %h2}"
9525   [(set_attr "type" "alu")
9526    (set_attr "length_immediate" "0")
9527    (set_attr "mode" "QI")])
9528
9529 (define_split
9530   [(set (match_operand 0 "register_operand" "")
9531         (ior (match_operand 1 "register_operand" "")
9532              (match_operand 2 "const_int_operand" "")))
9533    (clobber (reg:CC FLAGS_REG))]
9534    "reload_completed
9535     && QI_REG_P (operands[0])
9536     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9537     && !(INTVAL (operands[2]) & ~(255 << 8))
9538     && GET_MODE (operands[0]) != QImode"
9539   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9540                    (ior:SI (zero_extract:SI (match_dup 1)
9541                                             (const_int 8) (const_int 8))
9542                            (match_dup 2)))
9543               (clobber (reg:CC FLAGS_REG))])]
9544   "operands[0] = gen_lowpart (SImode, operands[0]);
9545    operands[1] = gen_lowpart (SImode, operands[1]);
9546    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9547
9548 ;; Since OR can be encoded with sign extended immediate, this is only
9549 ;; profitable when 7th bit is set.
9550 (define_split
9551   [(set (match_operand 0 "register_operand" "")
9552         (ior (match_operand 1 "general_operand" "")
9553              (match_operand 2 "const_int_operand" "")))
9554    (clobber (reg:CC FLAGS_REG))]
9555    "reload_completed
9556     && ANY_QI_REG_P (operands[0])
9557     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9558     && !(INTVAL (operands[2]) & ~255)
9559     && (INTVAL (operands[2]) & 128)
9560     && GET_MODE (operands[0]) != QImode"
9561   [(parallel [(set (strict_low_part (match_dup 0))
9562                    (ior:QI (match_dup 1)
9563                            (match_dup 2)))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "operands[0] = gen_lowpart (QImode, operands[0]);
9566    operands[1] = gen_lowpart (QImode, operands[1]);
9567    operands[2] = gen_lowpart (QImode, operands[2]);")
9568 \f
9569 ;; Logical XOR instructions
9570
9571 ;; %%% This used to optimize known byte-wide and operations to memory.
9572 ;; If this is considered useful, it should be done with splitters.
9573
9574 (define_expand "xordi3"
9575   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9576         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9577                 (match_operand:DI 2 "x86_64_general_operand" "")))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_64BIT"
9580   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9581
9582 (define_insn "*xordi_1_rex64"
9583   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9584         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9585                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9586    (clobber (reg:CC FLAGS_REG))]
9587   "TARGET_64BIT
9588    && ix86_binary_operator_ok (XOR, DImode, operands)"
9589   "@
9590    xor{q}\t{%2, %0|%0, %2}
9591    xor{q}\t{%2, %0|%0, %2}"
9592   [(set_attr "type" "alu")
9593    (set_attr "mode" "DI,DI")])
9594
9595 (define_insn "*xordi_2_rex64"
9596   [(set (reg FLAGS_REG)
9597         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9598                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9599                  (const_int 0)))
9600    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9601         (xor:DI (match_dup 1) (match_dup 2)))]
9602   "TARGET_64BIT
9603    && ix86_match_ccmode (insn, CCNOmode)
9604    && ix86_binary_operator_ok (XOR, DImode, operands)"
9605   "@
9606    xor{q}\t{%2, %0|%0, %2}
9607    xor{q}\t{%2, %0|%0, %2}"
9608   [(set_attr "type" "alu")
9609    (set_attr "mode" "DI,DI")])
9610
9611 (define_insn "*xordi_3_rex64"
9612   [(set (reg FLAGS_REG)
9613         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9614                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9615                  (const_int 0)))
9616    (clobber (match_scratch:DI 0 "=r"))]
9617   "TARGET_64BIT
9618    && ix86_match_ccmode (insn, CCNOmode)
9619    && ix86_binary_operator_ok (XOR, DImode, operands)"
9620   "xor{q}\t{%2, %0|%0, %2}"
9621   [(set_attr "type" "alu")
9622    (set_attr "mode" "DI")])
9623
9624 (define_expand "xorsi3"
9625   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9626         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9627                 (match_operand:SI 2 "general_operand" "")))
9628    (clobber (reg:CC FLAGS_REG))]
9629   ""
9630   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9631
9632 (define_insn "*xorsi_1"
9633   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9634         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635                 (match_operand:SI 2 "general_operand" "ri,rm")))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "ix86_binary_operator_ok (XOR, SImode, operands)"
9638   "xor{l}\t{%2, %0|%0, %2}"
9639   [(set_attr "type" "alu")
9640    (set_attr "mode" "SI")])
9641
9642 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9643 ;; Add speccase for immediates
9644 (define_insn "*xorsi_1_zext"
9645   [(set (match_operand:DI 0 "register_operand" "=r")
9646         (zero_extend:DI
9647           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9648                   (match_operand:SI 2 "general_operand" "g"))))
9649    (clobber (reg:CC FLAGS_REG))]
9650   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9651   "xor{l}\t{%2, %k0|%k0, %2}"
9652   [(set_attr "type" "alu")
9653    (set_attr "mode" "SI")])
9654
9655 (define_insn "*xorsi_1_zext_imm"
9656   [(set (match_operand:DI 0 "register_operand" "=r")
9657         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9658                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9661   "xor{l}\t{%2, %k0|%k0, %2}"
9662   [(set_attr "type" "alu")
9663    (set_attr "mode" "SI")])
9664
9665 (define_insn "*xorsi_2"
9666   [(set (reg FLAGS_REG)
9667         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9668                          (match_operand:SI 2 "general_operand" "g,ri"))
9669                  (const_int 0)))
9670    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9671         (xor:SI (match_dup 1) (match_dup 2)))]
9672   "ix86_match_ccmode (insn, CCNOmode)
9673    && ix86_binary_operator_ok (XOR, SImode, operands)"
9674   "xor{l}\t{%2, %0|%0, %2}"
9675   [(set_attr "type" "alu")
9676    (set_attr "mode" "SI")])
9677
9678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9679 ;; ??? Special case for immediate operand is missing - it is tricky.
9680 (define_insn "*xorsi_2_zext"
9681   [(set (reg FLAGS_REG)
9682         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683                          (match_operand:SI 2 "general_operand" "g"))
9684                  (const_int 0)))
9685    (set (match_operand:DI 0 "register_operand" "=r")
9686         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9687   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9688    && ix86_binary_operator_ok (XOR, SImode, operands)"
9689   "xor{l}\t{%2, %k0|%k0, %2}"
9690   [(set_attr "type" "alu")
9691    (set_attr "mode" "SI")])
9692
9693 (define_insn "*xorsi_2_zext_imm"
9694   [(set (reg FLAGS_REG)
9695         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9696                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9697                  (const_int 0)))
9698    (set (match_operand:DI 0 "register_operand" "=r")
9699         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9700   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9701    && ix86_binary_operator_ok (XOR, SImode, operands)"
9702   "xor{l}\t{%2, %k0|%k0, %2}"
9703   [(set_attr "type" "alu")
9704    (set_attr "mode" "SI")])
9705
9706 (define_insn "*xorsi_3"
9707   [(set (reg FLAGS_REG)
9708         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9709                          (match_operand:SI 2 "general_operand" "g"))
9710                  (const_int 0)))
9711    (clobber (match_scratch:SI 0 "=r"))]
9712   "ix86_match_ccmode (insn, CCNOmode)
9713    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9714   "xor{l}\t{%2, %0|%0, %2}"
9715   [(set_attr "type" "alu")
9716    (set_attr "mode" "SI")])
9717
9718 (define_expand "xorhi3"
9719   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9720         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9721                 (match_operand:HI 2 "general_operand" "")))
9722    (clobber (reg:CC FLAGS_REG))]
9723   "TARGET_HIMODE_MATH"
9724   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9725
9726 (define_insn "*xorhi_1"
9727   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9728         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9729                 (match_operand:HI 2 "general_operand" "g,ri")))
9730    (clobber (reg:CC FLAGS_REG))]
9731   "ix86_binary_operator_ok (XOR, HImode, operands)"
9732   "xor{w}\t{%2, %0|%0, %2}"
9733   [(set_attr "type" "alu")
9734    (set_attr "mode" "HI")])
9735
9736 (define_insn "*xorhi_2"
9737   [(set (reg FLAGS_REG)
9738         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9739                          (match_operand:HI 2 "general_operand" "g,ri"))
9740                  (const_int 0)))
9741    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9742         (xor:HI (match_dup 1) (match_dup 2)))]
9743   "ix86_match_ccmode (insn, CCNOmode)
9744    && ix86_binary_operator_ok (XOR, HImode, operands)"
9745   "xor{w}\t{%2, %0|%0, %2}"
9746   [(set_attr "type" "alu")
9747    (set_attr "mode" "HI")])
9748
9749 (define_insn "*xorhi_3"
9750   [(set (reg FLAGS_REG)
9751         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9752                          (match_operand:HI 2 "general_operand" "g"))
9753                  (const_int 0)))
9754    (clobber (match_scratch:HI 0 "=r"))]
9755   "ix86_match_ccmode (insn, CCNOmode)
9756    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9757   "xor{w}\t{%2, %0|%0, %2}"
9758   [(set_attr "type" "alu")
9759    (set_attr "mode" "HI")])
9760
9761 (define_expand "xorqi3"
9762   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9763         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9764                 (match_operand:QI 2 "general_operand" "")))
9765    (clobber (reg:CC FLAGS_REG))]
9766   "TARGET_QIMODE_MATH"
9767   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9768
9769 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9770 (define_insn "*xorqi_1"
9771   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9772         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9773                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "ix86_binary_operator_ok (XOR, QImode, operands)"
9776   "@
9777    xor{b}\t{%2, %0|%0, %2}
9778    xor{b}\t{%2, %0|%0, %2}
9779    xor{l}\t{%k2, %k0|%k0, %k2}"
9780   [(set_attr "type" "alu")
9781    (set_attr "mode" "QI,QI,SI")])
9782
9783 (define_insn "*xorqi_1_slp"
9784   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9785         (xor:QI (match_dup 0)
9786                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9789    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9790   "xor{b}\t{%1, %0|%0, %1}"
9791   [(set_attr "type" "alu1")
9792    (set_attr "mode" "QI")])
9793
9794 (define_insn "xorqi_ext_0"
9795   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9796                          (const_int 8)
9797                          (const_int 8))
9798         (xor:SI
9799           (zero_extract:SI
9800             (match_operand 1 "ext_register_operand" "0")
9801             (const_int 8)
9802             (const_int 8))
9803           (match_operand 2 "const_int_operand" "n")))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9806   "xor{b}\t{%2, %h0|%h0, %2}"
9807   [(set_attr "type" "alu")
9808    (set_attr "length_immediate" "1")
9809    (set_attr "mode" "QI")])
9810
9811 (define_insn "*xorqi_ext_1"
9812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9813                          (const_int 8)
9814                          (const_int 8))
9815         (xor:SI
9816           (zero_extract:SI
9817             (match_operand 1 "ext_register_operand" "0")
9818             (const_int 8)
9819             (const_int 8))
9820           (zero_extend:SI
9821             (match_operand:QI 2 "general_operand" "Qm"))))
9822    (clobber (reg:CC FLAGS_REG))]
9823   "!TARGET_64BIT
9824    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9825   "xor{b}\t{%2, %h0|%h0, %2}"
9826   [(set_attr "type" "alu")
9827    (set_attr "length_immediate" "0")
9828    (set_attr "mode" "QI")])
9829
9830 (define_insn "*xorqi_ext_1_rex64"
9831   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9832                          (const_int 8)
9833                          (const_int 8))
9834         (xor:SI
9835           (zero_extract:SI
9836             (match_operand 1 "ext_register_operand" "0")
9837             (const_int 8)
9838             (const_int 8))
9839           (zero_extend:SI
9840             (match_operand 2 "ext_register_operand" "Q"))))
9841    (clobber (reg:CC FLAGS_REG))]
9842   "TARGET_64BIT
9843    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9844   "xor{b}\t{%2, %h0|%h0, %2}"
9845   [(set_attr "type" "alu")
9846    (set_attr "length_immediate" "0")
9847    (set_attr "mode" "QI")])
9848
9849 (define_insn "*xorqi_ext_2"
9850   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9851                          (const_int 8)
9852                          (const_int 8))
9853         (xor:SI
9854           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9855                            (const_int 8)
9856                            (const_int 8))
9857           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9858                            (const_int 8)
9859                            (const_int 8))))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9862   "xor{b}\t{%h2, %h0|%h0, %h2}"
9863   [(set_attr "type" "alu")
9864    (set_attr "length_immediate" "0")
9865    (set_attr "mode" "QI")])
9866
9867 (define_insn "*xorqi_cc_1"
9868   [(set (reg FLAGS_REG)
9869         (compare
9870           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9871                   (match_operand:QI 2 "general_operand" "qim,qi"))
9872           (const_int 0)))
9873    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9874         (xor:QI (match_dup 1) (match_dup 2)))]
9875   "ix86_match_ccmode (insn, CCNOmode)
9876    && ix86_binary_operator_ok (XOR, QImode, operands)"
9877   "xor{b}\t{%2, %0|%0, %2}"
9878   [(set_attr "type" "alu")
9879    (set_attr "mode" "QI")])
9880
9881 (define_insn "*xorqi_2_slp"
9882   [(set (reg FLAGS_REG)
9883         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9884                          (match_operand:QI 1 "general_operand" "qim,qi"))
9885                  (const_int 0)))
9886    (set (strict_low_part (match_dup 0))
9887         (xor:QI (match_dup 0) (match_dup 1)))]
9888   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9889    && ix86_match_ccmode (insn, CCNOmode)
9890    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9891   "xor{b}\t{%1, %0|%0, %1}"
9892   [(set_attr "type" "alu1")
9893    (set_attr "mode" "QI")])
9894
9895 (define_insn "*xorqi_cc_2"
9896   [(set (reg FLAGS_REG)
9897         (compare
9898           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9899                   (match_operand:QI 2 "general_operand" "qim"))
9900           (const_int 0)))
9901    (clobber (match_scratch:QI 0 "=q"))]
9902   "ix86_match_ccmode (insn, CCNOmode)
9903    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904   "xor{b}\t{%2, %0|%0, %2}"
9905   [(set_attr "type" "alu")
9906    (set_attr "mode" "QI")])
9907
9908 (define_insn "*xorqi_cc_ext_1"
9909   [(set (reg FLAGS_REG)
9910         (compare
9911           (xor:SI
9912             (zero_extract:SI
9913               (match_operand 1 "ext_register_operand" "0")
9914               (const_int 8)
9915               (const_int 8))
9916             (match_operand:QI 2 "general_operand" "qmn"))
9917           (const_int 0)))
9918    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9919                          (const_int 8)
9920                          (const_int 8))
9921         (xor:SI
9922           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9923           (match_dup 2)))]
9924   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9925   "xor{b}\t{%2, %h0|%h0, %2}"
9926   [(set_attr "type" "alu")
9927    (set_attr "mode" "QI")])
9928
9929 (define_insn "*xorqi_cc_ext_1_rex64"
9930   [(set (reg FLAGS_REG)
9931         (compare
9932           (xor:SI
9933             (zero_extract:SI
9934               (match_operand 1 "ext_register_operand" "0")
9935               (const_int 8)
9936               (const_int 8))
9937             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9938           (const_int 0)))
9939    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9940                          (const_int 8)
9941                          (const_int 8))
9942         (xor:SI
9943           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9944           (match_dup 2)))]
9945   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9946   "xor{b}\t{%2, %h0|%h0, %2}"
9947   [(set_attr "type" "alu")
9948    (set_attr "mode" "QI")])
9949
9950 (define_expand "xorqi_cc_ext_1"
9951   [(parallel [
9952      (set (reg:CCNO FLAGS_REG)
9953           (compare:CCNO
9954             (xor:SI
9955               (zero_extract:SI
9956                 (match_operand 1 "ext_register_operand" "")
9957                 (const_int 8)
9958                 (const_int 8))
9959               (match_operand:QI 2 "general_operand" ""))
9960             (const_int 0)))
9961      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9962                            (const_int 8)
9963                            (const_int 8))
9964           (xor:SI
9965             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9966             (match_dup 2)))])]
9967   ""
9968   "")
9969
9970 (define_split
9971   [(set (match_operand 0 "register_operand" "")
9972         (xor (match_operand 1 "register_operand" "")
9973              (match_operand 2 "const_int_operand" "")))
9974    (clobber (reg:CC FLAGS_REG))]
9975    "reload_completed
9976     && QI_REG_P (operands[0])
9977     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9978     && !(INTVAL (operands[2]) & ~(255 << 8))
9979     && GET_MODE (operands[0]) != QImode"
9980   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9981                    (xor:SI (zero_extract:SI (match_dup 1)
9982                                             (const_int 8) (const_int 8))
9983                            (match_dup 2)))
9984               (clobber (reg:CC FLAGS_REG))])]
9985   "operands[0] = gen_lowpart (SImode, operands[0]);
9986    operands[1] = gen_lowpart (SImode, operands[1]);
9987    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9988
9989 ;; Since XOR can be encoded with sign extended immediate, this is only
9990 ;; profitable when 7th bit is set.
9991 (define_split
9992   [(set (match_operand 0 "register_operand" "")
9993         (xor (match_operand 1 "general_operand" "")
9994              (match_operand 2 "const_int_operand" "")))
9995    (clobber (reg:CC FLAGS_REG))]
9996    "reload_completed
9997     && ANY_QI_REG_P (operands[0])
9998     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9999     && !(INTVAL (operands[2]) & ~255)
10000     && (INTVAL (operands[2]) & 128)
10001     && GET_MODE (operands[0]) != QImode"
10002   [(parallel [(set (strict_low_part (match_dup 0))
10003                    (xor:QI (match_dup 1)
10004                            (match_dup 2)))
10005               (clobber (reg:CC FLAGS_REG))])]
10006   "operands[0] = gen_lowpart (QImode, operands[0]);
10007    operands[1] = gen_lowpart (QImode, operands[1]);
10008    operands[2] = gen_lowpart (QImode, operands[2]);")
10009 \f
10010 ;; Negation instructions
10011
10012 (define_expand "negti2"
10013   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10014                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10015               (clobber (reg:CC FLAGS_REG))])]
10016   "TARGET_64BIT"
10017   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10018
10019 (define_insn "*negti2_1"
10020   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10021         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10022    (clobber (reg:CC FLAGS_REG))]
10023   "TARGET_64BIT
10024    && ix86_unary_operator_ok (NEG, TImode, operands)"
10025   "#")
10026
10027 (define_split
10028   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10029         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "TARGET_64BIT && reload_completed"
10032   [(parallel
10033     [(set (reg:CCZ FLAGS_REG)
10034           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10035      (set (match_dup 0) (neg:DI (match_dup 2)))])
10036    (parallel
10037     [(set (match_dup 1)
10038           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10039                             (match_dup 3))
10040                    (const_int 0)))
10041      (clobber (reg:CC FLAGS_REG))])
10042    (parallel
10043     [(set (match_dup 1)
10044           (neg:DI (match_dup 1)))
10045      (clobber (reg:CC FLAGS_REG))])]
10046   "split_ti (operands+1, 1, operands+2, operands+3);
10047    split_ti (operands+0, 1, operands+0, operands+1);")
10048
10049 (define_expand "negdi2"
10050   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10051                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10052               (clobber (reg:CC FLAGS_REG))])]
10053   ""
10054   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10055
10056 (define_insn "*negdi2_1"
10057   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10058         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10059    (clobber (reg:CC FLAGS_REG))]
10060   "!TARGET_64BIT
10061    && ix86_unary_operator_ok (NEG, DImode, operands)"
10062   "#")
10063
10064 (define_split
10065   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066         (neg:DI (match_operand:DI 1 "general_operand" "")))
10067    (clobber (reg:CC FLAGS_REG))]
10068   "!TARGET_64BIT && reload_completed"
10069   [(parallel
10070     [(set (reg:CCZ FLAGS_REG)
10071           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10072      (set (match_dup 0) (neg:SI (match_dup 2)))])
10073    (parallel
10074     [(set (match_dup 1)
10075           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10076                             (match_dup 3))
10077                    (const_int 0)))
10078      (clobber (reg:CC FLAGS_REG))])
10079    (parallel
10080     [(set (match_dup 1)
10081           (neg:SI (match_dup 1)))
10082      (clobber (reg:CC FLAGS_REG))])]
10083   "split_di (operands+1, 1, operands+2, operands+3);
10084    split_di (operands+0, 1, operands+0, operands+1);")
10085
10086 (define_insn "*negdi2_1_rex64"
10087   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10088         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10089    (clobber (reg:CC FLAGS_REG))]
10090   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10091   "neg{q}\t%0"
10092   [(set_attr "type" "negnot")
10093    (set_attr "mode" "DI")])
10094
10095 ;; The problem with neg is that it does not perform (compare x 0),
10096 ;; it really performs (compare 0 x), which leaves us with the zero
10097 ;; flag being the only useful item.
10098
10099 (define_insn "*negdi2_cmpz_rex64"
10100   [(set (reg:CCZ FLAGS_REG)
10101         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10102                      (const_int 0)))
10103    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10104         (neg:DI (match_dup 1)))]
10105   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10106   "neg{q}\t%0"
10107   [(set_attr "type" "negnot")
10108    (set_attr "mode" "DI")])
10109
10110
10111 (define_expand "negsi2"
10112   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10113                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10114               (clobber (reg:CC FLAGS_REG))])]
10115   ""
10116   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10117
10118 (define_insn "*negsi2_1"
10119   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10120         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10121    (clobber (reg:CC FLAGS_REG))]
10122   "ix86_unary_operator_ok (NEG, SImode, operands)"
10123   "neg{l}\t%0"
10124   [(set_attr "type" "negnot")
10125    (set_attr "mode" "SI")])
10126
10127 ;; Combine is quite creative about this pattern.
10128 (define_insn "*negsi2_1_zext"
10129   [(set (match_operand:DI 0 "register_operand" "=r")
10130         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10131                                         (const_int 32)))
10132                      (const_int 32)))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10135   "neg{l}\t%k0"
10136   [(set_attr "type" "negnot")
10137    (set_attr "mode" "SI")])
10138
10139 ;; The problem with neg is that it does not perform (compare x 0),
10140 ;; it really performs (compare 0 x), which leaves us with the zero
10141 ;; flag being the only useful item.
10142
10143 (define_insn "*negsi2_cmpz"
10144   [(set (reg:CCZ FLAGS_REG)
10145         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10146                      (const_int 0)))
10147    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10148         (neg:SI (match_dup 1)))]
10149   "ix86_unary_operator_ok (NEG, SImode, operands)"
10150   "neg{l}\t%0"
10151   [(set_attr "type" "negnot")
10152    (set_attr "mode" "SI")])
10153
10154 (define_insn "*negsi2_cmpz_zext"
10155   [(set (reg:CCZ FLAGS_REG)
10156         (compare:CCZ (lshiftrt:DI
10157                        (neg:DI (ashift:DI
10158                                  (match_operand:DI 1 "register_operand" "0")
10159                                  (const_int 32)))
10160                        (const_int 32))
10161                      (const_int 0)))
10162    (set (match_operand:DI 0 "register_operand" "=r")
10163         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10164                                         (const_int 32)))
10165                      (const_int 32)))]
10166   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10167   "neg{l}\t%k0"
10168   [(set_attr "type" "negnot")
10169    (set_attr "mode" "SI")])
10170
10171 (define_expand "neghi2"
10172   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10173                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10174               (clobber (reg:CC FLAGS_REG))])]
10175   "TARGET_HIMODE_MATH"
10176   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10177
10178 (define_insn "*neghi2_1"
10179   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10180         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10181    (clobber (reg:CC FLAGS_REG))]
10182   "ix86_unary_operator_ok (NEG, HImode, operands)"
10183   "neg{w}\t%0"
10184   [(set_attr "type" "negnot")
10185    (set_attr "mode" "HI")])
10186
10187 (define_insn "*neghi2_cmpz"
10188   [(set (reg:CCZ FLAGS_REG)
10189         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10190                      (const_int 0)))
10191    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192         (neg:HI (match_dup 1)))]
10193   "ix86_unary_operator_ok (NEG, HImode, operands)"
10194   "neg{w}\t%0"
10195   [(set_attr "type" "negnot")
10196    (set_attr "mode" "HI")])
10197
10198 (define_expand "negqi2"
10199   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10200                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10201               (clobber (reg:CC FLAGS_REG))])]
10202   "TARGET_QIMODE_MATH"
10203   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10204
10205 (define_insn "*negqi2_1"
10206   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10208    (clobber (reg:CC FLAGS_REG))]
10209   "ix86_unary_operator_ok (NEG, QImode, operands)"
10210   "neg{b}\t%0"
10211   [(set_attr "type" "negnot")
10212    (set_attr "mode" "QI")])
10213
10214 (define_insn "*negqi2_cmpz"
10215   [(set (reg:CCZ FLAGS_REG)
10216         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10217                      (const_int 0)))
10218    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10219         (neg:QI (match_dup 1)))]
10220   "ix86_unary_operator_ok (NEG, QImode, operands)"
10221   "neg{b}\t%0"
10222   [(set_attr "type" "negnot")
10223    (set_attr "mode" "QI")])
10224
10225 ;; Changing of sign for FP values is doable using integer unit too.
10226
10227 (define_expand "negsf2"
10228   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10229         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10230   "TARGET_80387 || TARGET_SSE_MATH"
10231   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10232
10233 (define_expand "abssf2"
10234   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10235         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10236   "TARGET_80387 || TARGET_SSE_MATH"
10237   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10238
10239 (define_insn "*absnegsf2_mixed"
10240   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
10241         (match_operator:SF 3 "absneg_operator"
10242           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
10243    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
10244    (clobber (reg:CC FLAGS_REG))]
10245   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10246    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10247   "#")
10248
10249 (define_insn "*absnegsf2_sse"
10250   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
10251         (match_operator:SF 3 "absneg_operator"
10252           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10253    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
10254    (clobber (reg:CC FLAGS_REG))]
10255   "TARGET_SSE_MATH
10256    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10257   "#")
10258
10259 (define_insn "*absnegsf2_i387"
10260   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10261         (match_operator:SF 3 "absneg_operator"
10262           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10263    (use (match_operand 2 "" ""))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_80387 && !TARGET_SSE_MATH
10266    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10267   "#")
10268
10269 (define_expand "negdf2"
10270   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10271         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10272   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10273   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10274
10275 (define_expand "absdf2"
10276   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10277         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10278   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10279   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10280
10281 (define_insn "*absnegdf2_mixed"
10282   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10283         (match_operator:DF 3 "absneg_operator"
10284           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10285    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10286    (clobber (reg:CC FLAGS_REG))]
10287   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10288    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10289   "#")
10290
10291 (define_insn "*absnegdf2_sse"
10292   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10293         (match_operator:DF 3 "absneg_operator"
10294           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10295    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_SSE2 && TARGET_SSE_MATH
10298    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10299   "#")
10300
10301 (define_insn "*absnegdf2_i387"
10302   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10303         (match_operator:DF 3 "absneg_operator"
10304           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10305    (use (match_operand 2 "" ""))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10308    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10309   "#")
10310
10311 (define_expand "negxf2"
10312   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10313         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10314   "TARGET_80387"
10315   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10316
10317 (define_expand "absxf2"
10318   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10319         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10320   "TARGET_80387"
10321   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10322
10323 (define_insn "*absnegxf2_i387"
10324   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10325         (match_operator:XF 3 "absneg_operator"
10326           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10327    (use (match_operand 2 "" ""))
10328    (clobber (reg:CC FLAGS_REG))]
10329   "TARGET_80387
10330    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10331   "#")
10332
10333 (define_expand "negtf2"
10334   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10335         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10336   "TARGET_64BIT"
10337   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10338
10339 (define_expand "abstf2"
10340   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10341         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10342   "TARGET_64BIT"
10343   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10344
10345 (define_insn "*absnegtf2_sse"
10346   [(set (match_operand:TF 0 "nonimmediate_operand"    "=x,x,m")
10347         (match_operator:TF 3 "absneg_operator"
10348           [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10349    (use (match_operand:TF 2 "nonimmediate_operand"    "xm,0,X"))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT
10352    && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10353   "#")
10354
10355 ;; Splitters for fp abs and neg.
10356
10357 (define_split
10358   [(set (match_operand 0 "fp_register_operand" "")
10359         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10360    (use (match_operand 2 "" ""))
10361    (clobber (reg:CC FLAGS_REG))]
10362   "reload_completed"
10363   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10364
10365 (define_split
10366   [(set (match_operand 0 "register_operand" "")
10367         (match_operator 3 "absneg_operator"
10368           [(match_operand 1 "register_operand" "")]))
10369    (use (match_operand 2 "nonimmediate_operand" ""))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "reload_completed && SSE_REG_P (operands[0])"
10372   [(set (match_dup 0) (match_dup 3))]
10373 {
10374   enum machine_mode mode = GET_MODE (operands[0]);
10375   enum machine_mode vmode = GET_MODE (operands[2]);
10376   rtx tmp;
10377
10378   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10379   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10380   if (operands_match_p (operands[0], operands[2]))
10381     {
10382       tmp = operands[1];
10383       operands[1] = operands[2];
10384       operands[2] = tmp;
10385     }
10386   if (GET_CODE (operands[3]) == ABS)
10387     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10388   else
10389     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10390   operands[3] = tmp;
10391 })
10392
10393 (define_split
10394   [(set (match_operand:SF 0 "register_operand" "")
10395         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10396    (use (match_operand:V4SF 2 "" ""))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "reload_completed"
10399   [(parallel [(set (match_dup 0) (match_dup 1))
10400               (clobber (reg:CC FLAGS_REG))])]
10401 {
10402   rtx tmp;
10403   operands[0] = gen_lowpart (SImode, operands[0]);
10404   if (GET_CODE (operands[1]) == ABS)
10405     {
10406       tmp = gen_int_mode (0x7fffffff, SImode);
10407       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10408     }
10409   else
10410     {
10411       tmp = gen_int_mode (0x80000000, SImode);
10412       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10413     }
10414   operands[1] = tmp;
10415 })
10416
10417 (define_split
10418   [(set (match_operand:DF 0 "register_operand" "")
10419         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10420    (use (match_operand 2 "" ""))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "reload_completed"
10423   [(parallel [(set (match_dup 0) (match_dup 1))
10424               (clobber (reg:CC FLAGS_REG))])]
10425 {
10426   rtx tmp;
10427   if (TARGET_64BIT)
10428     {
10429       tmp = gen_lowpart (DImode, operands[0]);
10430       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10431       operands[0] = tmp;
10432
10433       if (GET_CODE (operands[1]) == ABS)
10434         tmp = const0_rtx;
10435       else
10436         tmp = gen_rtx_NOT (DImode, tmp);
10437     }
10438   else
10439     {
10440       operands[0] = gen_highpart (SImode, operands[0]);
10441       if (GET_CODE (operands[1]) == ABS)
10442         {
10443           tmp = gen_int_mode (0x7fffffff, SImode);
10444           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10445         }
10446       else
10447         {
10448           tmp = gen_int_mode (0x80000000, SImode);
10449           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10450         }
10451     }
10452   operands[1] = tmp;
10453 })
10454
10455 (define_split
10456   [(set (match_operand:XF 0 "register_operand" "")
10457         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10458    (use (match_operand 2 "" ""))
10459    (clobber (reg:CC FLAGS_REG))]
10460   "reload_completed"
10461   [(parallel [(set (match_dup 0) (match_dup 1))
10462               (clobber (reg:CC FLAGS_REG))])]
10463 {
10464   rtx tmp;
10465   operands[0] = gen_rtx_REG (SImode,
10466                              true_regnum (operands[0])
10467                              + (TARGET_64BIT ? 1 : 2));
10468   if (GET_CODE (operands[1]) == ABS)
10469     {
10470       tmp = GEN_INT (0x7fff);
10471       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10472     }
10473   else
10474     {
10475       tmp = GEN_INT (0x8000);
10476       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10477     }
10478   operands[1] = tmp;
10479 })
10480
10481 (define_split
10482   [(set (match_operand 0 "memory_operand" "")
10483         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10484    (use (match_operand 2 "" ""))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "reload_completed"
10487   [(parallel [(set (match_dup 0) (match_dup 1))
10488               (clobber (reg:CC FLAGS_REG))])]
10489 {
10490   enum machine_mode mode = GET_MODE (operands[0]);
10491   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10492   rtx tmp;
10493
10494   operands[0] = adjust_address (operands[0], QImode, size - 1);
10495   if (GET_CODE (operands[1]) == ABS)
10496     {
10497       tmp = gen_int_mode (0x7f, QImode);
10498       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10499     }
10500   else
10501     {
10502       tmp = gen_int_mode (0x80, QImode);
10503       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10504     }
10505   operands[1] = tmp;
10506 })
10507
10508 ;; Conditionalize these after reload. If they match before reload, we
10509 ;; lose the clobber and ability to use integer instructions.
10510
10511 (define_insn "*negsf2_1"
10512   [(set (match_operand:SF 0 "register_operand" "=f")
10513         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10514   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10515   "fchs"
10516   [(set_attr "type" "fsgn")
10517    (set_attr "mode" "SF")])
10518
10519 (define_insn "*negdf2_1"
10520   [(set (match_operand:DF 0 "register_operand" "=f")
10521         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10522   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10523   "fchs"
10524   [(set_attr "type" "fsgn")
10525    (set_attr "mode" "DF")])
10526
10527 (define_insn "*negxf2_1"
10528   [(set (match_operand:XF 0 "register_operand" "=f")
10529         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10530   "TARGET_80387"
10531   "fchs"
10532   [(set_attr "type" "fsgn")
10533    (set_attr "mode" "XF")])
10534
10535 (define_insn "*abssf2_1"
10536   [(set (match_operand:SF 0 "register_operand" "=f")
10537         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10538   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10539   "fabs"
10540   [(set_attr "type" "fsgn")
10541    (set_attr "mode" "SF")])
10542
10543 (define_insn "*absdf2_1"
10544   [(set (match_operand:DF 0 "register_operand" "=f")
10545         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10546   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10547   "fabs"
10548   [(set_attr "type" "fsgn")
10549    (set_attr "mode" "DF")])
10550
10551 (define_insn "*absxf2_1"
10552   [(set (match_operand:XF 0 "register_operand" "=f")
10553         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10554   "TARGET_80387"
10555   "fabs"
10556   [(set_attr "type" "fsgn")
10557    (set_attr "mode" "DF")])
10558
10559 (define_insn "*negextendsfdf2"
10560   [(set (match_operand:DF 0 "register_operand" "=f")
10561         (neg:DF (float_extend:DF
10562                   (match_operand:SF 1 "register_operand" "0"))))]
10563   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10564   "fchs"
10565   [(set_attr "type" "fsgn")
10566    (set_attr "mode" "DF")])
10567
10568 (define_insn "*negextenddfxf2"
10569   [(set (match_operand:XF 0 "register_operand" "=f")
10570         (neg:XF (float_extend:XF
10571                   (match_operand:DF 1 "register_operand" "0"))))]
10572   "TARGET_80387"
10573   "fchs"
10574   [(set_attr "type" "fsgn")
10575    (set_attr "mode" "XF")])
10576
10577 (define_insn "*negextendsfxf2"
10578   [(set (match_operand:XF 0 "register_operand" "=f")
10579         (neg:XF (float_extend:XF
10580                   (match_operand:SF 1 "register_operand" "0"))))]
10581   "TARGET_80387"
10582   "fchs"
10583   [(set_attr "type" "fsgn")
10584    (set_attr "mode" "XF")])
10585
10586 (define_insn "*absextendsfdf2"
10587   [(set (match_operand:DF 0 "register_operand" "=f")
10588         (abs:DF (float_extend:DF
10589                   (match_operand:SF 1 "register_operand" "0"))))]
10590   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10591   "fabs"
10592   [(set_attr "type" "fsgn")
10593    (set_attr "mode" "DF")])
10594
10595 (define_insn "*absextenddfxf2"
10596   [(set (match_operand:XF 0 "register_operand" "=f")
10597         (abs:XF (float_extend:XF
10598           (match_operand:DF 1 "register_operand" "0"))))]
10599   "TARGET_80387"
10600   "fabs"
10601   [(set_attr "type" "fsgn")
10602    (set_attr "mode" "XF")])
10603
10604 (define_insn "*absextendsfxf2"
10605   [(set (match_operand:XF 0 "register_operand" "=f")
10606         (abs:XF (float_extend:XF
10607           (match_operand:SF 1 "register_operand" "0"))))]
10608   "TARGET_80387"
10609   "fabs"
10610   [(set_attr "type" "fsgn")
10611    (set_attr "mode" "XF")])
10612
10613 ;; Copysign instructions
10614
10615 (define_mode_iterator CSGNMODE [SF DF TF])
10616 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10617
10618 (define_expand "copysign<mode>3"
10619   [(match_operand:CSGNMODE 0 "register_operand" "")
10620    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10621    (match_operand:CSGNMODE 2 "register_operand" "")]
10622   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10623    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10624 {
10625   ix86_expand_copysign (operands);
10626   DONE;
10627 })
10628
10629 (define_insn_and_split "copysign<mode>3_const"
10630   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10631         (unspec:CSGNMODE
10632           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10633            (match_operand:CSGNMODE 2 "register_operand" "0")
10634            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10635           UNSPEC_COPYSIGN))]
10636   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10637    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10638   "#"
10639   "&& reload_completed"
10640   [(const_int 0)]
10641 {
10642   ix86_split_copysign_const (operands);
10643   DONE;
10644 })
10645
10646 (define_insn "copysign<mode>3_var"
10647   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10648         (unspec:CSGNMODE
10649           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10650            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10651            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10652            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10653           UNSPEC_COPYSIGN))
10654    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10655   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10656    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10657   "#")
10658
10659 (define_split
10660   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10661         (unspec:CSGNMODE
10662           [(match_operand:CSGNMODE 2 "register_operand" "")
10663            (match_operand:CSGNMODE 3 "register_operand" "")
10664            (match_operand:<CSGNVMODE> 4 "" "")
10665            (match_operand:<CSGNVMODE> 5 "" "")]
10666           UNSPEC_COPYSIGN))
10667    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10668   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10669     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10670    && reload_completed"
10671   [(const_int 0)]
10672 {
10673   ix86_split_copysign_var (operands);
10674   DONE;
10675 })
10676 \f
10677 ;; One complement instructions
10678
10679 (define_expand "one_cmpldi2"
10680   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10681         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10682   "TARGET_64BIT"
10683   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10684
10685 (define_insn "*one_cmpldi2_1_rex64"
10686   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10687         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10688   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10689   "not{q}\t%0"
10690   [(set_attr "type" "negnot")
10691    (set_attr "mode" "DI")])
10692
10693 (define_insn "*one_cmpldi2_2_rex64"
10694   [(set (reg FLAGS_REG)
10695         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10696                  (const_int 0)))
10697    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10698         (not:DI (match_dup 1)))]
10699   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10700    && ix86_unary_operator_ok (NOT, DImode, operands)"
10701   "#"
10702   [(set_attr "type" "alu1")
10703    (set_attr "mode" "DI")])
10704
10705 (define_split
10706   [(set (match_operand 0 "flags_reg_operand" "")
10707         (match_operator 2 "compare_operator"
10708           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10709            (const_int 0)]))
10710    (set (match_operand:DI 1 "nonimmediate_operand" "")
10711         (not:DI (match_dup 3)))]
10712   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10713   [(parallel [(set (match_dup 0)
10714                    (match_op_dup 2
10715                      [(xor:DI (match_dup 3) (const_int -1))
10716                       (const_int 0)]))
10717               (set (match_dup 1)
10718                    (xor:DI (match_dup 3) (const_int -1)))])]
10719   "")
10720
10721 (define_expand "one_cmplsi2"
10722   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10723         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10724   ""
10725   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10726
10727 (define_insn "*one_cmplsi2_1"
10728   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10729         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10730   "ix86_unary_operator_ok (NOT, SImode, operands)"
10731   "not{l}\t%0"
10732   [(set_attr "type" "negnot")
10733    (set_attr "mode" "SI")])
10734
10735 ;; ??? Currently never generated - xor is used instead.
10736 (define_insn "*one_cmplsi2_1_zext"
10737   [(set (match_operand:DI 0 "register_operand" "=r")
10738         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10739   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10740   "not{l}\t%k0"
10741   [(set_attr "type" "negnot")
10742    (set_attr "mode" "SI")])
10743
10744 (define_insn "*one_cmplsi2_2"
10745   [(set (reg FLAGS_REG)
10746         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10747                  (const_int 0)))
10748    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10749         (not:SI (match_dup 1)))]
10750   "ix86_match_ccmode (insn, CCNOmode)
10751    && ix86_unary_operator_ok (NOT, SImode, operands)"
10752   "#"
10753   [(set_attr "type" "alu1")
10754    (set_attr "mode" "SI")])
10755
10756 (define_split
10757   [(set (match_operand 0 "flags_reg_operand" "")
10758         (match_operator 2 "compare_operator"
10759           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10760            (const_int 0)]))
10761    (set (match_operand:SI 1 "nonimmediate_operand" "")
10762         (not:SI (match_dup 3)))]
10763   "ix86_match_ccmode (insn, CCNOmode)"
10764   [(parallel [(set (match_dup 0)
10765                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10766                                     (const_int 0)]))
10767               (set (match_dup 1)
10768                    (xor:SI (match_dup 3) (const_int -1)))])]
10769   "")
10770
10771 ;; ??? Currently never generated - xor is used instead.
10772 (define_insn "*one_cmplsi2_2_zext"
10773   [(set (reg FLAGS_REG)
10774         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10775                  (const_int 0)))
10776    (set (match_operand:DI 0 "register_operand" "=r")
10777         (zero_extend:DI (not:SI (match_dup 1))))]
10778   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10779    && ix86_unary_operator_ok (NOT, SImode, operands)"
10780   "#"
10781   [(set_attr "type" "alu1")
10782    (set_attr "mode" "SI")])
10783
10784 (define_split
10785   [(set (match_operand 0 "flags_reg_operand" "")
10786         (match_operator 2 "compare_operator"
10787           [(not:SI (match_operand:SI 3 "register_operand" ""))
10788            (const_int 0)]))
10789    (set (match_operand:DI 1 "register_operand" "")
10790         (zero_extend:DI (not:SI (match_dup 3))))]
10791   "ix86_match_ccmode (insn, CCNOmode)"
10792   [(parallel [(set (match_dup 0)
10793                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10794                                     (const_int 0)]))
10795               (set (match_dup 1)
10796                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10797   "")
10798
10799 (define_expand "one_cmplhi2"
10800   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10801         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10802   "TARGET_HIMODE_MATH"
10803   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10804
10805 (define_insn "*one_cmplhi2_1"
10806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10807         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10808   "ix86_unary_operator_ok (NOT, HImode, operands)"
10809   "not{w}\t%0"
10810   [(set_attr "type" "negnot")
10811    (set_attr "mode" "HI")])
10812
10813 (define_insn "*one_cmplhi2_2"
10814   [(set (reg FLAGS_REG)
10815         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10816                  (const_int 0)))
10817    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10818         (not:HI (match_dup 1)))]
10819   "ix86_match_ccmode (insn, CCNOmode)
10820    && ix86_unary_operator_ok (NEG, HImode, operands)"
10821   "#"
10822   [(set_attr "type" "alu1")
10823    (set_attr "mode" "HI")])
10824
10825 (define_split
10826   [(set (match_operand 0 "flags_reg_operand" "")
10827         (match_operator 2 "compare_operator"
10828           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10829            (const_int 0)]))
10830    (set (match_operand:HI 1 "nonimmediate_operand" "")
10831         (not:HI (match_dup 3)))]
10832   "ix86_match_ccmode (insn, CCNOmode)"
10833   [(parallel [(set (match_dup 0)
10834                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10835                                     (const_int 0)]))
10836               (set (match_dup 1)
10837                    (xor:HI (match_dup 3) (const_int -1)))])]
10838   "")
10839
10840 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10841 (define_expand "one_cmplqi2"
10842   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10843         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10844   "TARGET_QIMODE_MATH"
10845   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10846
10847 (define_insn "*one_cmplqi2_1"
10848   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10849         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10850   "ix86_unary_operator_ok (NOT, QImode, operands)"
10851   "@
10852    not{b}\t%0
10853    not{l}\t%k0"
10854   [(set_attr "type" "negnot")
10855    (set_attr "mode" "QI,SI")])
10856
10857 (define_insn "*one_cmplqi2_2"
10858   [(set (reg FLAGS_REG)
10859         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10860                  (const_int 0)))
10861    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10862         (not:QI (match_dup 1)))]
10863   "ix86_match_ccmode (insn, CCNOmode)
10864    && ix86_unary_operator_ok (NOT, QImode, operands)"
10865   "#"
10866   [(set_attr "type" "alu1")
10867    (set_attr "mode" "QI")])
10868
10869 (define_split
10870   [(set (match_operand 0 "flags_reg_operand" "")
10871         (match_operator 2 "compare_operator"
10872           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10873            (const_int 0)]))
10874    (set (match_operand:QI 1 "nonimmediate_operand" "")
10875         (not:QI (match_dup 3)))]
10876   "ix86_match_ccmode (insn, CCNOmode)"
10877   [(parallel [(set (match_dup 0)
10878                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10879                                     (const_int 0)]))
10880               (set (match_dup 1)
10881                    (xor:QI (match_dup 3) (const_int -1)))])]
10882   "")
10883 \f
10884 ;; Arithmetic shift instructions
10885
10886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10889 ;; from the assembler input.
10890 ;;
10891 ;; This instruction shifts the target reg/mem as usual, but instead of
10892 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10893 ;; is a left shift double, bits are taken from the high order bits of
10894 ;; reg, else if the insn is a shift right double, bits are taken from the
10895 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10897 ;;
10898 ;; Since sh[lr]d does not change the `reg' operand, that is done
10899 ;; separately, making all shifts emit pairs of shift double and normal
10900 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10901 ;; support a 63 bit shift, each shift where the count is in a reg expands
10902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10903 ;;
10904 ;; If the shift count is a constant, we need never emit more than one
10905 ;; shift pair, instead using moves and sign extension for counts greater
10906 ;; than 31.
10907
10908 (define_expand "ashlti3"
10909   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10910                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10911                               (match_operand:QI 2 "nonmemory_operand" "")))
10912               (clobber (reg:CC FLAGS_REG))])]
10913   "TARGET_64BIT"
10914 {
10915   if (! immediate_operand (operands[2], QImode))
10916     {
10917       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10918       DONE;
10919     }
10920   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10921   DONE;
10922 })
10923
10924 (define_insn "ashlti3_1"
10925   [(set (match_operand:TI 0 "register_operand" "=r")
10926         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10927                    (match_operand:QI 2 "register_operand" "c")))
10928    (clobber (match_scratch:DI 3 "=&r"))
10929    (clobber (reg:CC FLAGS_REG))]
10930   "TARGET_64BIT"
10931   "#"
10932   [(set_attr "type" "multi")])
10933
10934 ;; This pattern must be defined before *ashlti3_2 to prevent
10935 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10936
10937 (define_insn "sse2_ashlti3"
10938   [(set (match_operand:TI 0 "register_operand" "=x")
10939         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10940                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10941   "TARGET_SSE2"
10942 {
10943   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10944   return "pslldq\t{%2, %0|%0, %2}";
10945 }
10946   [(set_attr "type" "sseishft")
10947    (set_attr "prefix_data16" "1")
10948    (set_attr "mode" "TI")])
10949
10950 (define_insn "*ashlti3_2"
10951   [(set (match_operand:TI 0 "register_operand" "=r")
10952         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10953                    (match_operand:QI 2 "immediate_operand" "O")))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "TARGET_64BIT"
10956   "#"
10957   [(set_attr "type" "multi")])
10958
10959 (define_split
10960   [(set (match_operand:TI 0 "register_operand" "")
10961         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10962                    (match_operand:QI 2 "register_operand" "")))
10963    (clobber (match_scratch:DI 3 ""))
10964    (clobber (reg:CC FLAGS_REG))]
10965   "TARGET_64BIT && reload_completed"
10966   [(const_int 0)]
10967   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10968
10969 (define_split
10970   [(set (match_operand:TI 0 "register_operand" "")
10971         (ashift:TI (match_operand:TI 1 "register_operand" "")
10972                    (match_operand:QI 2 "immediate_operand" "")))
10973    (clobber (reg:CC FLAGS_REG))]
10974   "TARGET_64BIT && reload_completed"
10975   [(const_int 0)]
10976   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10977
10978 (define_insn "x86_64_shld"
10979   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10980         (ior:DI (ashift:DI (match_dup 0)
10981                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10982                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10983                   (minus:QI (const_int 64) (match_dup 2)))))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "TARGET_64BIT"
10986   "@
10987    shld{q}\t{%2, %1, %0|%0, %1, %2}
10988    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10989   [(set_attr "type" "ishift")
10990    (set_attr "prefix_0f" "1")
10991    (set_attr "mode" "DI")
10992    (set_attr "athlon_decode" "vector")
10993    (set_attr "amdfam10_decode" "vector")])   
10994
10995 (define_expand "x86_64_shift_adj"
10996   [(set (reg:CCZ FLAGS_REG)
10997         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10998                              (const_int 64))
10999                      (const_int 0)))
11000    (set (match_operand:DI 0 "register_operand" "")
11001         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11002                          (match_operand:DI 1 "register_operand" "")
11003                          (match_dup 0)))
11004    (set (match_dup 1)
11005         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11006                          (match_operand:DI 3 "register_operand" "r")
11007                          (match_dup 1)))]
11008   "TARGET_64BIT"
11009   "")
11010
11011 (define_expand "ashldi3"
11012   [(set (match_operand:DI 0 "shiftdi_operand" "")
11013         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11014                    (match_operand:QI 2 "nonmemory_operand" "")))]
11015   ""
11016   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11017
11018 (define_insn "*ashldi3_1_rex64"
11019   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11020         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11021                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11022    (clobber (reg:CC FLAGS_REG))]
11023   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11024 {
11025   switch (get_attr_type (insn))
11026     {
11027     case TYPE_ALU:
11028       gcc_assert (operands[2] == const1_rtx);
11029       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11030       return "add{q}\t%0, %0";
11031
11032     case TYPE_LEA:
11033       gcc_assert (CONST_INT_P (operands[2]));
11034       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11035       operands[1] = gen_rtx_MULT (DImode, operands[1],
11036                                   GEN_INT (1 << INTVAL (operands[2])));
11037       return "lea{q}\t{%a1, %0|%0, %a1}";
11038
11039     default:
11040       if (REG_P (operands[2]))
11041         return "sal{q}\t{%b2, %0|%0, %b2}";
11042       else if (operands[2] == const1_rtx
11043                && (TARGET_SHIFT1 || optimize_size))
11044         return "sal{q}\t%0";
11045       else
11046         return "sal{q}\t{%2, %0|%0, %2}";
11047     }
11048 }
11049   [(set (attr "type")
11050      (cond [(eq_attr "alternative" "1")
11051               (const_string "lea")
11052             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11053                           (const_int 0))
11054                       (match_operand 0 "register_operand" ""))
11055                  (match_operand 2 "const1_operand" ""))
11056               (const_string "alu")
11057            ]
11058            (const_string "ishift")))
11059    (set_attr "mode" "DI")])
11060
11061 ;; Convert lea to the lea pattern to avoid flags dependency.
11062 (define_split
11063   [(set (match_operand:DI 0 "register_operand" "")
11064         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11065                    (match_operand:QI 2 "immediate_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_64BIT && reload_completed
11068    && true_regnum (operands[0]) != true_regnum (operands[1])"
11069   [(set (match_dup 0)
11070         (mult:DI (match_dup 1)
11071                  (match_dup 2)))]
11072   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11073
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags.  We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashldi3_cmp_rex64"
11078   [(set (reg FLAGS_REG)
11079         (compare
11080           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11081                      (match_operand:QI 2 "immediate_operand" "e"))
11082           (const_int 0)))
11083    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11084         (ashift:DI (match_dup 1) (match_dup 2)))]
11085   "TARGET_64BIT
11086    && (optimize_size
11087        || !TARGET_PARTIAL_FLAG_REG_STALL
11088        || (operands[2] == const1_rtx
11089            && (TARGET_SHIFT1
11090                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11091    && ix86_match_ccmode (insn, CCGOCmode)
11092    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11093 {
11094   switch (get_attr_type (insn))
11095     {
11096     case TYPE_ALU:
11097       gcc_assert (operands[2] == const1_rtx);
11098       return "add{q}\t%0, %0";
11099
11100     default:
11101       if (REG_P (operands[2]))
11102         return "sal{q}\t{%b2, %0|%0, %b2}";
11103       else if (operands[2] == const1_rtx
11104                && (TARGET_SHIFT1 || optimize_size))
11105         return "sal{q}\t%0";
11106       else
11107         return "sal{q}\t{%2, %0|%0, %2}";
11108     }
11109 }
11110   [(set (attr "type")
11111      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11112                           (const_int 0))
11113                       (match_operand 0 "register_operand" ""))
11114                  (match_operand 2 "const1_operand" ""))
11115               (const_string "alu")
11116            ]
11117            (const_string "ishift")))
11118    (set_attr "mode" "DI")])
11119
11120 (define_insn "*ashldi3_cconly_rex64"
11121   [(set (reg FLAGS_REG)
11122         (compare
11123           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11124                      (match_operand:QI 2 "immediate_operand" "e"))
11125           (const_int 0)))
11126    (clobber (match_scratch:DI 0 "=r"))]
11127   "TARGET_64BIT
11128    && (optimize_size
11129        || !TARGET_PARTIAL_FLAG_REG_STALL
11130        || (operands[2] == const1_rtx
11131            && (TARGET_SHIFT1
11132                || TARGET_DOUBLE_WITH_ADD)))
11133    && ix86_match_ccmode (insn, CCGOCmode)
11134    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11135 {
11136   switch (get_attr_type (insn))
11137     {
11138     case TYPE_ALU:
11139       gcc_assert (operands[2] == const1_rtx);
11140       return "add{q}\t%0, %0";
11141
11142     default:
11143       if (REG_P (operands[2]))
11144         return "sal{q}\t{%b2, %0|%0, %b2}";
11145       else if (operands[2] == const1_rtx
11146                && (TARGET_SHIFT1 || optimize_size))
11147         return "sal{q}\t%0";
11148       else
11149         return "sal{q}\t{%2, %0|%0, %2}";
11150     }
11151 }
11152   [(set (attr "type")
11153      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11154                           (const_int 0))
11155                       (match_operand 0 "register_operand" ""))
11156                  (match_operand 2 "const1_operand" ""))
11157               (const_string "alu")
11158            ]
11159            (const_string "ishift")))
11160    (set_attr "mode" "DI")])
11161
11162 (define_insn "*ashldi3_1"
11163   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11164         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11165                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "!TARGET_64BIT"
11168   "#"
11169   [(set_attr "type" "multi")])
11170
11171 ;; By default we don't ask for a scratch register, because when DImode
11172 ;; values are manipulated, registers are already at a premium.  But if
11173 ;; we have one handy, we won't turn it away.
11174 (define_peephole2
11175   [(match_scratch:SI 3 "r")
11176    (parallel [(set (match_operand:DI 0 "register_operand" "")
11177                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11178                               (match_operand:QI 2 "nonmemory_operand" "")))
11179               (clobber (reg:CC FLAGS_REG))])
11180    (match_dup 3)]
11181   "!TARGET_64BIT && TARGET_CMOVE"
11182   [(const_int 0)]
11183   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11184
11185 (define_split
11186   [(set (match_operand:DI 0 "register_operand" "")
11187         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11188                    (match_operand:QI 2 "nonmemory_operand" "")))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11191                      ? epilogue_completed : reload_completed)"
11192   [(const_int 0)]
11193   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11194
11195 (define_insn "x86_shld_1"
11196   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11197         (ior:SI (ashift:SI (match_dup 0)
11198                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11199                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11200                   (minus:QI (const_int 32) (match_dup 2)))))
11201    (clobber (reg:CC FLAGS_REG))]
11202   ""
11203   "@
11204    shld{l}\t{%2, %1, %0|%0, %1, %2}
11205    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11206   [(set_attr "type" "ishift")
11207    (set_attr "prefix_0f" "1")
11208    (set_attr "mode" "SI")
11209    (set_attr "pent_pair" "np")
11210    (set_attr "athlon_decode" "vector")
11211    (set_attr "amdfam10_decode" "vector")])   
11212
11213 (define_expand "x86_shift_adj_1"
11214   [(set (reg:CCZ FLAGS_REG)
11215         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11216                              (const_int 32))
11217                      (const_int 0)))
11218    (set (match_operand:SI 0 "register_operand" "")
11219         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11220                          (match_operand:SI 1 "register_operand" "")
11221                          (match_dup 0)))
11222    (set (match_dup 1)
11223         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11224                          (match_operand:SI 3 "register_operand" "r")
11225                          (match_dup 1)))]
11226   "TARGET_CMOVE"
11227   "")
11228
11229 (define_expand "x86_shift_adj_2"
11230   [(use (match_operand:SI 0 "register_operand" ""))
11231    (use (match_operand:SI 1 "register_operand" ""))
11232    (use (match_operand:QI 2 "register_operand" ""))]
11233   ""
11234 {
11235   rtx label = gen_label_rtx ();
11236   rtx tmp;
11237
11238   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11239
11240   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11241   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11242   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11243                               gen_rtx_LABEL_REF (VOIDmode, label),
11244                               pc_rtx);
11245   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11246   JUMP_LABEL (tmp) = label;
11247
11248   emit_move_insn (operands[0], operands[1]);
11249   ix86_expand_clear (operands[1]);
11250
11251   emit_label (label);
11252   LABEL_NUSES (label) = 1;
11253
11254   DONE;
11255 })
11256
11257 (define_expand "ashlsi3"
11258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260                    (match_operand:QI 2 "nonmemory_operand" "")))
11261    (clobber (reg:CC FLAGS_REG))]
11262   ""
11263   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11264
11265 (define_insn "*ashlsi3_1"
11266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11267         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11268                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11271 {
11272   switch (get_attr_type (insn))
11273     {
11274     case TYPE_ALU:
11275       gcc_assert (operands[2] == const1_rtx);
11276       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11277       return "add{l}\t%0, %0";
11278
11279     case TYPE_LEA:
11280       return "#";
11281
11282     default:
11283       if (REG_P (operands[2]))
11284         return "sal{l}\t{%b2, %0|%0, %b2}";
11285       else if (operands[2] == const1_rtx
11286                && (TARGET_SHIFT1 || optimize_size))
11287         return "sal{l}\t%0";
11288       else
11289         return "sal{l}\t{%2, %0|%0, %2}";
11290     }
11291 }
11292   [(set (attr "type")
11293      (cond [(eq_attr "alternative" "1")
11294               (const_string "lea")
11295             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11296                           (const_int 0))
11297                       (match_operand 0 "register_operand" ""))
11298                  (match_operand 2 "const1_operand" ""))
11299               (const_string "alu")
11300            ]
11301            (const_string "ishift")))
11302    (set_attr "mode" "SI")])
11303
11304 ;; Convert lea to the lea pattern to avoid flags dependency.
11305 (define_split
11306   [(set (match_operand 0 "register_operand" "")
11307         (ashift (match_operand 1 "index_register_operand" "")
11308                 (match_operand:QI 2 "const_int_operand" "")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "reload_completed
11311    && true_regnum (operands[0]) != true_regnum (operands[1])
11312    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11313   [(const_int 0)]
11314 {
11315   rtx pat;
11316   enum machine_mode mode = GET_MODE (operands[0]);
11317
11318   if (GET_MODE_SIZE (mode) < 4)
11319     operands[0] = gen_lowpart (SImode, operands[0]);
11320   if (mode != Pmode)
11321     operands[1] = gen_lowpart (Pmode, operands[1]);
11322   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11323
11324   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11325   if (Pmode != SImode)
11326     pat = gen_rtx_SUBREG (SImode, pat, 0);
11327   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11328   DONE;
11329 })
11330
11331 ;; Rare case of shifting RSP is handled by generating move and shift
11332 (define_split
11333   [(set (match_operand 0 "register_operand" "")
11334         (ashift (match_operand 1 "register_operand" "")
11335                 (match_operand:QI 2 "const_int_operand" "")))
11336    (clobber (reg:CC FLAGS_REG))]
11337   "reload_completed
11338    && true_regnum (operands[0]) != true_regnum (operands[1])"
11339   [(const_int 0)]
11340 {
11341   rtx pat, clob;
11342   emit_move_insn (operands[0], operands[1]);
11343   pat = gen_rtx_SET (VOIDmode, operands[0],
11344                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11345                                      operands[0], operands[2]));
11346   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11347   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11348   DONE;
11349 })
11350
11351 (define_insn "*ashlsi3_1_zext"
11352   [(set (match_operand:DI 0 "register_operand" "=r,r")
11353         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11354                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11355    (clobber (reg:CC FLAGS_REG))]
11356   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11357 {
11358   switch (get_attr_type (insn))
11359     {
11360     case TYPE_ALU:
11361       gcc_assert (operands[2] == const1_rtx);
11362       return "add{l}\t%k0, %k0";
11363
11364     case TYPE_LEA:
11365       return "#";
11366
11367     default:
11368       if (REG_P (operands[2]))
11369         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11370       else if (operands[2] == const1_rtx
11371                && (TARGET_SHIFT1 || optimize_size))
11372         return "sal{l}\t%k0";
11373       else
11374         return "sal{l}\t{%2, %k0|%k0, %2}";
11375     }
11376 }
11377   [(set (attr "type")
11378      (cond [(eq_attr "alternative" "1")
11379               (const_string "lea")
11380             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11381                      (const_int 0))
11382                  (match_operand 2 "const1_operand" ""))
11383               (const_string "alu")
11384            ]
11385            (const_string "ishift")))
11386    (set_attr "mode" "SI")])
11387
11388 ;; Convert lea to the lea pattern to avoid flags dependency.
11389 (define_split
11390   [(set (match_operand:DI 0 "register_operand" "")
11391         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11392                                 (match_operand:QI 2 "const_int_operand" ""))))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "TARGET_64BIT && reload_completed
11395    && true_regnum (operands[0]) != true_regnum (operands[1])"
11396   [(set (match_dup 0) (zero_extend:DI
11397                         (subreg:SI (mult:SI (match_dup 1)
11398                                             (match_dup 2)) 0)))]
11399 {
11400   operands[1] = gen_lowpart (Pmode, operands[1]);
11401   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11402 })
11403
11404 ;; This pattern can't accept a variable shift count, since shifts by
11405 ;; zero don't affect the flags.  We assume that shifts by constant
11406 ;; zero are optimized away.
11407 (define_insn "*ashlsi3_cmp"
11408   [(set (reg FLAGS_REG)
11409         (compare
11410           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11411                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11412           (const_int 0)))
11413    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11414         (ashift:SI (match_dup 1) (match_dup 2)))]
11415    "(optimize_size
11416      || !TARGET_PARTIAL_FLAG_REG_STALL
11417      || (operands[2] == const1_rtx
11418          && (TARGET_SHIFT1
11419              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11420    && ix86_match_ccmode (insn, CCGOCmode)
11421    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11422 {
11423   switch (get_attr_type (insn))
11424     {
11425     case TYPE_ALU:
11426       gcc_assert (operands[2] == const1_rtx);
11427       return "add{l}\t%0, %0";
11428
11429     default:
11430       if (REG_P (operands[2]))
11431         return "sal{l}\t{%b2, %0|%0, %b2}";
11432       else if (operands[2] == const1_rtx
11433                && (TARGET_SHIFT1 || optimize_size))
11434         return "sal{l}\t%0";
11435       else
11436         return "sal{l}\t{%2, %0|%0, %2}";
11437     }
11438 }
11439   [(set (attr "type")
11440      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11441                           (const_int 0))
11442                       (match_operand 0 "register_operand" ""))
11443                  (match_operand 2 "const1_operand" ""))
11444               (const_string "alu")
11445            ]
11446            (const_string "ishift")))
11447    (set_attr "mode" "SI")])
11448
11449 (define_insn "*ashlsi3_cconly"
11450   [(set (reg FLAGS_REG)
11451         (compare
11452           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11453                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11454           (const_int 0)))
11455    (clobber (match_scratch:SI 0 "=r"))]
11456   "(optimize_size
11457     || !TARGET_PARTIAL_FLAG_REG_STALL
11458     || (operands[2] == const1_rtx
11459         && (TARGET_SHIFT1
11460             || TARGET_DOUBLE_WITH_ADD)))
11461    && ix86_match_ccmode (insn, CCGOCmode)
11462    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11463 {
11464   switch (get_attr_type (insn))
11465     {
11466     case TYPE_ALU:
11467       gcc_assert (operands[2] == const1_rtx);
11468       return "add{l}\t%0, %0";
11469
11470     default:
11471       if (REG_P (operands[2]))
11472         return "sal{l}\t{%b2, %0|%0, %b2}";
11473       else if (operands[2] == const1_rtx
11474                && (TARGET_SHIFT1 || optimize_size))
11475         return "sal{l}\t%0";
11476       else
11477         return "sal{l}\t{%2, %0|%0, %2}";
11478     }
11479 }
11480   [(set (attr "type")
11481      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11482                           (const_int 0))
11483                       (match_operand 0 "register_operand" ""))
11484                  (match_operand 2 "const1_operand" ""))
11485               (const_string "alu")
11486            ]
11487            (const_string "ishift")))
11488    (set_attr "mode" "SI")])
11489
11490 (define_insn "*ashlsi3_cmp_zext"
11491   [(set (reg FLAGS_REG)
11492         (compare
11493           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11494                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11495           (const_int 0)))
11496    (set (match_operand:DI 0 "register_operand" "=r")
11497         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11498   "TARGET_64BIT
11499    && (optimize_size
11500        || !TARGET_PARTIAL_FLAG_REG_STALL
11501        || (operands[2] == const1_rtx
11502            && (TARGET_SHIFT1
11503                || TARGET_DOUBLE_WITH_ADD)))
11504    && ix86_match_ccmode (insn, CCGOCmode)
11505    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11506 {
11507   switch (get_attr_type (insn))
11508     {
11509     case TYPE_ALU:
11510       gcc_assert (operands[2] == const1_rtx);
11511       return "add{l}\t%k0, %k0";
11512
11513     default:
11514       if (REG_P (operands[2]))
11515         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11516       else if (operands[2] == const1_rtx
11517                && (TARGET_SHIFT1 || optimize_size))
11518         return "sal{l}\t%k0";
11519       else
11520         return "sal{l}\t{%2, %k0|%k0, %2}";
11521     }
11522 }
11523   [(set (attr "type")
11524      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11525                      (const_int 0))
11526                  (match_operand 2 "const1_operand" ""))
11527               (const_string "alu")
11528            ]
11529            (const_string "ishift")))
11530    (set_attr "mode" "SI")])
11531
11532 (define_expand "ashlhi3"
11533   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11534         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11535                    (match_operand:QI 2 "nonmemory_operand" "")))
11536    (clobber (reg:CC FLAGS_REG))]
11537   "TARGET_HIMODE_MATH"
11538   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11539
11540 (define_insn "*ashlhi3_1_lea"
11541   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11542         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11543                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "!TARGET_PARTIAL_REG_STALL
11546    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11547 {
11548   switch (get_attr_type (insn))
11549     {
11550     case TYPE_LEA:
11551       return "#";
11552     case TYPE_ALU:
11553       gcc_assert (operands[2] == const1_rtx);
11554       return "add{w}\t%0, %0";
11555
11556     default:
11557       if (REG_P (operands[2]))
11558         return "sal{w}\t{%b2, %0|%0, %b2}";
11559       else if (operands[2] == const1_rtx
11560                && (TARGET_SHIFT1 || optimize_size))
11561         return "sal{w}\t%0";
11562       else
11563         return "sal{w}\t{%2, %0|%0, %2}";
11564     }
11565 }
11566   [(set (attr "type")
11567      (cond [(eq_attr "alternative" "1")
11568               (const_string "lea")
11569             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11570                           (const_int 0))
11571                       (match_operand 0 "register_operand" ""))
11572                  (match_operand 2 "const1_operand" ""))
11573               (const_string "alu")
11574            ]
11575            (const_string "ishift")))
11576    (set_attr "mode" "HI,SI")])
11577
11578 (define_insn "*ashlhi3_1"
11579   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11580         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11581                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11582    (clobber (reg:CC FLAGS_REG))]
11583   "TARGET_PARTIAL_REG_STALL
11584    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11585 {
11586   switch (get_attr_type (insn))
11587     {
11588     case TYPE_ALU:
11589       gcc_assert (operands[2] == const1_rtx);
11590       return "add{w}\t%0, %0";
11591
11592     default:
11593       if (REG_P (operands[2]))
11594         return "sal{w}\t{%b2, %0|%0, %b2}";
11595       else if (operands[2] == const1_rtx
11596                && (TARGET_SHIFT1 || optimize_size))
11597         return "sal{w}\t%0";
11598       else
11599         return "sal{w}\t{%2, %0|%0, %2}";
11600     }
11601 }
11602   [(set (attr "type")
11603      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11604                           (const_int 0))
11605                       (match_operand 0 "register_operand" ""))
11606                  (match_operand 2 "const1_operand" ""))
11607               (const_string "alu")
11608            ]
11609            (const_string "ishift")))
11610    (set_attr "mode" "HI")])
11611
11612 ;; This pattern can't accept a variable shift count, since shifts by
11613 ;; zero don't affect the flags.  We assume that shifts by constant
11614 ;; zero are optimized away.
11615 (define_insn "*ashlhi3_cmp"
11616   [(set (reg FLAGS_REG)
11617         (compare
11618           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11619                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11620           (const_int 0)))
11621    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11622         (ashift:HI (match_dup 1) (match_dup 2)))]
11623   "(optimize_size
11624     || !TARGET_PARTIAL_FLAG_REG_STALL
11625     || (operands[2] == const1_rtx
11626         && (TARGET_SHIFT1
11627             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11628    && ix86_match_ccmode (insn, CCGOCmode)
11629    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11630 {
11631   switch (get_attr_type (insn))
11632     {
11633     case TYPE_ALU:
11634       gcc_assert (operands[2] == const1_rtx);
11635       return "add{w}\t%0, %0";
11636
11637     default:
11638       if (REG_P (operands[2]))
11639         return "sal{w}\t{%b2, %0|%0, %b2}";
11640       else if (operands[2] == const1_rtx
11641                && (TARGET_SHIFT1 || optimize_size))
11642         return "sal{w}\t%0";
11643       else
11644         return "sal{w}\t{%2, %0|%0, %2}";
11645     }
11646 }
11647   [(set (attr "type")
11648      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11649                           (const_int 0))
11650                       (match_operand 0 "register_operand" ""))
11651                  (match_operand 2 "const1_operand" ""))
11652               (const_string "alu")
11653            ]
11654            (const_string "ishift")))
11655    (set_attr "mode" "HI")])
11656
11657 (define_insn "*ashlhi3_cconly"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11661                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11662           (const_int 0)))
11663    (clobber (match_scratch:HI 0 "=r"))]
11664   "(optimize_size
11665     || !TARGET_PARTIAL_FLAG_REG_STALL
11666     || (operands[2] == const1_rtx
11667         && (TARGET_SHIFT1
11668             || TARGET_DOUBLE_WITH_ADD)))
11669    && ix86_match_ccmode (insn, CCGOCmode)
11670    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11671 {
11672   switch (get_attr_type (insn))
11673     {
11674     case TYPE_ALU:
11675       gcc_assert (operands[2] == const1_rtx);
11676       return "add{w}\t%0, %0";
11677
11678     default:
11679       if (REG_P (operands[2]))
11680         return "sal{w}\t{%b2, %0|%0, %b2}";
11681       else if (operands[2] == const1_rtx
11682                && (TARGET_SHIFT1 || optimize_size))
11683         return "sal{w}\t%0";
11684       else
11685         return "sal{w}\t{%2, %0|%0, %2}";
11686     }
11687 }
11688   [(set (attr "type")
11689      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11690                           (const_int 0))
11691                       (match_operand 0 "register_operand" ""))
11692                  (match_operand 2 "const1_operand" ""))
11693               (const_string "alu")
11694            ]
11695            (const_string "ishift")))
11696    (set_attr "mode" "HI")])
11697
11698 (define_expand "ashlqi3"
11699   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11700         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11701                    (match_operand:QI 2 "nonmemory_operand" "")))
11702    (clobber (reg:CC FLAGS_REG))]
11703   "TARGET_QIMODE_MATH"
11704   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11705
11706 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11707
11708 (define_insn "*ashlqi3_1_lea"
11709   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11710         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11711                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11712    (clobber (reg:CC FLAGS_REG))]
11713   "!TARGET_PARTIAL_REG_STALL
11714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11715 {
11716   switch (get_attr_type (insn))
11717     {
11718     case TYPE_LEA:
11719       return "#";
11720     case TYPE_ALU:
11721       gcc_assert (operands[2] == const1_rtx);
11722       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11723         return "add{l}\t%k0, %k0";
11724       else
11725         return "add{b}\t%0, %0";
11726
11727     default:
11728       if (REG_P (operands[2]))
11729         {
11730           if (get_attr_mode (insn) == MODE_SI)
11731             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11732           else
11733             return "sal{b}\t{%b2, %0|%0, %b2}";
11734         }
11735       else if (operands[2] == const1_rtx
11736                && (TARGET_SHIFT1 || optimize_size))
11737         {
11738           if (get_attr_mode (insn) == MODE_SI)
11739             return "sal{l}\t%0";
11740           else
11741             return "sal{b}\t%0";
11742         }
11743       else
11744         {
11745           if (get_attr_mode (insn) == MODE_SI)
11746             return "sal{l}\t{%2, %k0|%k0, %2}";
11747           else
11748             return "sal{b}\t{%2, %0|%0, %2}";
11749         }
11750     }
11751 }
11752   [(set (attr "type")
11753      (cond [(eq_attr "alternative" "2")
11754               (const_string "lea")
11755             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11756                           (const_int 0))
11757                       (match_operand 0 "register_operand" ""))
11758                  (match_operand 2 "const1_operand" ""))
11759               (const_string "alu")
11760            ]
11761            (const_string "ishift")))
11762    (set_attr "mode" "QI,SI,SI")])
11763
11764 (define_insn "*ashlqi3_1"
11765   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11766         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11767                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11768    (clobber (reg:CC FLAGS_REG))]
11769   "TARGET_PARTIAL_REG_STALL
11770    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11771 {
11772   switch (get_attr_type (insn))
11773     {
11774     case TYPE_ALU:
11775       gcc_assert (operands[2] == const1_rtx);
11776       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11777         return "add{l}\t%k0, %k0";
11778       else
11779         return "add{b}\t%0, %0";
11780
11781     default:
11782       if (REG_P (operands[2]))
11783         {
11784           if (get_attr_mode (insn) == MODE_SI)
11785             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11786           else
11787             return "sal{b}\t{%b2, %0|%0, %b2}";
11788         }
11789       else if (operands[2] == const1_rtx
11790                && (TARGET_SHIFT1 || optimize_size))
11791         {
11792           if (get_attr_mode (insn) == MODE_SI)
11793             return "sal{l}\t%0";
11794           else
11795             return "sal{b}\t%0";
11796         }
11797       else
11798         {
11799           if (get_attr_mode (insn) == MODE_SI)
11800             return "sal{l}\t{%2, %k0|%k0, %2}";
11801           else
11802             return "sal{b}\t{%2, %0|%0, %2}";
11803         }
11804     }
11805 }
11806   [(set (attr "type")
11807      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11808                           (const_int 0))
11809                       (match_operand 0 "register_operand" ""))
11810                  (match_operand 2 "const1_operand" ""))
11811               (const_string "alu")
11812            ]
11813            (const_string "ishift")))
11814    (set_attr "mode" "QI,SI")])
11815
11816 ;; This pattern can't accept a variable shift count, since shifts by
11817 ;; zero don't affect the flags.  We assume that shifts by constant
11818 ;; zero are optimized away.
11819 (define_insn "*ashlqi3_cmp"
11820   [(set (reg FLAGS_REG)
11821         (compare
11822           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11823                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11824           (const_int 0)))
11825    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11826         (ashift:QI (match_dup 1) (match_dup 2)))]
11827   "(optimize_size
11828     || !TARGET_PARTIAL_FLAG_REG_STALL
11829     || (operands[2] == const1_rtx
11830         && (TARGET_SHIFT1
11831             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11832    && ix86_match_ccmode (insn, CCGOCmode)
11833    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11834 {
11835   switch (get_attr_type (insn))
11836     {
11837     case TYPE_ALU:
11838       gcc_assert (operands[2] == const1_rtx);
11839       return "add{b}\t%0, %0";
11840
11841     default:
11842       if (REG_P (operands[2]))
11843         return "sal{b}\t{%b2, %0|%0, %b2}";
11844       else if (operands[2] == const1_rtx
11845                && (TARGET_SHIFT1 || optimize_size))
11846         return "sal{b}\t%0";
11847       else
11848         return "sal{b}\t{%2, %0|%0, %2}";
11849     }
11850 }
11851   [(set (attr "type")
11852      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11853                           (const_int 0))
11854                       (match_operand 0 "register_operand" ""))
11855                  (match_operand 2 "const1_operand" ""))
11856               (const_string "alu")
11857            ]
11858            (const_string "ishift")))
11859    (set_attr "mode" "QI")])
11860
11861 (define_insn "*ashlqi3_cconly"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866           (const_int 0)))
11867    (clobber (match_scratch:QI 0 "=q"))]
11868   "(optimize_size
11869     || !TARGET_PARTIAL_FLAG_REG_STALL
11870     || (operands[2] == const1_rtx
11871         && (TARGET_SHIFT1
11872             || TARGET_DOUBLE_WITH_ADD)))
11873    && ix86_match_ccmode (insn, CCGOCmode)
11874    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11875 {
11876   switch (get_attr_type (insn))
11877     {
11878     case TYPE_ALU:
11879       gcc_assert (operands[2] == const1_rtx);
11880       return "add{b}\t%0, %0";
11881
11882     default:
11883       if (REG_P (operands[2]))
11884         return "sal{b}\t{%b2, %0|%0, %b2}";
11885       else if (operands[2] == const1_rtx
11886                && (TARGET_SHIFT1 || optimize_size))
11887         return "sal{b}\t%0";
11888       else
11889         return "sal{b}\t{%2, %0|%0, %2}";
11890     }
11891 }
11892   [(set (attr "type")
11893      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11894                           (const_int 0))
11895                       (match_operand 0 "register_operand" ""))
11896                  (match_operand 2 "const1_operand" ""))
11897               (const_string "alu")
11898            ]
11899            (const_string "ishift")))
11900    (set_attr "mode" "QI")])
11901
11902 ;; See comment above `ashldi3' about how this works.
11903
11904 (define_expand "ashrti3"
11905   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11906                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11907                                 (match_operand:QI 2 "nonmemory_operand" "")))
11908               (clobber (reg:CC FLAGS_REG))])]
11909   "TARGET_64BIT"
11910 {
11911   if (! immediate_operand (operands[2], QImode))
11912     {
11913       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11914       DONE;
11915     }
11916   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11917   DONE;
11918 })
11919
11920 (define_insn "ashrti3_1"
11921   [(set (match_operand:TI 0 "register_operand" "=r")
11922         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11923                      (match_operand:QI 2 "register_operand" "c")))
11924    (clobber (match_scratch:DI 3 "=&r"))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "TARGET_64BIT"
11927   "#"
11928   [(set_attr "type" "multi")])
11929
11930 (define_insn "*ashrti3_2"
11931   [(set (match_operand:TI 0 "register_operand" "=r")
11932         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933                      (match_operand:QI 2 "immediate_operand" "O")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "TARGET_64BIT"
11936   "#"
11937   [(set_attr "type" "multi")])
11938
11939 (define_split
11940   [(set (match_operand:TI 0 "register_operand" "")
11941         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11942                      (match_operand:QI 2 "register_operand" "")))
11943    (clobber (match_scratch:DI 3 ""))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "TARGET_64BIT && reload_completed"
11946   [(const_int 0)]
11947   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11948
11949 (define_split
11950   [(set (match_operand:TI 0 "register_operand" "")
11951         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11952                      (match_operand:QI 2 "immediate_operand" "")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "TARGET_64BIT && reload_completed"
11955   [(const_int 0)]
11956   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11957
11958 (define_insn "x86_64_shrd"
11959   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11960         (ior:DI (ashiftrt:DI (match_dup 0)
11961                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11962                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11963                   (minus:QI (const_int 64) (match_dup 2)))))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_64BIT"
11966   "@
11967    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11968    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11969   [(set_attr "type" "ishift")
11970    (set_attr "prefix_0f" "1")
11971    (set_attr "mode" "DI")
11972    (set_attr "athlon_decode" "vector")
11973    (set_attr "amdfam10_decode" "vector")])   
11974
11975 (define_expand "ashrdi3"
11976   [(set (match_operand:DI 0 "shiftdi_operand" "")
11977         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11978                      (match_operand:QI 2 "nonmemory_operand" "")))]
11979   ""
11980   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11981
11982 (define_insn "*ashrdi3_63_rex64"
11983   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11984         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11985                      (match_operand:DI 2 "const_int_operand" "i,i")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "TARGET_64BIT && INTVAL (operands[2]) == 63
11988    && (TARGET_USE_CLTD || optimize_size)
11989    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11990   "@
11991    {cqto|cqo}
11992    sar{q}\t{%2, %0|%0, %2}"
11993   [(set_attr "type" "imovx,ishift")
11994    (set_attr "prefix_0f" "0,*")
11995    (set_attr "length_immediate" "0,*")
11996    (set_attr "modrm" "0,1")
11997    (set_attr "mode" "DI")])
11998
11999 (define_insn "*ashrdi3_1_one_bit_rex64"
12000   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12001         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "TARGET_64BIT
12005    && (TARGET_SHIFT1 || optimize_size)
12006    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12007   "sar{q}\t%0"
12008   [(set_attr "type" "ishift")
12009    (set (attr "length")
12010      (if_then_else (match_operand:DI 0 "register_operand" "")
12011         (const_string "2")
12012         (const_string "*")))])
12013
12014 (define_insn "*ashrdi3_1_rex64"
12015   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12016         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12017                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12020   "@
12021    sar{q}\t{%2, %0|%0, %2}
12022    sar{q}\t{%b2, %0|%0, %b2}"
12023   [(set_attr "type" "ishift")
12024    (set_attr "mode" "DI")])
12025
12026 ;; This pattern can't accept a variable shift count, since shifts by
12027 ;; zero don't affect the flags.  We assume that shifts by constant
12028 ;; zero are optimized away.
12029 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12030   [(set (reg FLAGS_REG)
12031         (compare
12032           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12033                        (match_operand:QI 2 "const1_operand" ""))
12034           (const_int 0)))
12035    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12036         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12037   "TARGET_64BIT
12038    && (TARGET_SHIFT1 || optimize_size)
12039    && ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12041   "sar{q}\t%0"
12042   [(set_attr "type" "ishift")
12043    (set (attr "length")
12044      (if_then_else (match_operand:DI 0 "register_operand" "")
12045         (const_string "2")
12046         (const_string "*")))])
12047
12048 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12049   [(set (reg FLAGS_REG)
12050         (compare
12051           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052                        (match_operand:QI 2 "const1_operand" ""))
12053           (const_int 0)))
12054    (clobber (match_scratch:DI 0 "=r"))]
12055   "TARGET_64BIT
12056    && (TARGET_SHIFT1 || optimize_size)
12057    && ix86_match_ccmode (insn, CCGOCmode)
12058    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12059   "sar{q}\t%0"
12060   [(set_attr "type" "ishift")
12061    (set_attr "length" "2")])
12062
12063 ;; This pattern can't accept a variable shift count, since shifts by
12064 ;; zero don't affect the flags.  We assume that shifts by constant
12065 ;; zero are optimized away.
12066 (define_insn "*ashrdi3_cmp_rex64"
12067   [(set (reg FLAGS_REG)
12068         (compare
12069           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12070                        (match_operand:QI 2 "const_int_operand" "n"))
12071           (const_int 0)))
12072    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12074   "TARGET_64BIT
12075    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12076    && ix86_match_ccmode (insn, CCGOCmode)
12077    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12078   "sar{q}\t{%2, %0|%0, %2}"
12079   [(set_attr "type" "ishift")
12080    (set_attr "mode" "DI")])
12081
12082 (define_insn "*ashrdi3_cconly_rex64"
12083   [(set (reg FLAGS_REG)
12084         (compare
12085           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12086                        (match_operand:QI 2 "const_int_operand" "n"))
12087           (const_int 0)))
12088    (clobber (match_scratch:DI 0 "=r"))]
12089   "TARGET_64BIT
12090    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12091    && ix86_match_ccmode (insn, CCGOCmode)
12092    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12093   "sar{q}\t{%2, %0|%0, %2}"
12094   [(set_attr "type" "ishift")
12095    (set_attr "mode" "DI")])
12096
12097 (define_insn "*ashrdi3_1"
12098   [(set (match_operand:DI 0 "register_operand" "=r")
12099         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12100                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   "!TARGET_64BIT"
12103   "#"
12104   [(set_attr "type" "multi")])
12105
12106 ;; By default we don't ask for a scratch register, because when DImode
12107 ;; values are manipulated, registers are already at a premium.  But if
12108 ;; we have one handy, we won't turn it away.
12109 (define_peephole2
12110   [(match_scratch:SI 3 "r")
12111    (parallel [(set (match_operand:DI 0 "register_operand" "")
12112                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12113                                 (match_operand:QI 2 "nonmemory_operand" "")))
12114               (clobber (reg:CC FLAGS_REG))])
12115    (match_dup 3)]
12116   "!TARGET_64BIT && TARGET_CMOVE"
12117   [(const_int 0)]
12118   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12119
12120 (define_split
12121   [(set (match_operand:DI 0 "register_operand" "")
12122         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12123                      (match_operand:QI 2 "nonmemory_operand" "")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12126                      ? epilogue_completed : reload_completed)"
12127   [(const_int 0)]
12128   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12129
12130 (define_insn "x86_shrd_1"
12131   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12132         (ior:SI (ashiftrt:SI (match_dup 0)
12133                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12134                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12135                   (minus:QI (const_int 32) (match_dup 2)))))
12136    (clobber (reg:CC FLAGS_REG))]
12137   ""
12138   "@
12139    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12140    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12141   [(set_attr "type" "ishift")
12142    (set_attr "prefix_0f" "1")
12143    (set_attr "pent_pair" "np")
12144    (set_attr "mode" "SI")])
12145
12146 (define_expand "x86_shift_adj_3"
12147   [(use (match_operand:SI 0 "register_operand" ""))
12148    (use (match_operand:SI 1 "register_operand" ""))
12149    (use (match_operand:QI 2 "register_operand" ""))]
12150   ""
12151 {
12152   rtx label = gen_label_rtx ();
12153   rtx tmp;
12154
12155   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12156
12157   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12158   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12159   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12160                               gen_rtx_LABEL_REF (VOIDmode, label),
12161                               pc_rtx);
12162   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12163   JUMP_LABEL (tmp) = label;
12164
12165   emit_move_insn (operands[0], operands[1]);
12166   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12167
12168   emit_label (label);
12169   LABEL_NUSES (label) = 1;
12170
12171   DONE;
12172 })
12173
12174 (define_insn "ashrsi3_31"
12175   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12176         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12177                      (match_operand:SI 2 "const_int_operand" "i,i")))
12178    (clobber (reg:CC FLAGS_REG))]
12179   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12180    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181   "@
12182    {cltd|cdq}
12183    sar{l}\t{%2, %0|%0, %2}"
12184   [(set_attr "type" "imovx,ishift")
12185    (set_attr "prefix_0f" "0,*")
12186    (set_attr "length_immediate" "0,*")
12187    (set_attr "modrm" "0,1")
12188    (set_attr "mode" "SI")])
12189
12190 (define_insn "*ashrsi3_31_zext"
12191   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12192         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12193                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12196    && INTVAL (operands[2]) == 31
12197    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12198   "@
12199    {cltd|cdq}
12200    sar{l}\t{%2, %k0|%k0, %2}"
12201   [(set_attr "type" "imovx,ishift")
12202    (set_attr "prefix_0f" "0,*")
12203    (set_attr "length_immediate" "0,*")
12204    (set_attr "modrm" "0,1")
12205    (set_attr "mode" "SI")])
12206
12207 (define_expand "ashrsi3"
12208   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12209         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12210                      (match_operand:QI 2 "nonmemory_operand" "")))
12211    (clobber (reg:CC FLAGS_REG))]
12212   ""
12213   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12214
12215 (define_insn "*ashrsi3_1_one_bit"
12216   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12217         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218                      (match_operand:QI 2 "const1_operand" "")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "(TARGET_SHIFT1 || optimize_size)
12221    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12222   "sar{l}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:SI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*ashrsi3_1_one_bit_zext"
12230   [(set (match_operand:DI 0 "register_operand" "=r")
12231         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12232                                      (match_operand:QI 2 "const1_operand" ""))))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT
12235    && (TARGET_SHIFT1 || optimize_size)
12236    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12237   "sar{l}\t%k0"
12238   [(set_attr "type" "ishift")
12239    (set_attr "length" "2")])
12240
12241 (define_insn "*ashrsi3_1"
12242   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12243         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12244                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12247   "@
12248    sar{l}\t{%2, %0|%0, %2}
12249    sar{l}\t{%b2, %0|%0, %b2}"
12250   [(set_attr "type" "ishift")
12251    (set_attr "mode" "SI")])
12252
12253 (define_insn "*ashrsi3_1_zext"
12254   [(set (match_operand:DI 0 "register_operand" "=r,r")
12255         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12256                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12257    (clobber (reg:CC FLAGS_REG))]
12258   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12259   "@
12260    sar{l}\t{%2, %k0|%k0, %2}
12261    sar{l}\t{%b2, %k0|%k0, %b2}"
12262   [(set_attr "type" "ishift")
12263    (set_attr "mode" "SI")])
12264
12265 ;; This pattern can't accept a variable shift count, since shifts by
12266 ;; zero don't affect the flags.  We assume that shifts by constant
12267 ;; zero are optimized away.
12268 (define_insn "*ashrsi3_one_bit_cmp"
12269   [(set (reg FLAGS_REG)
12270         (compare
12271           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12272                        (match_operand:QI 2 "const1_operand" ""))
12273           (const_int 0)))
12274    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12275         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12276   "(TARGET_SHIFT1 || optimize_size)
12277    && ix86_match_ccmode (insn, CCGOCmode)
12278    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12279   "sar{l}\t%0"
12280   [(set_attr "type" "ishift")
12281    (set (attr "length")
12282      (if_then_else (match_operand:SI 0 "register_operand" "")
12283         (const_string "2")
12284         (const_string "*")))])
12285
12286 (define_insn "*ashrsi3_one_bit_cconly"
12287   [(set (reg FLAGS_REG)
12288         (compare
12289           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12290                        (match_operand:QI 2 "const1_operand" ""))
12291           (const_int 0)))
12292    (clobber (match_scratch:SI 0 "=r"))]
12293   "(TARGET_SHIFT1 || optimize_size)
12294    && ix86_match_ccmode (insn, CCGOCmode)
12295    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12296   "sar{l}\t%0"
12297   [(set_attr "type" "ishift")
12298    (set_attr "length" "2")])
12299
12300 (define_insn "*ashrsi3_one_bit_cmp_zext"
12301   [(set (reg FLAGS_REG)
12302         (compare
12303           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12304                        (match_operand:QI 2 "const1_operand" ""))
12305           (const_int 0)))
12306    (set (match_operand:DI 0 "register_operand" "=r")
12307         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12308   "TARGET_64BIT
12309    && (TARGET_SHIFT1 || optimize_size)
12310    && ix86_match_ccmode (insn, CCmode)
12311    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12312   "sar{l}\t%k0"
12313   [(set_attr "type" "ishift")
12314    (set_attr "length" "2")])
12315
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags.  We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*ashrsi3_cmp"
12320   [(set (reg FLAGS_REG)
12321         (compare
12322           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12323                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12324           (const_int 0)))
12325    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12326         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12327   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328    && ix86_match_ccmode (insn, CCGOCmode)
12329    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12330   "sar{l}\t{%2, %0|%0, %2}"
12331   [(set_attr "type" "ishift")
12332    (set_attr "mode" "SI")])
12333
12334 (define_insn "*ashrsi3_cconly"
12335   [(set (reg FLAGS_REG)
12336         (compare
12337           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12338                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12339           (const_int 0)))
12340    (clobber (match_scratch:SI 0 "=r"))]
12341   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342    && ix86_match_ccmode (insn, CCGOCmode)
12343    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12344   "sar{l}\t{%2, %0|%0, %2}"
12345   [(set_attr "type" "ishift")
12346    (set_attr "mode" "SI")])
12347
12348 (define_insn "*ashrsi3_cmp_zext"
12349   [(set (reg FLAGS_REG)
12350         (compare
12351           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12352                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12353           (const_int 0)))
12354    (set (match_operand:DI 0 "register_operand" "=r")
12355         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12356   "TARGET_64BIT
12357    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12358    && ix86_match_ccmode (insn, CCGOCmode)
12359    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12360   "sar{l}\t{%2, %k0|%k0, %2}"
12361   [(set_attr "type" "ishift")
12362    (set_attr "mode" "SI")])
12363
12364 (define_expand "ashrhi3"
12365   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12366         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12367                      (match_operand:QI 2 "nonmemory_operand" "")))
12368    (clobber (reg:CC FLAGS_REG))]
12369   "TARGET_HIMODE_MATH"
12370   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12371
12372 (define_insn "*ashrhi3_1_one_bit"
12373   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12374         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12375                      (match_operand:QI 2 "const1_operand" "")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "(TARGET_SHIFT1 || optimize_size)
12378    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12379   "sar{w}\t%0"
12380   [(set_attr "type" "ishift")
12381    (set (attr "length")
12382      (if_then_else (match_operand 0 "register_operand" "")
12383         (const_string "2")
12384         (const_string "*")))])
12385
12386 (define_insn "*ashrhi3_1"
12387   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12388         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12389                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12390    (clobber (reg:CC FLAGS_REG))]
12391   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12392   "@
12393    sar{w}\t{%2, %0|%0, %2}
12394    sar{w}\t{%b2, %0|%0, %b2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "HI")])
12397
12398 ;; This pattern can't accept a variable shift count, since shifts by
12399 ;; zero don't affect the flags.  We assume that shifts by constant
12400 ;; zero are optimized away.
12401 (define_insn "*ashrhi3_one_bit_cmp"
12402   [(set (reg FLAGS_REG)
12403         (compare
12404           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405                        (match_operand:QI 2 "const1_operand" ""))
12406           (const_int 0)))
12407    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12408         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12409   "(TARGET_SHIFT1 || optimize_size)
12410    && ix86_match_ccmode (insn, CCGOCmode)
12411    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12412   "sar{w}\t%0"
12413   [(set_attr "type" "ishift")
12414    (set (attr "length")
12415      (if_then_else (match_operand 0 "register_operand" "")
12416         (const_string "2")
12417         (const_string "*")))])
12418
12419 (define_insn "*ashrhi3_one_bit_cconly"
12420   [(set (reg FLAGS_REG)
12421         (compare
12422           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12423                        (match_operand:QI 2 "const1_operand" ""))
12424           (const_int 0)))
12425    (clobber (match_scratch:HI 0 "=r"))]
12426   "(TARGET_SHIFT1 || optimize_size)
12427    && ix86_match_ccmode (insn, CCGOCmode)
12428    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12429   "sar{w}\t%0"
12430   [(set_attr "type" "ishift")
12431    (set_attr "length" "2")])
12432
12433 ;; This pattern can't accept a variable shift count, since shifts by
12434 ;; zero don't affect the flags.  We assume that shifts by constant
12435 ;; zero are optimized away.
12436 (define_insn "*ashrhi3_cmp"
12437   [(set (reg FLAGS_REG)
12438         (compare
12439           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12440                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12441           (const_int 0)))
12442    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12443         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12444   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12445    && ix86_match_ccmode (insn, CCGOCmode)
12446    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12447   "sar{w}\t{%2, %0|%0, %2}"
12448   [(set_attr "type" "ishift")
12449    (set_attr "mode" "HI")])
12450
12451 (define_insn "*ashrhi3_cconly"
12452   [(set (reg FLAGS_REG)
12453         (compare
12454           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12455                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12456           (const_int 0)))
12457    (clobber (match_scratch:HI 0 "=r"))]
12458   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12459    && ix86_match_ccmode (insn, CCGOCmode)
12460    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12461   "sar{w}\t{%2, %0|%0, %2}"
12462   [(set_attr "type" "ishift")
12463    (set_attr "mode" "HI")])
12464
12465 (define_expand "ashrqi3"
12466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12467         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12468                      (match_operand:QI 2 "nonmemory_operand" "")))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "TARGET_QIMODE_MATH"
12471   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12472
12473 (define_insn "*ashrqi3_1_one_bit"
12474   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12475         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476                      (match_operand:QI 2 "const1_operand" "")))
12477    (clobber (reg:CC FLAGS_REG))]
12478   "(TARGET_SHIFT1 || optimize_size)
12479    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12480   "sar{b}\t%0"
12481   [(set_attr "type" "ishift")
12482    (set (attr "length")
12483      (if_then_else (match_operand 0 "register_operand" "")
12484         (const_string "2")
12485         (const_string "*")))])
12486
12487 (define_insn "*ashrqi3_1_one_bit_slp"
12488   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12489         (ashiftrt:QI (match_dup 0)
12490                      (match_operand:QI 1 "const1_operand" "")))
12491    (clobber (reg:CC FLAGS_REG))]
12492   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493    && (TARGET_SHIFT1 || optimize_size)
12494    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12495   "sar{b}\t%0"
12496   [(set_attr "type" "ishift1")
12497    (set (attr "length")
12498      (if_then_else (match_operand 0 "register_operand" "")
12499         (const_string "2")
12500         (const_string "*")))])
12501
12502 (define_insn "*ashrqi3_1"
12503   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12504         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12505                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12506    (clobber (reg:CC FLAGS_REG))]
12507   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12508   "@
12509    sar{b}\t{%2, %0|%0, %2}
12510    sar{b}\t{%b2, %0|%0, %b2}"
12511   [(set_attr "type" "ishift")
12512    (set_attr "mode" "QI")])
12513
12514 (define_insn "*ashrqi3_1_slp"
12515   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12516         (ashiftrt:QI (match_dup 0)
12517                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12520    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12521   "@
12522    sar{b}\t{%1, %0|%0, %1}
12523    sar{b}\t{%b1, %0|%0, %b1}"
12524   [(set_attr "type" "ishift1")
12525    (set_attr "mode" "QI")])
12526
12527 ;; This pattern can't accept a variable shift count, since shifts by
12528 ;; zero don't affect the flags.  We assume that shifts by constant
12529 ;; zero are optimized away.
12530 (define_insn "*ashrqi3_one_bit_cmp"
12531   [(set (reg FLAGS_REG)
12532         (compare
12533           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12534                        (match_operand:QI 2 "const1_operand" "I"))
12535           (const_int 0)))
12536    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12537         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12538   "(TARGET_SHIFT1 || optimize_size)
12539    && ix86_match_ccmode (insn, CCGOCmode)
12540    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12541   "sar{b}\t%0"
12542   [(set_attr "type" "ishift")
12543    (set (attr "length")
12544      (if_then_else (match_operand 0 "register_operand" "")
12545         (const_string "2")
12546         (const_string "*")))])
12547
12548 (define_insn "*ashrqi3_one_bit_cconly"
12549   [(set (reg FLAGS_REG)
12550         (compare
12551           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12552                        (match_operand:QI 2 "const1_operand" "I"))
12553           (const_int 0)))
12554    (clobber (match_scratch:QI 0 "=q"))]
12555   "(TARGET_SHIFT1 || optimize_size)
12556    && ix86_match_ccmode (insn, CCGOCmode)
12557    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12558   "sar{b}\t%0"
12559   [(set_attr "type" "ishift")
12560    (set_attr "length" "2")])
12561
12562 ;; This pattern can't accept a variable shift count, since shifts by
12563 ;; zero don't affect the flags.  We assume that shifts by constant
12564 ;; zero are optimized away.
12565 (define_insn "*ashrqi3_cmp"
12566   [(set (reg FLAGS_REG)
12567         (compare
12568           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12569                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12570           (const_int 0)))
12571    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12572         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12573   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12574    && ix86_match_ccmode (insn, CCGOCmode)
12575    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12576   "sar{b}\t{%2, %0|%0, %2}"
12577   [(set_attr "type" "ishift")
12578    (set_attr "mode" "QI")])
12579
12580 (define_insn "*ashrqi3_cconly"
12581   [(set (reg FLAGS_REG)
12582         (compare
12583           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12584                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12585           (const_int 0)))
12586    (clobber (match_scratch:QI 0 "=q"))]
12587   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12588    && ix86_match_ccmode (insn, CCGOCmode)
12589    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12590   "sar{b}\t{%2, %0|%0, %2}"
12591   [(set_attr "type" "ishift")
12592    (set_attr "mode" "QI")])
12593
12594 \f
12595 ;; Logical shift instructions
12596
12597 ;; See comment above `ashldi3' about how this works.
12598
12599 (define_expand "lshrti3"
12600   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12601                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12602                                 (match_operand:QI 2 "nonmemory_operand" "")))
12603               (clobber (reg:CC FLAGS_REG))])]
12604   "TARGET_64BIT"
12605 {
12606   if (! immediate_operand (operands[2], QImode))
12607     {
12608       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12609       DONE;
12610     }
12611   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12612   DONE;
12613 })
12614
12615 (define_insn "lshrti3_1"
12616   [(set (match_operand:TI 0 "register_operand" "=r")
12617         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12618                      (match_operand:QI 2 "register_operand" "c")))
12619    (clobber (match_scratch:DI 3 "=&r"))
12620    (clobber (reg:CC FLAGS_REG))]
12621   "TARGET_64BIT"
12622   "#"
12623   [(set_attr "type" "multi")])
12624
12625 ;; This pattern must be defined before *lshrti3_2 to prevent
12626 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12627
12628 (define_insn "sse2_lshrti3"
12629   [(set (match_operand:TI 0 "register_operand" "=x")
12630         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12631                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12632   "TARGET_SSE2"
12633 {
12634   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12635   return "psrldq\t{%2, %0|%0, %2}";
12636 }
12637   [(set_attr "type" "sseishft")
12638    (set_attr "prefix_data16" "1")
12639    (set_attr "mode" "TI")])
12640
12641 (define_insn "*lshrti3_2"
12642   [(set (match_operand:TI 0 "register_operand" "=r")
12643         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12644                      (match_operand:QI 2 "immediate_operand" "O")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "TARGET_64BIT"
12647   "#"
12648   [(set_attr "type" "multi")])
12649
12650 (define_split
12651   [(set (match_operand:TI 0 "register_operand" "")
12652         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12653                      (match_operand:QI 2 "register_operand" "")))
12654    (clobber (match_scratch:DI 3 ""))
12655    (clobber (reg:CC FLAGS_REG))]
12656   "TARGET_64BIT && reload_completed"
12657   [(const_int 0)]
12658   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12659
12660 (define_split
12661   [(set (match_operand:TI 0 "register_operand" "")
12662         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12663                      (match_operand:QI 2 "immediate_operand" "")))
12664    (clobber (reg:CC FLAGS_REG))]
12665   "TARGET_64BIT && reload_completed"
12666   [(const_int 0)]
12667   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12668
12669 (define_expand "lshrdi3"
12670   [(set (match_operand:DI 0 "shiftdi_operand" "")
12671         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12672                      (match_operand:QI 2 "nonmemory_operand" "")))]
12673   ""
12674   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12675
12676 (define_insn "*lshrdi3_1_one_bit_rex64"
12677   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12678         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12679                      (match_operand:QI 2 "const1_operand" "")))
12680    (clobber (reg:CC FLAGS_REG))]
12681   "TARGET_64BIT
12682    && (TARGET_SHIFT1 || optimize_size)
12683    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12684   "shr{q}\t%0"
12685   [(set_attr "type" "ishift")
12686    (set (attr "length")
12687      (if_then_else (match_operand:DI 0 "register_operand" "")
12688         (const_string "2")
12689         (const_string "*")))])
12690
12691 (define_insn "*lshrdi3_1_rex64"
12692   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12693         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12694                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12697   "@
12698    shr{q}\t{%2, %0|%0, %2}
12699    shr{q}\t{%b2, %0|%0, %b2}"
12700   [(set_attr "type" "ishift")
12701    (set_attr "mode" "DI")])
12702
12703 ;; This pattern can't accept a variable shift count, since shifts by
12704 ;; zero don't affect the flags.  We assume that shifts by constant
12705 ;; zero are optimized away.
12706 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12707   [(set (reg FLAGS_REG)
12708         (compare
12709           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12710                        (match_operand:QI 2 "const1_operand" ""))
12711           (const_int 0)))
12712    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12713         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12714   "TARGET_64BIT
12715    && (TARGET_SHIFT1 || optimize_size)
12716    && ix86_match_ccmode (insn, CCGOCmode)
12717    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12718   "shr{q}\t%0"
12719   [(set_attr "type" "ishift")
12720    (set (attr "length")
12721      (if_then_else (match_operand:DI 0 "register_operand" "")
12722         (const_string "2")
12723         (const_string "*")))])
12724
12725 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12726   [(set (reg FLAGS_REG)
12727         (compare
12728           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12729                        (match_operand:QI 2 "const1_operand" ""))
12730           (const_int 0)))
12731    (clobber (match_scratch:DI 0 "=r"))]
12732   "TARGET_64BIT
12733    && (TARGET_SHIFT1 || optimize_size)
12734    && ix86_match_ccmode (insn, CCGOCmode)
12735    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12736   "shr{q}\t%0"
12737   [(set_attr "type" "ishift")
12738    (set_attr "length" "2")])
12739
12740 ;; This pattern can't accept a variable shift count, since shifts by
12741 ;; zero don't affect the flags.  We assume that shifts by constant
12742 ;; zero are optimized away.
12743 (define_insn "*lshrdi3_cmp_rex64"
12744   [(set (reg FLAGS_REG)
12745         (compare
12746           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12747                        (match_operand:QI 2 "const_int_operand" "e"))
12748           (const_int 0)))
12749    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12750         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12751   "TARGET_64BIT
12752    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12753    && ix86_match_ccmode (insn, CCGOCmode)
12754    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12755   "shr{q}\t{%2, %0|%0, %2}"
12756   [(set_attr "type" "ishift")
12757    (set_attr "mode" "DI")])
12758
12759 (define_insn "*lshrdi3_cconly_rex64"
12760   [(set (reg FLAGS_REG)
12761         (compare
12762           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12763                        (match_operand:QI 2 "const_int_operand" "e"))
12764           (const_int 0)))
12765    (clobber (match_scratch:DI 0 "=r"))]
12766   "TARGET_64BIT
12767    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12768    && ix86_match_ccmode (insn, CCGOCmode)
12769    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12770   "shr{q}\t{%2, %0|%0, %2}"
12771   [(set_attr "type" "ishift")
12772    (set_attr "mode" "DI")])
12773
12774 (define_insn "*lshrdi3_1"
12775   [(set (match_operand:DI 0 "register_operand" "=r")
12776         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12777                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12778    (clobber (reg:CC FLAGS_REG))]
12779   "!TARGET_64BIT"
12780   "#"
12781   [(set_attr "type" "multi")])
12782
12783 ;; By default we don't ask for a scratch register, because when DImode
12784 ;; values are manipulated, registers are already at a premium.  But if
12785 ;; we have one handy, we won't turn it away.
12786 (define_peephole2
12787   [(match_scratch:SI 3 "r")
12788    (parallel [(set (match_operand:DI 0 "register_operand" "")
12789                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12790                                 (match_operand:QI 2 "nonmemory_operand" "")))
12791               (clobber (reg:CC FLAGS_REG))])
12792    (match_dup 3)]
12793   "!TARGET_64BIT && TARGET_CMOVE"
12794   [(const_int 0)]
12795   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12796
12797 (define_split
12798   [(set (match_operand:DI 0 "register_operand" "")
12799         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12800                      (match_operand:QI 2 "nonmemory_operand" "")))
12801    (clobber (reg:CC FLAGS_REG))]
12802   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12803                      ? epilogue_completed : reload_completed)"
12804   [(const_int 0)]
12805   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12806
12807 (define_expand "lshrsi3"
12808   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12809         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12810                      (match_operand:QI 2 "nonmemory_operand" "")))
12811    (clobber (reg:CC FLAGS_REG))]
12812   ""
12813   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12814
12815 (define_insn "*lshrsi3_1_one_bit"
12816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12817         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12818                      (match_operand:QI 2 "const1_operand" "")))
12819    (clobber (reg:CC FLAGS_REG))]
12820   "(TARGET_SHIFT1 || optimize_size)
12821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12822   "shr{l}\t%0"
12823   [(set_attr "type" "ishift")
12824    (set (attr "length")
12825      (if_then_else (match_operand:SI 0 "register_operand" "")
12826         (const_string "2")
12827         (const_string "*")))])
12828
12829 (define_insn "*lshrsi3_1_one_bit_zext"
12830   [(set (match_operand:DI 0 "register_operand" "=r")
12831         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12832                      (match_operand:QI 2 "const1_operand" "")))
12833    (clobber (reg:CC FLAGS_REG))]
12834   "TARGET_64BIT
12835    && (TARGET_SHIFT1 || optimize_size)
12836    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12837   "shr{l}\t%k0"
12838   [(set_attr "type" "ishift")
12839    (set_attr "length" "2")])
12840
12841 (define_insn "*lshrsi3_1"
12842   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12843         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12844                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12845    (clobber (reg:CC FLAGS_REG))]
12846   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12847   "@
12848    shr{l}\t{%2, %0|%0, %2}
12849    shr{l}\t{%b2, %0|%0, %b2}"
12850   [(set_attr "type" "ishift")
12851    (set_attr "mode" "SI")])
12852
12853 (define_insn "*lshrsi3_1_zext"
12854   [(set (match_operand:DI 0 "register_operand" "=r,r")
12855         (zero_extend:DI
12856           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12857                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12860   "@
12861    shr{l}\t{%2, %k0|%k0, %2}
12862    shr{l}\t{%b2, %k0|%k0, %b2}"
12863   [(set_attr "type" "ishift")
12864    (set_attr "mode" "SI")])
12865
12866 ;; This pattern can't accept a variable shift count, since shifts by
12867 ;; zero don't affect the flags.  We assume that shifts by constant
12868 ;; zero are optimized away.
12869 (define_insn "*lshrsi3_one_bit_cmp"
12870   [(set (reg FLAGS_REG)
12871         (compare
12872           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12873                        (match_operand:QI 2 "const1_operand" ""))
12874           (const_int 0)))
12875    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12876         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12877   "(TARGET_SHIFT1 || optimize_size)
12878    && ix86_match_ccmode (insn, CCGOCmode)
12879    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12880   "shr{l}\t%0"
12881   [(set_attr "type" "ishift")
12882    (set (attr "length")
12883      (if_then_else (match_operand:SI 0 "register_operand" "")
12884         (const_string "2")
12885         (const_string "*")))])
12886
12887 (define_insn "*lshrsi3_one_bit_cconly"
12888   [(set (reg FLAGS_REG)
12889         (compare
12890           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12891                        (match_operand:QI 2 "const1_operand" ""))
12892           (const_int 0)))
12893    (clobber (match_scratch:SI 0 "=r"))]
12894   "(TARGET_SHIFT1 || optimize_size)
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897   "shr{l}\t%0"
12898   [(set_attr "type" "ishift")
12899    (set_attr "length" "2")])
12900
12901 (define_insn "*lshrsi3_cmp_one_bit_zext"
12902   [(set (reg FLAGS_REG)
12903         (compare
12904           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12905                        (match_operand:QI 2 "const1_operand" ""))
12906           (const_int 0)))
12907    (set (match_operand:DI 0 "register_operand" "=r")
12908         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12909   "TARGET_64BIT
12910    && (TARGET_SHIFT1 || optimize_size)
12911    && ix86_match_ccmode (insn, CCGOCmode)
12912    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12913   "shr{l}\t%k0"
12914   [(set_attr "type" "ishift")
12915    (set_attr "length" "2")])
12916
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags.  We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrsi3_cmp"
12921   [(set (reg FLAGS_REG)
12922         (compare
12923           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12924                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12925           (const_int 0)))
12926    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12927         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12928   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12929    && ix86_match_ccmode (insn, CCGOCmode)
12930    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931   "shr{l}\t{%2, %0|%0, %2}"
12932   [(set_attr "type" "ishift")
12933    (set_attr "mode" "SI")])
12934
12935 (define_insn "*lshrsi3_cconly"
12936   [(set (reg FLAGS_REG)
12937       (compare
12938         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12939                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12940         (const_int 0)))
12941    (clobber (match_scratch:SI 0 "=r"))]
12942   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943    && ix86_match_ccmode (insn, CCGOCmode)
12944    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945   "shr{l}\t{%2, %0|%0, %2}"
12946   [(set_attr "type" "ishift")
12947    (set_attr "mode" "SI")])
12948
12949 (define_insn "*lshrsi3_cmp_zext"
12950   [(set (reg FLAGS_REG)
12951         (compare
12952           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12953                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12954           (const_int 0)))
12955    (set (match_operand:DI 0 "register_operand" "=r")
12956         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12957   "TARGET_64BIT
12958    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12959    && ix86_match_ccmode (insn, CCGOCmode)
12960    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12961   "shr{l}\t{%2, %k0|%k0, %2}"
12962   [(set_attr "type" "ishift")
12963    (set_attr "mode" "SI")])
12964
12965 (define_expand "lshrhi3"
12966   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12967         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12968                      (match_operand:QI 2 "nonmemory_operand" "")))
12969    (clobber (reg:CC FLAGS_REG))]
12970   "TARGET_HIMODE_MATH"
12971   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12972
12973 (define_insn "*lshrhi3_1_one_bit"
12974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12975         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12976                      (match_operand:QI 2 "const1_operand" "")))
12977    (clobber (reg:CC FLAGS_REG))]
12978   "(TARGET_SHIFT1 || optimize_size)
12979    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12980   "shr{w}\t%0"
12981   [(set_attr "type" "ishift")
12982    (set (attr "length")
12983      (if_then_else (match_operand 0 "register_operand" "")
12984         (const_string "2")
12985         (const_string "*")))])
12986
12987 (define_insn "*lshrhi3_1"
12988   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12989         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12990                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12991    (clobber (reg:CC FLAGS_REG))]
12992   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12993   "@
12994    shr{w}\t{%2, %0|%0, %2}
12995    shr{w}\t{%b2, %0|%0, %b2}"
12996   [(set_attr "type" "ishift")
12997    (set_attr "mode" "HI")])
12998
12999 ;; This pattern can't accept a variable shift count, since shifts by
13000 ;; zero don't affect the flags.  We assume that shifts by constant
13001 ;; zero are optimized away.
13002 (define_insn "*lshrhi3_one_bit_cmp"
13003   [(set (reg FLAGS_REG)
13004         (compare
13005           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13006                        (match_operand:QI 2 "const1_operand" ""))
13007           (const_int 0)))
13008    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13009         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13010   "(TARGET_SHIFT1 || optimize_size)
13011    && ix86_match_ccmode (insn, CCGOCmode)
13012    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13013   "shr{w}\t%0"
13014   [(set_attr "type" "ishift")
13015    (set (attr "length")
13016      (if_then_else (match_operand:SI 0 "register_operand" "")
13017         (const_string "2")
13018         (const_string "*")))])
13019
13020 (define_insn "*lshrhi3_one_bit_cconly"
13021   [(set (reg FLAGS_REG)
13022         (compare
13023           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13024                        (match_operand:QI 2 "const1_operand" ""))
13025           (const_int 0)))
13026    (clobber (match_scratch:HI 0 "=r"))]
13027   "(TARGET_SHIFT1 || optimize_size)
13028    && ix86_match_ccmode (insn, CCGOCmode)
13029    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13030   "shr{w}\t%0"
13031   [(set_attr "type" "ishift")
13032    (set_attr "length" "2")])
13033
13034 ;; This pattern can't accept a variable shift count, since shifts by
13035 ;; zero don't affect the flags.  We assume that shifts by constant
13036 ;; zero are optimized away.
13037 (define_insn "*lshrhi3_cmp"
13038   [(set (reg FLAGS_REG)
13039         (compare
13040           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13041                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13042           (const_int 0)))
13043    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13044         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13045   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13046    && ix86_match_ccmode (insn, CCGOCmode)
13047    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13048   "shr{w}\t{%2, %0|%0, %2}"
13049   [(set_attr "type" "ishift")
13050    (set_attr "mode" "HI")])
13051
13052 (define_insn "*lshrhi3_cconly"
13053   [(set (reg FLAGS_REG)
13054         (compare
13055           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13056                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13057           (const_int 0)))
13058    (clobber (match_scratch:HI 0 "=r"))]
13059   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13060    && ix86_match_ccmode (insn, CCGOCmode)
13061    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13062   "shr{w}\t{%2, %0|%0, %2}"
13063   [(set_attr "type" "ishift")
13064    (set_attr "mode" "HI")])
13065
13066 (define_expand "lshrqi3"
13067   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13068         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13069                      (match_operand:QI 2 "nonmemory_operand" "")))
13070    (clobber (reg:CC FLAGS_REG))]
13071   "TARGET_QIMODE_MATH"
13072   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13073
13074 (define_insn "*lshrqi3_1_one_bit"
13075   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13076         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13077                      (match_operand:QI 2 "const1_operand" "")))
13078    (clobber (reg:CC FLAGS_REG))]
13079   "(TARGET_SHIFT1 || optimize_size)
13080    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13081   "shr{b}\t%0"
13082   [(set_attr "type" "ishift")
13083    (set (attr "length")
13084      (if_then_else (match_operand 0 "register_operand" "")
13085         (const_string "2")
13086         (const_string "*")))])
13087
13088 (define_insn "*lshrqi3_1_one_bit_slp"
13089   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13090         (lshiftrt:QI (match_dup 0)
13091                      (match_operand:QI 1 "const1_operand" "")))
13092    (clobber (reg:CC FLAGS_REG))]
13093   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13094    && (TARGET_SHIFT1 || optimize_size)"
13095   "shr{b}\t%0"
13096   [(set_attr "type" "ishift1")
13097    (set (attr "length")
13098      (if_then_else (match_operand 0 "register_operand" "")
13099         (const_string "2")
13100         (const_string "*")))])
13101
13102 (define_insn "*lshrqi3_1"
13103   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13104         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13105                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13106    (clobber (reg:CC FLAGS_REG))]
13107   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13108   "@
13109    shr{b}\t{%2, %0|%0, %2}
13110    shr{b}\t{%b2, %0|%0, %b2}"
13111   [(set_attr "type" "ishift")
13112    (set_attr "mode" "QI")])
13113
13114 (define_insn "*lshrqi3_1_slp"
13115   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13116         (lshiftrt:QI (match_dup 0)
13117                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13118    (clobber (reg:CC FLAGS_REG))]
13119   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13120    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13121   "@
13122    shr{b}\t{%1, %0|%0, %1}
13123    shr{b}\t{%b1, %0|%0, %b1}"
13124   [(set_attr "type" "ishift1")
13125    (set_attr "mode" "QI")])
13126
13127 ;; This pattern can't accept a variable shift count, since shifts by
13128 ;; zero don't affect the flags.  We assume that shifts by constant
13129 ;; zero are optimized away.
13130 (define_insn "*lshrqi2_one_bit_cmp"
13131   [(set (reg FLAGS_REG)
13132         (compare
13133           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13134                        (match_operand:QI 2 "const1_operand" ""))
13135           (const_int 0)))
13136    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13137         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13138   "(TARGET_SHIFT1 || optimize_size)
13139    && ix86_match_ccmode (insn, CCGOCmode)
13140    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13141   "shr{b}\t%0"
13142   [(set_attr "type" "ishift")
13143    (set (attr "length")
13144      (if_then_else (match_operand:SI 0 "register_operand" "")
13145         (const_string "2")
13146         (const_string "*")))])
13147
13148 (define_insn "*lshrqi2_one_bit_cconly"
13149   [(set (reg FLAGS_REG)
13150         (compare
13151           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13152                        (match_operand:QI 2 "const1_operand" ""))
13153           (const_int 0)))
13154    (clobber (match_scratch:QI 0 "=q"))]
13155   "(TARGET_SHIFT1 || optimize_size)
13156    && ix86_match_ccmode (insn, CCGOCmode)
13157    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13158   "shr{b}\t%0"
13159   [(set_attr "type" "ishift")
13160    (set_attr "length" "2")])
13161
13162 ;; This pattern can't accept a variable shift count, since shifts by
13163 ;; zero don't affect the flags.  We assume that shifts by constant
13164 ;; zero are optimized away.
13165 (define_insn "*lshrqi2_cmp"
13166   [(set (reg FLAGS_REG)
13167         (compare
13168           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13169                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13170           (const_int 0)))
13171    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13172         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13173   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13174    && ix86_match_ccmode (insn, CCGOCmode)
13175    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13176   "shr{b}\t{%2, %0|%0, %2}"
13177   [(set_attr "type" "ishift")
13178    (set_attr "mode" "QI")])
13179
13180 (define_insn "*lshrqi2_cconly"
13181   [(set (reg FLAGS_REG)
13182         (compare
13183           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13184                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13185           (const_int 0)))
13186    (clobber (match_scratch:QI 0 "=q"))]
13187   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13188    && ix86_match_ccmode (insn, CCGOCmode)
13189    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13190   "shr{b}\t{%2, %0|%0, %2}"
13191   [(set_attr "type" "ishift")
13192    (set_attr "mode" "QI")])
13193 \f
13194 ;; Rotate instructions
13195
13196 (define_expand "rotldi3"
13197   [(set (match_operand:DI 0 "shiftdi_operand" "")
13198         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13199                    (match_operand:QI 2 "nonmemory_operand" "")))
13200    (clobber (reg:CC FLAGS_REG))]
13201  ""
13202 {
13203   if (TARGET_64BIT)
13204     {
13205       ix86_expand_binary_operator (ROTATE, DImode, operands);
13206       DONE;
13207     }
13208   if (!const_1_to_31_operand (operands[2], VOIDmode))
13209     FAIL;
13210   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13211   DONE;
13212 })
13213
13214 ;; Implement rotation using two double-precision shift instructions
13215 ;; and a scratch register.
13216 (define_insn_and_split "ix86_rotldi3"
13217  [(set (match_operand:DI 0 "register_operand" "=r")
13218        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13219                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13220   (clobber (reg:CC FLAGS_REG))
13221   (clobber (match_scratch:SI 3 "=&r"))]
13222  "!TARGET_64BIT"
13223  ""
13224  "&& reload_completed"
13225  [(set (match_dup 3) (match_dup 4))
13226   (parallel
13227    [(set (match_dup 4)
13228          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13229                  (lshiftrt:SI (match_dup 5)
13230                               (minus:QI (const_int 32) (match_dup 2)))))
13231     (clobber (reg:CC FLAGS_REG))])
13232   (parallel
13233    [(set (match_dup 5)
13234          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13235                  (lshiftrt:SI (match_dup 3)
13236                               (minus:QI (const_int 32) (match_dup 2)))))
13237     (clobber (reg:CC FLAGS_REG))])]
13238  "split_di (operands, 1, operands + 4, operands + 5);")
13239
13240 (define_insn "*rotlsi3_1_one_bit_rex64"
13241   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13242         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13243                    (match_operand:QI 2 "const1_operand" "")))
13244    (clobber (reg:CC FLAGS_REG))]
13245   "TARGET_64BIT
13246    && (TARGET_SHIFT1 || optimize_size)
13247    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13248   "rol{q}\t%0"
13249   [(set_attr "type" "rotate")
13250    (set (attr "length")
13251      (if_then_else (match_operand:DI 0 "register_operand" "")
13252         (const_string "2")
13253         (const_string "*")))])
13254
13255 (define_insn "*rotldi3_1_rex64"
13256   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13257         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13258                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13259    (clobber (reg:CC FLAGS_REG))]
13260   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13261   "@
13262    rol{q}\t{%2, %0|%0, %2}
13263    rol{q}\t{%b2, %0|%0, %b2}"
13264   [(set_attr "type" "rotate")
13265    (set_attr "mode" "DI")])
13266
13267 (define_expand "rotlsi3"
13268   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13269         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13270                    (match_operand:QI 2 "nonmemory_operand" "")))
13271    (clobber (reg:CC FLAGS_REG))]
13272   ""
13273   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13274
13275 (define_insn "*rotlsi3_1_one_bit"
13276   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13277         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13278                    (match_operand:QI 2 "const1_operand" "")))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "(TARGET_SHIFT1 || optimize_size)
13281    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13282   "rol{l}\t%0"
13283   [(set_attr "type" "rotate")
13284    (set (attr "length")
13285      (if_then_else (match_operand:SI 0 "register_operand" "")
13286         (const_string "2")
13287         (const_string "*")))])
13288
13289 (define_insn "*rotlsi3_1_one_bit_zext"
13290   [(set (match_operand:DI 0 "register_operand" "=r")
13291         (zero_extend:DI
13292           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13293                      (match_operand:QI 2 "const1_operand" ""))))
13294    (clobber (reg:CC FLAGS_REG))]
13295   "TARGET_64BIT
13296    && (TARGET_SHIFT1 || optimize_size)
13297    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13298   "rol{l}\t%k0"
13299   [(set_attr "type" "rotate")
13300    (set_attr "length" "2")])
13301
13302 (define_insn "*rotlsi3_1"
13303   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13304         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13305                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13306    (clobber (reg:CC FLAGS_REG))]
13307   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13308   "@
13309    rol{l}\t{%2, %0|%0, %2}
13310    rol{l}\t{%b2, %0|%0, %b2}"
13311   [(set_attr "type" "rotate")
13312    (set_attr "mode" "SI")])
13313
13314 (define_insn "*rotlsi3_1_zext"
13315   [(set (match_operand:DI 0 "register_operand" "=r,r")
13316         (zero_extend:DI
13317           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13318                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13319    (clobber (reg:CC FLAGS_REG))]
13320   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13321   "@
13322    rol{l}\t{%2, %k0|%k0, %2}
13323    rol{l}\t{%b2, %k0|%k0, %b2}"
13324   [(set_attr "type" "rotate")
13325    (set_attr "mode" "SI")])
13326
13327 (define_expand "rotlhi3"
13328   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13329         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13330                    (match_operand:QI 2 "nonmemory_operand" "")))
13331    (clobber (reg:CC FLAGS_REG))]
13332   "TARGET_HIMODE_MATH"
13333   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13334
13335 (define_insn "*rotlhi3_1_one_bit"
13336   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13337         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13338                    (match_operand:QI 2 "const1_operand" "")))
13339    (clobber (reg:CC FLAGS_REG))]
13340   "(TARGET_SHIFT1 || optimize_size)
13341    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13342   "rol{w}\t%0"
13343   [(set_attr "type" "rotate")
13344    (set (attr "length")
13345      (if_then_else (match_operand 0 "register_operand" "")
13346         (const_string "2")
13347         (const_string "*")))])
13348
13349 (define_insn "*rotlhi3_1"
13350   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13351         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13352                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13353    (clobber (reg:CC FLAGS_REG))]
13354   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13355   "@
13356    rol{w}\t{%2, %0|%0, %2}
13357    rol{w}\t{%b2, %0|%0, %b2}"
13358   [(set_attr "type" "rotate")
13359    (set_attr "mode" "HI")])
13360
13361 (define_split
13362  [(set (match_operand:HI 0 "register_operand" "")
13363        (rotate:HI (match_dup 0) (const_int 8)))
13364   (clobber (reg:CC FLAGS_REG))]
13365  "reload_completed"
13366  [(parallel [(set (strict_low_part (match_dup 0))
13367                   (bswap:HI (match_dup 0)))
13368              (clobber (reg:CC FLAGS_REG))])]
13369  "")
13370
13371 (define_expand "rotlqi3"
13372   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13373         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13374                    (match_operand:QI 2 "nonmemory_operand" "")))
13375    (clobber (reg:CC FLAGS_REG))]
13376   "TARGET_QIMODE_MATH"
13377   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13378
13379 (define_insn "*rotlqi3_1_one_bit_slp"
13380   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13381         (rotate:QI (match_dup 0)
13382                    (match_operand:QI 1 "const1_operand" "")))
13383    (clobber (reg:CC FLAGS_REG))]
13384   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13385    && (TARGET_SHIFT1 || optimize_size)"
13386   "rol{b}\t%0"
13387   [(set_attr "type" "rotate1")
13388    (set (attr "length")
13389      (if_then_else (match_operand 0 "register_operand" "")
13390         (const_string "2")
13391         (const_string "*")))])
13392
13393 (define_insn "*rotlqi3_1_one_bit"
13394   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13395         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13396                    (match_operand:QI 2 "const1_operand" "")))
13397    (clobber (reg:CC FLAGS_REG))]
13398   "(TARGET_SHIFT1 || optimize_size)
13399    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13400   "rol{b}\t%0"
13401   [(set_attr "type" "rotate")
13402    (set (attr "length")
13403      (if_then_else (match_operand 0 "register_operand" "")
13404         (const_string "2")
13405         (const_string "*")))])
13406
13407 (define_insn "*rotlqi3_1_slp"
13408   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13409         (rotate:QI (match_dup 0)
13410                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13411    (clobber (reg:CC FLAGS_REG))]
13412   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13413    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13414   "@
13415    rol{b}\t{%1, %0|%0, %1}
13416    rol{b}\t{%b1, %0|%0, %b1}"
13417   [(set_attr "type" "rotate1")
13418    (set_attr "mode" "QI")])
13419
13420 (define_insn "*rotlqi3_1"
13421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13422         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13423                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13424    (clobber (reg:CC FLAGS_REG))]
13425   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13426   "@
13427    rol{b}\t{%2, %0|%0, %2}
13428    rol{b}\t{%b2, %0|%0, %b2}"
13429   [(set_attr "type" "rotate")
13430    (set_attr "mode" "QI")])
13431
13432 (define_expand "rotrdi3"
13433   [(set (match_operand:DI 0 "shiftdi_operand" "")
13434         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13435                    (match_operand:QI 2 "nonmemory_operand" "")))
13436    (clobber (reg:CC FLAGS_REG))]
13437  ""
13438 {
13439   if (TARGET_64BIT)
13440     {
13441       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13442       DONE;
13443     }
13444   if (!const_1_to_31_operand (operands[2], VOIDmode))
13445     FAIL;
13446   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13447   DONE;
13448 })
13449
13450 ;; Implement rotation using two double-precision shift instructions
13451 ;; and a scratch register.
13452 (define_insn_and_split "ix86_rotrdi3"
13453  [(set (match_operand:DI 0 "register_operand" "=r")
13454        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13455                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13456   (clobber (reg:CC FLAGS_REG))
13457   (clobber (match_scratch:SI 3 "=&r"))]
13458  "!TARGET_64BIT"
13459  ""
13460  "&& reload_completed"
13461  [(set (match_dup 3) (match_dup 4))
13462   (parallel
13463    [(set (match_dup 4)
13464          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13465                  (ashift:SI (match_dup 5)
13466                             (minus:QI (const_int 32) (match_dup 2)))))
13467     (clobber (reg:CC FLAGS_REG))])
13468   (parallel
13469    [(set (match_dup 5)
13470          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13471                  (ashift:SI (match_dup 3)
13472                             (minus:QI (const_int 32) (match_dup 2)))))
13473     (clobber (reg:CC FLAGS_REG))])]
13474  "split_di (operands, 1, operands + 4, operands + 5);")
13475
13476 (define_insn "*rotrdi3_1_one_bit_rex64"
13477   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13478         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13479                      (match_operand:QI 2 "const1_operand" "")))
13480    (clobber (reg:CC FLAGS_REG))]
13481   "TARGET_64BIT
13482    && (TARGET_SHIFT1 || optimize_size)
13483    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13484   "ror{q}\t%0"
13485   [(set_attr "type" "rotate")
13486    (set (attr "length")
13487      (if_then_else (match_operand:DI 0 "register_operand" "")
13488         (const_string "2")
13489         (const_string "*")))])
13490
13491 (define_insn "*rotrdi3_1_rex64"
13492   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13493         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13494                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13495    (clobber (reg:CC FLAGS_REG))]
13496   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13497   "@
13498    ror{q}\t{%2, %0|%0, %2}
13499    ror{q}\t{%b2, %0|%0, %b2}"
13500   [(set_attr "type" "rotate")
13501    (set_attr "mode" "DI")])
13502
13503 (define_expand "rotrsi3"
13504   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13505         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13506                      (match_operand:QI 2 "nonmemory_operand" "")))
13507    (clobber (reg:CC FLAGS_REG))]
13508   ""
13509   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13510
13511 (define_insn "*rotrsi3_1_one_bit"
13512   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13513         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13514                      (match_operand:QI 2 "const1_operand" "")))
13515    (clobber (reg:CC FLAGS_REG))]
13516   "(TARGET_SHIFT1 || optimize_size)
13517    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13518   "ror{l}\t%0"
13519   [(set_attr "type" "rotate")
13520    (set (attr "length")
13521      (if_then_else (match_operand:SI 0 "register_operand" "")
13522         (const_string "2")
13523         (const_string "*")))])
13524
13525 (define_insn "*rotrsi3_1_one_bit_zext"
13526   [(set (match_operand:DI 0 "register_operand" "=r")
13527         (zero_extend:DI
13528           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13529                        (match_operand:QI 2 "const1_operand" ""))))
13530    (clobber (reg:CC FLAGS_REG))]
13531   "TARGET_64BIT
13532    && (TARGET_SHIFT1 || optimize_size)
13533    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13534   "ror{l}\t%k0"
13535   [(set_attr "type" "rotate")
13536    (set (attr "length")
13537      (if_then_else (match_operand:SI 0 "register_operand" "")
13538         (const_string "2")
13539         (const_string "*")))])
13540
13541 (define_insn "*rotrsi3_1"
13542   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13543         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13544                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13545    (clobber (reg:CC FLAGS_REG))]
13546   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13547   "@
13548    ror{l}\t{%2, %0|%0, %2}
13549    ror{l}\t{%b2, %0|%0, %b2}"
13550   [(set_attr "type" "rotate")
13551    (set_attr "mode" "SI")])
13552
13553 (define_insn "*rotrsi3_1_zext"
13554   [(set (match_operand:DI 0 "register_operand" "=r,r")
13555         (zero_extend:DI
13556           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13557                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13558    (clobber (reg:CC FLAGS_REG))]
13559   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13560   "@
13561    ror{l}\t{%2, %k0|%k0, %2}
13562    ror{l}\t{%b2, %k0|%k0, %b2}"
13563   [(set_attr "type" "rotate")
13564    (set_attr "mode" "SI")])
13565
13566 (define_expand "rotrhi3"
13567   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13568         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13569                      (match_operand:QI 2 "nonmemory_operand" "")))
13570    (clobber (reg:CC FLAGS_REG))]
13571   "TARGET_HIMODE_MATH"
13572   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13573
13574 (define_insn "*rotrhi3_one_bit"
13575   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13576         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13577                      (match_operand:QI 2 "const1_operand" "")))
13578    (clobber (reg:CC FLAGS_REG))]
13579   "(TARGET_SHIFT1 || optimize_size)
13580    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13581   "ror{w}\t%0"
13582   [(set_attr "type" "rotate")
13583    (set (attr "length")
13584      (if_then_else (match_operand 0 "register_operand" "")
13585         (const_string "2")
13586         (const_string "*")))])
13587
13588 (define_insn "*rotrhi3_1"
13589   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13590         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13591                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13592    (clobber (reg:CC FLAGS_REG))]
13593   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13594   "@
13595    ror{w}\t{%2, %0|%0, %2}
13596    ror{w}\t{%b2, %0|%0, %b2}"
13597   [(set_attr "type" "rotate")
13598    (set_attr "mode" "HI")])
13599
13600 (define_split
13601  [(set (match_operand:HI 0 "register_operand" "")
13602        (rotatert:HI (match_dup 0) (const_int 8)))
13603   (clobber (reg:CC FLAGS_REG))]
13604  "reload_completed"
13605  [(parallel [(set (strict_low_part (match_dup 0))
13606                   (bswap:HI (match_dup 0)))
13607              (clobber (reg:CC FLAGS_REG))])]
13608  "")
13609
13610 (define_expand "rotrqi3"
13611   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13612         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13613                      (match_operand:QI 2 "nonmemory_operand" "")))
13614    (clobber (reg:CC FLAGS_REG))]
13615   "TARGET_QIMODE_MATH"
13616   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13617
13618 (define_insn "*rotrqi3_1_one_bit"
13619   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13620         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13621                      (match_operand:QI 2 "const1_operand" "")))
13622    (clobber (reg:CC FLAGS_REG))]
13623   "(TARGET_SHIFT1 || optimize_size)
13624    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13625   "ror{b}\t%0"
13626   [(set_attr "type" "rotate")
13627    (set (attr "length")
13628      (if_then_else (match_operand 0 "register_operand" "")
13629         (const_string "2")
13630         (const_string "*")))])
13631
13632 (define_insn "*rotrqi3_1_one_bit_slp"
13633   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13634         (rotatert:QI (match_dup 0)
13635                      (match_operand:QI 1 "const1_operand" "")))
13636    (clobber (reg:CC FLAGS_REG))]
13637   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13638    && (TARGET_SHIFT1 || optimize_size)"
13639   "ror{b}\t%0"
13640   [(set_attr "type" "rotate1")
13641    (set (attr "length")
13642      (if_then_else (match_operand 0 "register_operand" "")
13643         (const_string "2")
13644         (const_string "*")))])
13645
13646 (define_insn "*rotrqi3_1"
13647   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13648         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13649                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13650    (clobber (reg:CC FLAGS_REG))]
13651   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13652   "@
13653    ror{b}\t{%2, %0|%0, %2}
13654    ror{b}\t{%b2, %0|%0, %b2}"
13655   [(set_attr "type" "rotate")
13656    (set_attr "mode" "QI")])
13657
13658 (define_insn "*rotrqi3_1_slp"
13659   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13660         (rotatert:QI (match_dup 0)
13661                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13662    (clobber (reg:CC FLAGS_REG))]
13663   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13664    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13665   "@
13666    ror{b}\t{%1, %0|%0, %1}
13667    ror{b}\t{%b1, %0|%0, %b1}"
13668   [(set_attr "type" "rotate1")
13669    (set_attr "mode" "QI")])
13670 \f
13671 ;; Bit set / bit test instructions
13672
13673 (define_expand "extv"
13674   [(set (match_operand:SI 0 "register_operand" "")
13675         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13676                          (match_operand:SI 2 "const8_operand" "")
13677                          (match_operand:SI 3 "const8_operand" "")))]
13678   ""
13679 {
13680   /* Handle extractions from %ah et al.  */
13681   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13682     FAIL;
13683
13684   /* From mips.md: extract_bit_field doesn't verify that our source
13685      matches the predicate, so check it again here.  */
13686   if (! ext_register_operand (operands[1], VOIDmode))
13687     FAIL;
13688 })
13689
13690 (define_expand "extzv"
13691   [(set (match_operand:SI 0 "register_operand" "")
13692         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13693                          (match_operand:SI 2 "const8_operand" "")
13694                          (match_operand:SI 3 "const8_operand" "")))]
13695   ""
13696 {
13697   /* Handle extractions from %ah et al.  */
13698   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13699     FAIL;
13700
13701   /* From mips.md: extract_bit_field doesn't verify that our source
13702      matches the predicate, so check it again here.  */
13703   if (! ext_register_operand (operands[1], VOIDmode))
13704     FAIL;
13705 })
13706
13707 (define_expand "insv"
13708   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13709                       (match_operand 1 "const8_operand" "")
13710                       (match_operand 2 "const8_operand" ""))
13711         (match_operand 3 "register_operand" ""))]
13712   ""
13713 {
13714   /* Handle insertions to %ah et al.  */
13715   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13716     FAIL;
13717
13718   /* From mips.md: insert_bit_field doesn't verify that our source
13719      matches the predicate, so check it again here.  */
13720   if (! ext_register_operand (operands[0], VOIDmode))
13721     FAIL;
13722
13723   if (TARGET_64BIT)
13724     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13725   else
13726     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13727
13728   DONE;
13729 })
13730
13731 ;; %%% bts, btr, btc, bt.
13732 ;; In general these instructions are *slow* when applied to memory,
13733 ;; since they enforce atomic operation.  When applied to registers,
13734 ;; it depends on the cpu implementation.  They're never faster than
13735 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13736 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13737 ;; within the instruction itself, so operating on bits in the high
13738 ;; 32-bits of a register becomes easier.
13739 ;;
13740 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13741 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13742 ;; negdf respectively, so they can never be disabled entirely.
13743
13744 (define_insn "*btsq"
13745   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13746                          (const_int 1)
13747                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13748         (const_int 1))
13749    (clobber (reg:CC FLAGS_REG))]
13750   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13751   "bts{q} %1,%0"
13752   [(set_attr "type" "alu1")])
13753
13754 (define_insn "*btrq"
13755   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13756                          (const_int 1)
13757                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13758         (const_int 0))
13759    (clobber (reg:CC FLAGS_REG))]
13760   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13761   "btr{q} %1,%0"
13762   [(set_attr "type" "alu1")])
13763
13764 (define_insn "*btcq"
13765   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13766                          (const_int 1)
13767                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13768         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13769    (clobber (reg:CC FLAGS_REG))]
13770   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13771   "btc{q} %1,%0"
13772   [(set_attr "type" "alu1")])
13773
13774 ;; Allow Nocona to avoid these instructions if a register is available.
13775
13776 (define_peephole2
13777   [(match_scratch:DI 2 "r")
13778    (parallel [(set (zero_extract:DI
13779                      (match_operand:DI 0 "register_operand" "")
13780                      (const_int 1)
13781                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13782                    (const_int 1))
13783               (clobber (reg:CC FLAGS_REG))])]
13784   "TARGET_64BIT && !TARGET_USE_BT"
13785   [(const_int 0)]
13786 {
13787   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13788   rtx op1;
13789
13790   if (HOST_BITS_PER_WIDE_INT >= 64)
13791     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13792   else if (i < HOST_BITS_PER_WIDE_INT)
13793     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13794   else
13795     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13796
13797   op1 = immed_double_const (lo, hi, DImode);
13798   if (i >= 31)
13799     {
13800       emit_move_insn (operands[2], op1);
13801       op1 = operands[2];
13802     }
13803
13804   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13805   DONE;
13806 })
13807
13808 (define_peephole2
13809   [(match_scratch:DI 2 "r")
13810    (parallel [(set (zero_extract:DI
13811                      (match_operand:DI 0 "register_operand" "")
13812                      (const_int 1)
13813                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13814                    (const_int 0))
13815               (clobber (reg:CC FLAGS_REG))])]
13816   "TARGET_64BIT && !TARGET_USE_BT"
13817   [(const_int 0)]
13818 {
13819   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13820   rtx op1;
13821
13822   if (HOST_BITS_PER_WIDE_INT >= 64)
13823     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13824   else if (i < HOST_BITS_PER_WIDE_INT)
13825     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13826   else
13827     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13828
13829   op1 = immed_double_const (~lo, ~hi, DImode);
13830   if (i >= 32)
13831     {
13832       emit_move_insn (operands[2], op1);
13833       op1 = operands[2];
13834     }
13835
13836   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13837   DONE;
13838 })
13839
13840 (define_peephole2
13841   [(match_scratch:DI 2 "r")
13842    (parallel [(set (zero_extract:DI
13843                      (match_operand:DI 0 "register_operand" "")
13844                      (const_int 1)
13845                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13846               (not:DI (zero_extract:DI
13847                         (match_dup 0) (const_int 1) (match_dup 1))))
13848               (clobber (reg:CC FLAGS_REG))])]
13849   "TARGET_64BIT && !TARGET_USE_BT"
13850   [(const_int 0)]
13851 {
13852   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13853   rtx op1;
13854
13855   if (HOST_BITS_PER_WIDE_INT >= 64)
13856     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13857   else if (i < HOST_BITS_PER_WIDE_INT)
13858     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13859   else
13860     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13861
13862   op1 = immed_double_const (lo, hi, DImode);
13863   if (i >= 31)
13864     {
13865       emit_move_insn (operands[2], op1);
13866       op1 = operands[2];
13867     }
13868
13869   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13870   DONE;
13871 })
13872 \f
13873 ;; Store-flag instructions.
13874
13875 ;; For all sCOND expanders, also expand the compare or test insn that
13876 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13877
13878 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13879 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13880 ;; way, which can later delete the movzx if only QImode is needed.
13881
13882 (define_expand "seq"
13883   [(set (match_operand:QI 0 "register_operand" "")
13884         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13885   ""
13886   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13887
13888 (define_expand "sne"
13889   [(set (match_operand:QI 0 "register_operand" "")
13890         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13891   ""
13892   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13893
13894 (define_expand "sgt"
13895   [(set (match_operand:QI 0 "register_operand" "")
13896         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13897   ""
13898   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13899
13900 (define_expand "sgtu"
13901   [(set (match_operand:QI 0 "register_operand" "")
13902         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13903   ""
13904   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13905
13906 (define_expand "slt"
13907   [(set (match_operand:QI 0 "register_operand" "")
13908         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13909   ""
13910   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13911
13912 (define_expand "sltu"
13913   [(set (match_operand:QI 0 "register_operand" "")
13914         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13915   ""
13916   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13917
13918 (define_expand "sge"
13919   [(set (match_operand:QI 0 "register_operand" "")
13920         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13921   ""
13922   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13923
13924 (define_expand "sgeu"
13925   [(set (match_operand:QI 0 "register_operand" "")
13926         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13927   ""
13928   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13929
13930 (define_expand "sle"
13931   [(set (match_operand:QI 0 "register_operand" "")
13932         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13933   ""
13934   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13935
13936 (define_expand "sleu"
13937   [(set (match_operand:QI 0 "register_operand" "")
13938         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13939   ""
13940   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13941
13942 (define_expand "sunordered"
13943   [(set (match_operand:QI 0 "register_operand" "")
13944         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13945   "TARGET_80387 || TARGET_SSE"
13946   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13947
13948 (define_expand "sordered"
13949   [(set (match_operand:QI 0 "register_operand" "")
13950         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13951   "TARGET_80387"
13952   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13953
13954 (define_expand "suneq"
13955   [(set (match_operand:QI 0 "register_operand" "")
13956         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13957   "TARGET_80387 || TARGET_SSE"
13958   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13959
13960 (define_expand "sunge"
13961   [(set (match_operand:QI 0 "register_operand" "")
13962         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13963   "TARGET_80387 || TARGET_SSE"
13964   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13965
13966 (define_expand "sungt"
13967   [(set (match_operand:QI 0 "register_operand" "")
13968         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13969   "TARGET_80387 || TARGET_SSE"
13970   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13971
13972 (define_expand "sunle"
13973   [(set (match_operand:QI 0 "register_operand" "")
13974         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13975   "TARGET_80387 || TARGET_SSE"
13976   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13977
13978 (define_expand "sunlt"
13979   [(set (match_operand:QI 0 "register_operand" "")
13980         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13981   "TARGET_80387 || TARGET_SSE"
13982   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13983
13984 (define_expand "sltgt"
13985   [(set (match_operand:QI 0 "register_operand" "")
13986         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13987   "TARGET_80387 || TARGET_SSE"
13988   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13989
13990 (define_insn "*setcc_1"
13991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13992         (match_operator:QI 1 "ix86_comparison_operator"
13993           [(reg FLAGS_REG) (const_int 0)]))]
13994   ""
13995   "set%C1\t%0"
13996   [(set_attr "type" "setcc")
13997    (set_attr "mode" "QI")])
13998
13999 (define_insn "*setcc_2"
14000   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14001         (match_operator:QI 1 "ix86_comparison_operator"
14002           [(reg FLAGS_REG) (const_int 0)]))]
14003   ""
14004   "set%C1\t%0"
14005   [(set_attr "type" "setcc")
14006    (set_attr "mode" "QI")])
14007
14008 ;; In general it is not safe to assume too much about CCmode registers,
14009 ;; so simplify-rtx stops when it sees a second one.  Under certain
14010 ;; conditions this is safe on x86, so help combine not create
14011 ;;
14012 ;;      seta    %al
14013 ;;      testb   %al, %al
14014 ;;      sete    %al
14015
14016 (define_split
14017   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14018         (ne:QI (match_operator 1 "ix86_comparison_operator"
14019                  [(reg FLAGS_REG) (const_int 0)])
14020             (const_int 0)))]
14021   ""
14022   [(set (match_dup 0) (match_dup 1))]
14023 {
14024   PUT_MODE (operands[1], QImode);
14025 })
14026
14027 (define_split
14028   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14029         (ne:QI (match_operator 1 "ix86_comparison_operator"
14030                  [(reg FLAGS_REG) (const_int 0)])
14031             (const_int 0)))]
14032   ""
14033   [(set (match_dup 0) (match_dup 1))]
14034 {
14035   PUT_MODE (operands[1], QImode);
14036 })
14037
14038 (define_split
14039   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14040         (eq:QI (match_operator 1 "ix86_comparison_operator"
14041                  [(reg FLAGS_REG) (const_int 0)])
14042             (const_int 0)))]
14043   ""
14044   [(set (match_dup 0) (match_dup 1))]
14045 {
14046   rtx new_op1 = copy_rtx (operands[1]);
14047   operands[1] = new_op1;
14048   PUT_MODE (new_op1, QImode);
14049   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14050                                              GET_MODE (XEXP (new_op1, 0))));
14051
14052   /* Make sure that (a) the CCmode we have for the flags is strong
14053      enough for the reversed compare or (b) we have a valid FP compare.  */
14054   if (! ix86_comparison_operator (new_op1, VOIDmode))
14055     FAIL;
14056 })
14057
14058 (define_split
14059   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14060         (eq:QI (match_operator 1 "ix86_comparison_operator"
14061                  [(reg FLAGS_REG) (const_int 0)])
14062             (const_int 0)))]
14063   ""
14064   [(set (match_dup 0) (match_dup 1))]
14065 {
14066   rtx new_op1 = copy_rtx (operands[1]);
14067   operands[1] = new_op1;
14068   PUT_MODE (new_op1, QImode);
14069   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14070                                              GET_MODE (XEXP (new_op1, 0))));
14071
14072   /* Make sure that (a) the CCmode we have for the flags is strong
14073      enough for the reversed compare or (b) we have a valid FP compare.  */
14074   if (! ix86_comparison_operator (new_op1, VOIDmode))
14075     FAIL;
14076 })
14077
14078 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14079 ;; subsequent logical operations are used to imitate conditional moves.
14080 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14081 ;; it directly.
14082
14083 (define_insn "*sse_setccsf"
14084   [(set (match_operand:SF 0 "register_operand" "=x")
14085         (match_operator:SF 1 "sse_comparison_operator"
14086           [(match_operand:SF 2 "register_operand" "0")
14087            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
14088   "TARGET_SSE && !TARGET_SSE5"
14089   "cmp%D1ss\t{%3, %0|%0, %3}"
14090   [(set_attr "type" "ssecmp")
14091    (set_attr "mode" "SF")])
14092
14093 (define_insn "*sse_setccdf"
14094   [(set (match_operand:DF 0 "register_operand" "=x")
14095         (match_operator:DF 1 "sse_comparison_operator"
14096           [(match_operand:DF 2 "register_operand" "0")
14097            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
14098   "TARGET_SSE2 && !TARGET_SSE5"
14099   "cmp%D1sd\t{%3, %0|%0, %3}"
14100   [(set_attr "type" "ssecmp")
14101    (set_attr "mode" "DF")])
14102
14103 (define_insn "*sse5_setcc<mode>"
14104   [(set (match_operand:MODEF 0 "register_operand" "=x")
14105         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14106           [(match_operand:MODEF 2 "register_operand" "x")
14107            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14108   "TARGET_SSE5"
14109   "com%Y1ss\t{%3, %2, %0|%0, %2, %3}"
14110   [(set_attr "type" "sse4arg")
14111    (set_attr "mode" "<MODE>")])
14112
14113 \f
14114 ;; Basic conditional jump instructions.
14115 ;; We ignore the overflow flag for signed branch instructions.
14116
14117 ;; For all bCOND expanders, also expand the compare or test insn that
14118 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14119
14120 (define_expand "beq"
14121   [(set (pc)
14122         (if_then_else (match_dup 1)
14123                       (label_ref (match_operand 0 "" ""))
14124                       (pc)))]
14125   ""
14126   "ix86_expand_branch (EQ, operands[0]); DONE;")
14127
14128 (define_expand "bne"
14129   [(set (pc)
14130         (if_then_else (match_dup 1)
14131                       (label_ref (match_operand 0 "" ""))
14132                       (pc)))]
14133   ""
14134   "ix86_expand_branch (NE, operands[0]); DONE;")
14135
14136 (define_expand "bgt"
14137   [(set (pc)
14138         (if_then_else (match_dup 1)
14139                       (label_ref (match_operand 0 "" ""))
14140                       (pc)))]
14141   ""
14142   "ix86_expand_branch (GT, operands[0]); DONE;")
14143
14144 (define_expand "bgtu"
14145   [(set (pc)
14146         (if_then_else (match_dup 1)
14147                       (label_ref (match_operand 0 "" ""))
14148                       (pc)))]
14149   ""
14150   "ix86_expand_branch (GTU, operands[0]); DONE;")
14151
14152 (define_expand "blt"
14153   [(set (pc)
14154         (if_then_else (match_dup 1)
14155                       (label_ref (match_operand 0 "" ""))
14156                       (pc)))]
14157   ""
14158   "ix86_expand_branch (LT, operands[0]); DONE;")
14159
14160 (define_expand "bltu"
14161   [(set (pc)
14162         (if_then_else (match_dup 1)
14163                       (label_ref (match_operand 0 "" ""))
14164                       (pc)))]
14165   ""
14166   "ix86_expand_branch (LTU, operands[0]); DONE;")
14167
14168 (define_expand "bge"
14169   [(set (pc)
14170         (if_then_else (match_dup 1)
14171                       (label_ref (match_operand 0 "" ""))
14172                       (pc)))]
14173   ""
14174   "ix86_expand_branch (GE, operands[0]); DONE;")
14175
14176 (define_expand "bgeu"
14177   [(set (pc)
14178         (if_then_else (match_dup 1)
14179                       (label_ref (match_operand 0 "" ""))
14180                       (pc)))]
14181   ""
14182   "ix86_expand_branch (GEU, operands[0]); DONE;")
14183
14184 (define_expand "ble"
14185   [(set (pc)
14186         (if_then_else (match_dup 1)
14187                       (label_ref (match_operand 0 "" ""))
14188                       (pc)))]
14189   ""
14190   "ix86_expand_branch (LE, operands[0]); DONE;")
14191
14192 (define_expand "bleu"
14193   [(set (pc)
14194         (if_then_else (match_dup 1)
14195                       (label_ref (match_operand 0 "" ""))
14196                       (pc)))]
14197   ""
14198   "ix86_expand_branch (LEU, operands[0]); DONE;")
14199
14200 (define_expand "bunordered"
14201   [(set (pc)
14202         (if_then_else (match_dup 1)
14203                       (label_ref (match_operand 0 "" ""))
14204                       (pc)))]
14205   "TARGET_80387 || TARGET_SSE_MATH"
14206   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14207
14208 (define_expand "bordered"
14209   [(set (pc)
14210         (if_then_else (match_dup 1)
14211                       (label_ref (match_operand 0 "" ""))
14212                       (pc)))]
14213   "TARGET_80387 || TARGET_SSE_MATH"
14214   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14215
14216 (define_expand "buneq"
14217   [(set (pc)
14218         (if_then_else (match_dup 1)
14219                       (label_ref (match_operand 0 "" ""))
14220                       (pc)))]
14221   "TARGET_80387 || TARGET_SSE_MATH"
14222   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14223
14224 (define_expand "bunge"
14225   [(set (pc)
14226         (if_then_else (match_dup 1)
14227                       (label_ref (match_operand 0 "" ""))
14228                       (pc)))]
14229   "TARGET_80387 || TARGET_SSE_MATH"
14230   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14231
14232 (define_expand "bungt"
14233   [(set (pc)
14234         (if_then_else (match_dup 1)
14235                       (label_ref (match_operand 0 "" ""))
14236                       (pc)))]
14237   "TARGET_80387 || TARGET_SSE_MATH"
14238   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14239
14240 (define_expand "bunle"
14241   [(set (pc)
14242         (if_then_else (match_dup 1)
14243                       (label_ref (match_operand 0 "" ""))
14244                       (pc)))]
14245   "TARGET_80387 || TARGET_SSE_MATH"
14246   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14247
14248 (define_expand "bunlt"
14249   [(set (pc)
14250         (if_then_else (match_dup 1)
14251                       (label_ref (match_operand 0 "" ""))
14252                       (pc)))]
14253   "TARGET_80387 || TARGET_SSE_MATH"
14254   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14255
14256 (define_expand "bltgt"
14257   [(set (pc)
14258         (if_then_else (match_dup 1)
14259                       (label_ref (match_operand 0 "" ""))
14260                       (pc)))]
14261   "TARGET_80387 || TARGET_SSE_MATH"
14262   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14263
14264 (define_insn "*jcc_1"
14265   [(set (pc)
14266         (if_then_else (match_operator 1 "ix86_comparison_operator"
14267                                       [(reg FLAGS_REG) (const_int 0)])
14268                       (label_ref (match_operand 0 "" ""))
14269                       (pc)))]
14270   ""
14271   "%+j%C1\t%l0"
14272   [(set_attr "type" "ibr")
14273    (set_attr "modrm" "0")
14274    (set (attr "length")
14275            (if_then_else (and (ge (minus (match_dup 0) (pc))
14276                                   (const_int -126))
14277                               (lt (minus (match_dup 0) (pc))
14278                                   (const_int 128)))
14279              (const_int 2)
14280              (const_int 6)))])
14281
14282 (define_insn "*jcc_2"
14283   [(set (pc)
14284         (if_then_else (match_operator 1 "ix86_comparison_operator"
14285                                       [(reg FLAGS_REG) (const_int 0)])
14286                       (pc)
14287                       (label_ref (match_operand 0 "" ""))))]
14288   ""
14289   "%+j%c1\t%l0"
14290   [(set_attr "type" "ibr")
14291    (set_attr "modrm" "0")
14292    (set (attr "length")
14293            (if_then_else (and (ge (minus (match_dup 0) (pc))
14294                                   (const_int -126))
14295                               (lt (minus (match_dup 0) (pc))
14296                                   (const_int 128)))
14297              (const_int 2)
14298              (const_int 6)))])
14299
14300 ;; In general it is not safe to assume too much about CCmode registers,
14301 ;; so simplify-rtx stops when it sees a second one.  Under certain
14302 ;; conditions this is safe on x86, so help combine not create
14303 ;;
14304 ;;      seta    %al
14305 ;;      testb   %al, %al
14306 ;;      je      Lfoo
14307
14308 (define_split
14309   [(set (pc)
14310         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14311                                       [(reg FLAGS_REG) (const_int 0)])
14312                           (const_int 0))
14313                       (label_ref (match_operand 1 "" ""))
14314                       (pc)))]
14315   ""
14316   [(set (pc)
14317         (if_then_else (match_dup 0)
14318                       (label_ref (match_dup 1))
14319                       (pc)))]
14320 {
14321   PUT_MODE (operands[0], VOIDmode);
14322 })
14323
14324 (define_split
14325   [(set (pc)
14326         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14327                                       [(reg FLAGS_REG) (const_int 0)])
14328                           (const_int 0))
14329                       (label_ref (match_operand 1 "" ""))
14330                       (pc)))]
14331   ""
14332   [(set (pc)
14333         (if_then_else (match_dup 0)
14334                       (label_ref (match_dup 1))
14335                       (pc)))]
14336 {
14337   rtx new_op0 = copy_rtx (operands[0]);
14338   operands[0] = new_op0;
14339   PUT_MODE (new_op0, VOIDmode);
14340   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14341                                              GET_MODE (XEXP (new_op0, 0))));
14342
14343   /* Make sure that (a) the CCmode we have for the flags is strong
14344      enough for the reversed compare or (b) we have a valid FP compare.  */
14345   if (! ix86_comparison_operator (new_op0, VOIDmode))
14346     FAIL;
14347 })
14348
14349 ;; Define combination compare-and-branch fp compare instructions to use
14350 ;; during early optimization.  Splitting the operation apart early makes
14351 ;; for bad code when we want to reverse the operation.
14352
14353 (define_insn "*fp_jcc_1_mixed"
14354   [(set (pc)
14355         (if_then_else (match_operator 0 "comparison_operator"
14356                         [(match_operand 1 "register_operand" "f,x")
14357                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14358           (label_ref (match_operand 3 "" ""))
14359           (pc)))
14360    (clobber (reg:CCFP FPSR_REG))
14361    (clobber (reg:CCFP FLAGS_REG))]
14362   "TARGET_MIX_SSE_I387
14363    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14364    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14365    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14366   "#")
14367
14368 (define_insn "*fp_jcc_1_sse"
14369   [(set (pc)
14370         (if_then_else (match_operator 0 "comparison_operator"
14371                         [(match_operand 1 "register_operand" "x")
14372                          (match_operand 2 "nonimmediate_operand" "xm")])
14373           (label_ref (match_operand 3 "" ""))
14374           (pc)))
14375    (clobber (reg:CCFP FPSR_REG))
14376    (clobber (reg:CCFP FLAGS_REG))]
14377   "TARGET_SSE_MATH
14378    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14379    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14380    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14381   "#")
14382
14383 (define_insn "*fp_jcc_1_387"
14384   [(set (pc)
14385         (if_then_else (match_operator 0 "comparison_operator"
14386                         [(match_operand 1 "register_operand" "f")
14387                          (match_operand 2 "register_operand" "f")])
14388           (label_ref (match_operand 3 "" ""))
14389           (pc)))
14390    (clobber (reg:CCFP FPSR_REG))
14391    (clobber (reg:CCFP FLAGS_REG))]
14392   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14393    && TARGET_CMOVE
14394    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14395    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14396   "#")
14397
14398 (define_insn "*fp_jcc_2_mixed"
14399   [(set (pc)
14400         (if_then_else (match_operator 0 "comparison_operator"
14401                         [(match_operand 1 "register_operand" "f,x")
14402                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14403           (pc)
14404           (label_ref (match_operand 3 "" ""))))
14405    (clobber (reg:CCFP FPSR_REG))
14406    (clobber (reg:CCFP FLAGS_REG))]
14407   "TARGET_MIX_SSE_I387
14408    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14409    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14410    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14411   "#")
14412
14413 (define_insn "*fp_jcc_2_sse"
14414   [(set (pc)
14415         (if_then_else (match_operator 0 "comparison_operator"
14416                         [(match_operand 1 "register_operand" "x")
14417                          (match_operand 2 "nonimmediate_operand" "xm")])
14418           (pc)
14419           (label_ref (match_operand 3 "" ""))))
14420    (clobber (reg:CCFP FPSR_REG))
14421    (clobber (reg:CCFP FLAGS_REG))]
14422   "TARGET_SSE_MATH
14423    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14424    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14425    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14426   "#")
14427
14428 (define_insn "*fp_jcc_2_387"
14429   [(set (pc)
14430         (if_then_else (match_operator 0 "comparison_operator"
14431                         [(match_operand 1 "register_operand" "f")
14432                          (match_operand 2 "register_operand" "f")])
14433           (pc)
14434           (label_ref (match_operand 3 "" ""))))
14435    (clobber (reg:CCFP FPSR_REG))
14436    (clobber (reg:CCFP FLAGS_REG))]
14437   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14438    && TARGET_CMOVE
14439    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14440    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14441   "#")
14442
14443 (define_insn "*fp_jcc_3_387"
14444   [(set (pc)
14445         (if_then_else (match_operator 0 "comparison_operator"
14446                         [(match_operand 1 "register_operand" "f")
14447                          (match_operand 2 "nonimmediate_operand" "fm")])
14448           (label_ref (match_operand 3 "" ""))
14449           (pc)))
14450    (clobber (reg:CCFP FPSR_REG))
14451    (clobber (reg:CCFP FLAGS_REG))
14452    (clobber (match_scratch:HI 4 "=a"))]
14453   "TARGET_80387
14454    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14455    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14457    && SELECT_CC_MODE (GET_CODE (operands[0]),
14458                       operands[1], operands[2]) == CCFPmode
14459    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14460   "#")
14461
14462 (define_insn "*fp_jcc_4_387"
14463   [(set (pc)
14464         (if_then_else (match_operator 0 "comparison_operator"
14465                         [(match_operand 1 "register_operand" "f")
14466                          (match_operand 2 "nonimmediate_operand" "fm")])
14467           (pc)
14468           (label_ref (match_operand 3 "" ""))))
14469    (clobber (reg:CCFP FPSR_REG))
14470    (clobber (reg:CCFP FLAGS_REG))
14471    (clobber (match_scratch:HI 4 "=a"))]
14472   "TARGET_80387
14473    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14474    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14475    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14476    && SELECT_CC_MODE (GET_CODE (operands[0]),
14477                       operands[1], operands[2]) == CCFPmode
14478    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14479   "#")
14480
14481 (define_insn "*fp_jcc_5_387"
14482   [(set (pc)
14483         (if_then_else (match_operator 0 "comparison_operator"
14484                         [(match_operand 1 "register_operand" "f")
14485                          (match_operand 2 "register_operand" "f")])
14486           (label_ref (match_operand 3 "" ""))
14487           (pc)))
14488    (clobber (reg:CCFP FPSR_REG))
14489    (clobber (reg:CCFP FLAGS_REG))
14490    (clobber (match_scratch:HI 4 "=a"))]
14491   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14492    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14493    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14494   "#")
14495
14496 (define_insn "*fp_jcc_6_387"
14497   [(set (pc)
14498         (if_then_else (match_operator 0 "comparison_operator"
14499                         [(match_operand 1 "register_operand" "f")
14500                          (match_operand 2 "register_operand" "f")])
14501           (pc)
14502           (label_ref (match_operand 3 "" ""))))
14503    (clobber (reg:CCFP FPSR_REG))
14504    (clobber (reg:CCFP FLAGS_REG))
14505    (clobber (match_scratch:HI 4 "=a"))]
14506   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14507    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14508    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14509   "#")
14510
14511 (define_insn "*fp_jcc_7_387"
14512   [(set (pc)
14513         (if_then_else (match_operator 0 "comparison_operator"
14514                         [(match_operand 1 "register_operand" "f")
14515                          (match_operand 2 "const0_operand" "X")])
14516           (label_ref (match_operand 3 "" ""))
14517           (pc)))
14518    (clobber (reg:CCFP FPSR_REG))
14519    (clobber (reg:CCFP FLAGS_REG))
14520    (clobber (match_scratch:HI 4 "=a"))]
14521   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14522    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14523    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14524    && SELECT_CC_MODE (GET_CODE (operands[0]),
14525                       operands[1], operands[2]) == CCFPmode
14526    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14527   "#")
14528
14529 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14530 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14531 ;; with a precedence over other operators and is always put in the first
14532 ;; place. Swap condition and operands to match ficom instruction.
14533
14534 (define_insn "*fp_jcc_8<mode>_387"
14535   [(set (pc)
14536         (if_then_else (match_operator 0 "comparison_operator"
14537                         [(match_operator 1 "float_operator"
14538                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14539                            (match_operand 3 "register_operand" "f,f")])
14540           (label_ref (match_operand 4 "" ""))
14541           (pc)))
14542    (clobber (reg:CCFP FPSR_REG))
14543    (clobber (reg:CCFP FLAGS_REG))
14544    (clobber (match_scratch:HI 5 "=a,a"))]
14545   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14546    && TARGET_USE_<MODE>MODE_FIOP
14547    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14548    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14549    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14550    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14551   "#")
14552
14553 (define_split
14554   [(set (pc)
14555         (if_then_else (match_operator 0 "comparison_operator"
14556                         [(match_operand 1 "register_operand" "")
14557                          (match_operand 2 "nonimmediate_operand" "")])
14558           (match_operand 3 "" "")
14559           (match_operand 4 "" "")))
14560    (clobber (reg:CCFP FPSR_REG))
14561    (clobber (reg:CCFP FLAGS_REG))]
14562   "reload_completed"
14563   [(const_int 0)]
14564 {
14565   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14566                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14567   DONE;
14568 })
14569
14570 (define_split
14571   [(set (pc)
14572         (if_then_else (match_operator 0 "comparison_operator"
14573                         [(match_operand 1 "register_operand" "")
14574                          (match_operand 2 "general_operand" "")])
14575           (match_operand 3 "" "")
14576           (match_operand 4 "" "")))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))
14579    (clobber (match_scratch:HI 5 "=a"))]
14580   "reload_completed"
14581   [(const_int 0)]
14582 {
14583   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14584                         operands[3], operands[4], operands[5], NULL_RTX);
14585   DONE;
14586 })
14587
14588 (define_split
14589   [(set (pc)
14590         (if_then_else (match_operator 0 "comparison_operator"
14591                         [(match_operator 1 "float_operator"
14592                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14593                            (match_operand 3 "register_operand" "")])
14594           (match_operand 4 "" "")
14595           (match_operand 5 "" "")))
14596    (clobber (reg:CCFP FPSR_REG))
14597    (clobber (reg:CCFP FLAGS_REG))
14598    (clobber (match_scratch:HI 6 "=a"))]
14599   "reload_completed"
14600   [(const_int 0)]
14601 {
14602   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14603   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14604                         operands[3], operands[7],
14605                         operands[4], operands[5], operands[6], NULL_RTX);
14606   DONE;
14607 })
14608
14609 ;; %%% Kill this when reload knows how to do it.
14610 (define_split
14611   [(set (pc)
14612         (if_then_else (match_operator 0 "comparison_operator"
14613                         [(match_operator 1 "float_operator"
14614                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14615                            (match_operand 3 "register_operand" "")])
14616           (match_operand 4 "" "")
14617           (match_operand 5 "" "")))
14618    (clobber (reg:CCFP FPSR_REG))
14619    (clobber (reg:CCFP FLAGS_REG))
14620    (clobber (match_scratch:HI 6 "=a"))]
14621   "reload_completed"
14622   [(const_int 0)]
14623 {
14624   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14625   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14626   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14627                         operands[3], operands[7],
14628                         operands[4], operands[5], operands[6], operands[2]);
14629   DONE;
14630 })
14631 \f
14632 ;; Unconditional and other jump instructions
14633
14634 (define_insn "jump"
14635   [(set (pc)
14636         (label_ref (match_operand 0 "" "")))]
14637   ""
14638   "jmp\t%l0"
14639   [(set_attr "type" "ibr")
14640    (set (attr "length")
14641            (if_then_else (and (ge (minus (match_dup 0) (pc))
14642                                   (const_int -126))
14643                               (lt (minus (match_dup 0) (pc))
14644                                   (const_int 128)))
14645              (const_int 2)
14646              (const_int 5)))
14647    (set_attr "modrm" "0")])
14648
14649 (define_expand "indirect_jump"
14650   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14651   ""
14652   "")
14653
14654 (define_insn "*indirect_jump"
14655   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14656   "!TARGET_64BIT"
14657   "jmp\t%A0"
14658   [(set_attr "type" "ibr")
14659    (set_attr "length_immediate" "0")])
14660
14661 (define_insn "*indirect_jump_rtx64"
14662   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14663   "TARGET_64BIT"
14664   "jmp\t%A0"
14665   [(set_attr "type" "ibr")
14666    (set_attr "length_immediate" "0")])
14667
14668 (define_expand "tablejump"
14669   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14670               (use (label_ref (match_operand 1 "" "")))])]
14671   ""
14672 {
14673   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14674      relative.  Convert the relative address to an absolute address.  */
14675   if (flag_pic)
14676     {
14677       rtx op0, op1;
14678       enum rtx_code code;
14679
14680       /* We can't use @GOTOFF for text labels on VxWorks;
14681          see gotoff_operand.  */
14682       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14683         {
14684           code = PLUS;
14685           op0 = operands[0];
14686           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14687         }
14688       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14689         {
14690           code = PLUS;
14691           op0 = operands[0];
14692           op1 = pic_offset_table_rtx;
14693         }
14694       else
14695         {
14696           code = MINUS;
14697           op0 = pic_offset_table_rtx;
14698           op1 = operands[0];
14699         }
14700
14701       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14702                                          OPTAB_DIRECT);
14703     }
14704 })
14705
14706 (define_insn "*tablejump_1"
14707   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14708    (use (label_ref (match_operand 1 "" "")))]
14709   "!TARGET_64BIT"
14710   "jmp\t%A0"
14711   [(set_attr "type" "ibr")
14712    (set_attr "length_immediate" "0")])
14713
14714 (define_insn "*tablejump_1_rtx64"
14715   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14716    (use (label_ref (match_operand 1 "" "")))]
14717   "TARGET_64BIT"
14718   "jmp\t%A0"
14719   [(set_attr "type" "ibr")
14720    (set_attr "length_immediate" "0")])
14721 \f
14722 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14723
14724 (define_peephole2
14725   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14726    (set (match_operand:QI 1 "register_operand" "")
14727         (match_operator:QI 2 "ix86_comparison_operator"
14728           [(reg FLAGS_REG) (const_int 0)]))
14729    (set (match_operand 3 "q_regs_operand" "")
14730         (zero_extend (match_dup 1)))]
14731   "(peep2_reg_dead_p (3, operands[1])
14732     || operands_match_p (operands[1], operands[3]))
14733    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14734   [(set (match_dup 4) (match_dup 0))
14735    (set (strict_low_part (match_dup 5))
14736         (match_dup 2))]
14737 {
14738   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14739   operands[5] = gen_lowpart (QImode, operands[3]);
14740   ix86_expand_clear (operands[3]);
14741 })
14742
14743 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14744
14745 (define_peephole2
14746   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14747    (set (match_operand:QI 1 "register_operand" "")
14748         (match_operator:QI 2 "ix86_comparison_operator"
14749           [(reg FLAGS_REG) (const_int 0)]))
14750    (parallel [(set (match_operand 3 "q_regs_operand" "")
14751                    (zero_extend (match_dup 1)))
14752               (clobber (reg:CC FLAGS_REG))])]
14753   "(peep2_reg_dead_p (3, operands[1])
14754     || operands_match_p (operands[1], operands[3]))
14755    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14756   [(set (match_dup 4) (match_dup 0))
14757    (set (strict_low_part (match_dup 5))
14758         (match_dup 2))]
14759 {
14760   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14761   operands[5] = gen_lowpart (QImode, operands[3]);
14762   ix86_expand_clear (operands[3]);
14763 })
14764 \f
14765 ;; Call instructions.
14766
14767 ;; The predicates normally associated with named expanders are not properly
14768 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14769 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14770
14771 ;; Call subroutine returning no value.
14772
14773 (define_expand "call_pop"
14774   [(parallel [(call (match_operand:QI 0 "" "")
14775                     (match_operand:SI 1 "" ""))
14776               (set (reg:SI SP_REG)
14777                    (plus:SI (reg:SI SP_REG)
14778                             (match_operand:SI 3 "" "")))])]
14779   "!TARGET_64BIT"
14780 {
14781   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14782   DONE;
14783 })
14784
14785 (define_insn "*call_pop_0"
14786   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14787          (match_operand:SI 1 "" ""))
14788    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14789                             (match_operand:SI 2 "immediate_operand" "")))]
14790   "!TARGET_64BIT"
14791 {
14792   if (SIBLING_CALL_P (insn))
14793     return "jmp\t%P0";
14794   else
14795     return "call\t%P0";
14796 }
14797   [(set_attr "type" "call")])
14798
14799 (define_insn "*call_pop_1"
14800   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14801          (match_operand:SI 1 "" ""))
14802    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14803                             (match_operand:SI 2 "immediate_operand" "i")))]
14804   "!TARGET_64BIT"
14805 {
14806   if (constant_call_address_operand (operands[0], Pmode))
14807     {
14808       if (SIBLING_CALL_P (insn))
14809         return "jmp\t%P0";
14810       else
14811         return "call\t%P0";
14812     }
14813   if (SIBLING_CALL_P (insn))
14814     return "jmp\t%A0";
14815   else
14816     return "call\t%A0";
14817 }
14818   [(set_attr "type" "call")])
14819
14820 (define_expand "call"
14821   [(call (match_operand:QI 0 "" "")
14822          (match_operand 1 "" ""))
14823    (use (match_operand 2 "" ""))]
14824   ""
14825 {
14826   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14827   DONE;
14828 })
14829
14830 (define_expand "sibcall"
14831   [(call (match_operand:QI 0 "" "")
14832          (match_operand 1 "" ""))
14833    (use (match_operand 2 "" ""))]
14834   ""
14835 {
14836   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14837   DONE;
14838 })
14839
14840 (define_insn "*call_0"
14841   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14842          (match_operand 1 "" ""))]
14843   ""
14844 {
14845   if (SIBLING_CALL_P (insn))
14846     return "jmp\t%P0";
14847   else
14848     return "call\t%P0";
14849 }
14850   [(set_attr "type" "call")])
14851
14852 (define_insn "*call_1"
14853   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14854          (match_operand 1 "" ""))]
14855   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14856 {
14857   if (constant_call_address_operand (operands[0], Pmode))
14858     return "call\t%P0";
14859   return "call\t%A0";
14860 }
14861   [(set_attr "type" "call")])
14862
14863 (define_insn "*sibcall_1"
14864   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14865          (match_operand 1 "" ""))]
14866   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14867 {
14868   if (constant_call_address_operand (operands[0], Pmode))
14869     return "jmp\t%P0";
14870   return "jmp\t%A0";
14871 }
14872   [(set_attr "type" "call")])
14873
14874 (define_insn "*call_1_rex64"
14875   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14876          (match_operand 1 "" ""))]
14877   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14878    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14879 {
14880   if (constant_call_address_operand (operands[0], Pmode))
14881     return "call\t%P0";
14882   return "call\t%A0";
14883 }
14884   [(set_attr "type" "call")])
14885
14886 (define_insn "*call_1_rex64_large"
14887   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14888          (match_operand 1 "" ""))]
14889   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14890   "call\t%A0"
14891   [(set_attr "type" "call")])
14892
14893 (define_insn "*sibcall_1_rex64"
14894   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14895          (match_operand 1 "" ""))]
14896   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14897   "jmp\t%P0"
14898   [(set_attr "type" "call")])
14899
14900 (define_insn "*sibcall_1_rex64_v"
14901   [(call (mem:QI (reg:DI R11_REG))
14902          (match_operand 0 "" ""))]
14903   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14904   "jmp\t*%%r11"
14905   [(set_attr "type" "call")])
14906
14907
14908 ;; Call subroutine, returning value in operand 0
14909
14910 (define_expand "call_value_pop"
14911   [(parallel [(set (match_operand 0 "" "")
14912                    (call (match_operand:QI 1 "" "")
14913                          (match_operand:SI 2 "" "")))
14914               (set (reg:SI SP_REG)
14915                    (plus:SI (reg:SI SP_REG)
14916                             (match_operand:SI 4 "" "")))])]
14917   "!TARGET_64BIT"
14918 {
14919   ix86_expand_call (operands[0], operands[1], operands[2],
14920                     operands[3], operands[4], 0);
14921   DONE;
14922 })
14923
14924 (define_expand "call_value"
14925   [(set (match_operand 0 "" "")
14926         (call (match_operand:QI 1 "" "")
14927               (match_operand:SI 2 "" "")))
14928    (use (match_operand:SI 3 "" ""))]
14929   ;; Operand 2 not used on the i386.
14930   ""
14931 {
14932   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14933   DONE;
14934 })
14935
14936 (define_expand "sibcall_value"
14937   [(set (match_operand 0 "" "")
14938         (call (match_operand:QI 1 "" "")
14939               (match_operand:SI 2 "" "")))
14940    (use (match_operand:SI 3 "" ""))]
14941   ;; Operand 2 not used on the i386.
14942   ""
14943 {
14944   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14945   DONE;
14946 })
14947
14948 ;; Call subroutine returning any type.
14949
14950 (define_expand "untyped_call"
14951   [(parallel [(call (match_operand 0 "" "")
14952                     (const_int 0))
14953               (match_operand 1 "" "")
14954               (match_operand 2 "" "")])]
14955   ""
14956 {
14957   int i;
14958
14959   /* In order to give reg-stack an easier job in validating two
14960      coprocessor registers as containing a possible return value,
14961      simply pretend the untyped call returns a complex long double
14962      value.  */
14963
14964   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14965                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14966                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14967                     NULL, 0);
14968
14969   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14970     {
14971       rtx set = XVECEXP (operands[2], 0, i);
14972       emit_move_insn (SET_DEST (set), SET_SRC (set));
14973     }
14974
14975   /* The optimizer does not know that the call sets the function value
14976      registers we stored in the result block.  We avoid problems by
14977      claiming that all hard registers are used and clobbered at this
14978      point.  */
14979   emit_insn (gen_blockage ());
14980
14981   DONE;
14982 })
14983 \f
14984 ;; Prologue and epilogue instructions
14985
14986 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14987 ;; all of memory.  This blocks insns from being moved across this point.
14988
14989 (define_insn "blockage"
14990   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14991   ""
14992   ""
14993   [(set_attr "length" "0")])
14994
14995 ;; As USE insns aren't meaningful after reload, this is used instead
14996 ;; to prevent deleting instructions setting registers for PIC code
14997 (define_insn "prologue_use"
14998   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14999   ""
15000   ""
15001   [(set_attr "length" "0")])
15002
15003 ;; Insn emitted into the body of a function to return from a function.
15004 ;; This is only done if the function's epilogue is known to be simple.
15005 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15006
15007 (define_expand "return"
15008   [(return)]
15009   "ix86_can_use_return_insn_p ()"
15010 {
15011   if (current_function_pops_args)
15012     {
15013       rtx popc = GEN_INT (current_function_pops_args);
15014       emit_jump_insn (gen_return_pop_internal (popc));
15015       DONE;
15016     }
15017 })
15018
15019 (define_insn "return_internal"
15020   [(return)]
15021   "reload_completed"
15022   "ret"
15023   [(set_attr "length" "1")
15024    (set_attr "length_immediate" "0")
15025    (set_attr "modrm" "0")])
15026
15027 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15028 ;; instruction Athlon and K8 have.
15029
15030 (define_insn "return_internal_long"
15031   [(return)
15032    (unspec [(const_int 0)] UNSPEC_REP)]
15033   "reload_completed"
15034   "rep{\;| }ret"
15035   [(set_attr "length" "1")
15036    (set_attr "length_immediate" "0")
15037    (set_attr "prefix_rep" "1")
15038    (set_attr "modrm" "0")])
15039
15040 (define_insn "return_pop_internal"
15041   [(return)
15042    (use (match_operand:SI 0 "const_int_operand" ""))]
15043   "reload_completed"
15044   "ret\t%0"
15045   [(set_attr "length" "3")
15046    (set_attr "length_immediate" "2")
15047    (set_attr "modrm" "0")])
15048
15049 (define_insn "return_indirect_internal"
15050   [(return)
15051    (use (match_operand:SI 0 "register_operand" "r"))]
15052   "reload_completed"
15053   "jmp\t%A0"
15054   [(set_attr "type" "ibr")
15055    (set_attr "length_immediate" "0")])
15056
15057 (define_insn "nop"
15058   [(const_int 0)]
15059   ""
15060   "nop"
15061   [(set_attr "length" "1")
15062    (set_attr "length_immediate" "0")
15063    (set_attr "modrm" "0")])
15064
15065 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15066 ;; branch prediction penalty for the third jump in a 16-byte
15067 ;; block on K8.
15068
15069 (define_insn "align"
15070   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15071   ""
15072 {
15073 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15074   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15075 #else
15076   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15077      The align insn is used to avoid 3 jump instructions in the row to improve
15078      branch prediction and the benefits hardly outweigh the cost of extra 8
15079      nops on the average inserted by full alignment pseudo operation.  */
15080 #endif
15081   return "";
15082 }
15083   [(set_attr "length" "16")])
15084
15085 (define_expand "prologue"
15086   [(const_int 0)]
15087   ""
15088   "ix86_expand_prologue (); DONE;")
15089
15090 (define_insn "set_got"
15091   [(set (match_operand:SI 0 "register_operand" "=r")
15092         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15093    (clobber (reg:CC FLAGS_REG))]
15094   "!TARGET_64BIT"
15095   { return output_set_got (operands[0], NULL_RTX); }
15096   [(set_attr "type" "multi")
15097    (set_attr "length" "12")])
15098
15099 (define_insn "set_got_labelled"
15100   [(set (match_operand:SI 0 "register_operand" "=r")
15101         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15102          UNSPEC_SET_GOT))
15103    (clobber (reg:CC FLAGS_REG))]
15104   "!TARGET_64BIT"
15105   { return output_set_got (operands[0], operands[1]); }
15106   [(set_attr "type" "multi")
15107    (set_attr "length" "12")])
15108
15109 (define_insn "set_got_rex64"
15110   [(set (match_operand:DI 0 "register_operand" "=r")
15111         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15112   "TARGET_64BIT"
15113   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
15114   [(set_attr "type" "lea")
15115    (set_attr "length" "6")])
15116
15117 (define_insn "set_rip_rex64"
15118   [(set (match_operand:DI 0 "register_operand" "=r")
15119         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15120   "TARGET_64BIT"
15121   "lea{q}\t%l1(%%rip), %0"
15122   [(set_attr "type" "lea")
15123    (set_attr "length" "6")])
15124
15125 (define_insn "set_got_offset_rex64"
15126   [(set (match_operand:DI 0 "register_operand" "=r")
15127         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15128   "TARGET_64BIT"
15129   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
15130   [(set_attr "type" "imov")
15131    (set_attr "length" "11")])
15132
15133 (define_expand "epilogue"
15134   [(const_int 0)]
15135   ""
15136   "ix86_expand_epilogue (1); DONE;")
15137
15138 (define_expand "sibcall_epilogue"
15139   [(const_int 0)]
15140   ""
15141   "ix86_expand_epilogue (0); DONE;")
15142
15143 (define_expand "eh_return"
15144   [(use (match_operand 0 "register_operand" ""))]
15145   ""
15146 {
15147   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15148
15149   /* Tricky bit: we write the address of the handler to which we will
15150      be returning into someone else's stack frame, one word below the
15151      stack address we wish to restore.  */
15152   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15153   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15154   tmp = gen_rtx_MEM (Pmode, tmp);
15155   emit_move_insn (tmp, ra);
15156
15157   if (Pmode == SImode)
15158     emit_jump_insn (gen_eh_return_si (sa));
15159   else
15160     emit_jump_insn (gen_eh_return_di (sa));
15161   emit_barrier ();
15162   DONE;
15163 })
15164
15165 (define_insn_and_split "eh_return_si"
15166   [(set (pc)
15167         (unspec [(match_operand:SI 0 "register_operand" "c")]
15168                  UNSPEC_EH_RETURN))]
15169   "!TARGET_64BIT"
15170   "#"
15171   "reload_completed"
15172   [(const_int 0)]
15173   "ix86_expand_epilogue (2); DONE;")
15174
15175 (define_insn_and_split "eh_return_di"
15176   [(set (pc)
15177         (unspec [(match_operand:DI 0 "register_operand" "c")]
15178                  UNSPEC_EH_RETURN))]
15179   "TARGET_64BIT"
15180   "#"
15181   "reload_completed"
15182   [(const_int 0)]
15183   "ix86_expand_epilogue (2); DONE;")
15184
15185 (define_insn "leave"
15186   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15187    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15188    (clobber (mem:BLK (scratch)))]
15189   "!TARGET_64BIT"
15190   "leave"
15191   [(set_attr "type" "leave")])
15192
15193 (define_insn "leave_rex64"
15194   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15195    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15196    (clobber (mem:BLK (scratch)))]
15197   "TARGET_64BIT"
15198   "leave"
15199   [(set_attr "type" "leave")])
15200 \f
15201 (define_expand "ffssi2"
15202   [(parallel
15203      [(set (match_operand:SI 0 "register_operand" "")
15204            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15205       (clobber (match_scratch:SI 2 ""))
15206       (clobber (reg:CC FLAGS_REG))])]
15207   ""
15208 {
15209   if (TARGET_CMOVE)
15210     {
15211       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15212       DONE;
15213     }
15214 })
15215
15216 (define_expand "ffs_cmove"
15217   [(set (match_dup 2) (const_int -1))
15218    (parallel [(set (reg:CCZ FLAGS_REG)
15219                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15220                                 (const_int 0)))
15221               (set (match_operand:SI 0 "nonimmediate_operand" "")
15222                    (ctz:SI (match_dup 1)))])
15223    (set (match_dup 0) (if_then_else:SI
15224                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15225                         (match_dup 2)
15226                         (match_dup 0)))
15227    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15228               (clobber (reg:CC FLAGS_REG))])]
15229   "TARGET_CMOVE"
15230   "operands[2] = gen_reg_rtx (SImode);")
15231
15232 (define_insn_and_split "*ffs_no_cmove"
15233   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15234         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15235    (clobber (match_scratch:SI 2 "=&q"))
15236    (clobber (reg:CC FLAGS_REG))]
15237   "!TARGET_CMOVE"
15238   "#"
15239   "&& reload_completed"
15240   [(parallel [(set (reg:CCZ FLAGS_REG)
15241                    (compare:CCZ (match_dup 1) (const_int 0)))
15242               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15243    (set (strict_low_part (match_dup 3))
15244         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15245    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15246               (clobber (reg:CC FLAGS_REG))])
15247    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15248               (clobber (reg:CC FLAGS_REG))])
15249    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15250               (clobber (reg:CC FLAGS_REG))])]
15251 {
15252   operands[3] = gen_lowpart (QImode, operands[2]);
15253   ix86_expand_clear (operands[2]);
15254 })
15255
15256 (define_insn "*ffssi_1"
15257   [(set (reg:CCZ FLAGS_REG)
15258         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15259                      (const_int 0)))
15260    (set (match_operand:SI 0 "register_operand" "=r")
15261         (ctz:SI (match_dup 1)))]
15262   ""
15263   "bsf{l}\t{%1, %0|%0, %1}"
15264   [(set_attr "prefix_0f" "1")])
15265
15266 (define_expand "ffsdi2"
15267   [(set (match_dup 2) (const_int -1))
15268    (parallel [(set (reg:CCZ FLAGS_REG)
15269                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15270                                 (const_int 0)))
15271               (set (match_operand:DI 0 "nonimmediate_operand" "")
15272                    (ctz:DI (match_dup 1)))])
15273    (set (match_dup 0) (if_then_else:DI
15274                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15275                         (match_dup 2)
15276                         (match_dup 0)))
15277    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15278               (clobber (reg:CC FLAGS_REG))])]
15279   "TARGET_64BIT"
15280   "operands[2] = gen_reg_rtx (DImode);")
15281
15282 (define_insn "*ffsdi_1"
15283   [(set (reg:CCZ FLAGS_REG)
15284         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15285                      (const_int 0)))
15286    (set (match_operand:DI 0 "register_operand" "=r")
15287         (ctz:DI (match_dup 1)))]
15288   "TARGET_64BIT"
15289   "bsf{q}\t{%1, %0|%0, %1}"
15290   [(set_attr "prefix_0f" "1")])
15291
15292 (define_insn "ctzsi2"
15293   [(set (match_operand:SI 0 "register_operand" "=r")
15294         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15295    (clobber (reg:CC FLAGS_REG))]
15296   ""
15297   "bsf{l}\t{%1, %0|%0, %1}"
15298   [(set_attr "prefix_0f" "1")])
15299
15300 (define_insn "ctzdi2"
15301   [(set (match_operand:DI 0 "register_operand" "=r")
15302         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15303    (clobber (reg:CC FLAGS_REG))]
15304   "TARGET_64BIT"
15305   "bsf{q}\t{%1, %0|%0, %1}"
15306   [(set_attr "prefix_0f" "1")])
15307
15308 (define_expand "clzsi2"
15309   [(parallel
15310      [(set (match_operand:SI 0 "register_operand" "")
15311            (minus:SI (const_int 31)
15312                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15313       (clobber (reg:CC FLAGS_REG))])
15314    (parallel
15315      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15316       (clobber (reg:CC FLAGS_REG))])]
15317   ""
15318 {
15319   if (TARGET_ABM)
15320     {
15321       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15322       DONE;
15323     }
15324 })
15325
15326 (define_insn "clzsi2_abm"
15327   [(set (match_operand:SI 0 "register_operand" "=r")
15328         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15329    (clobber (reg:CC FLAGS_REG))]
15330   "TARGET_ABM"
15331   "lzcnt{l}\t{%1, %0|%0, %1}"
15332   [(set_attr "prefix_rep" "1")
15333    (set_attr "type" "bitmanip")
15334    (set_attr "mode" "SI")])
15335
15336 (define_insn "*bsr"
15337   [(set (match_operand:SI 0 "register_operand" "=r")
15338         (minus:SI (const_int 31)
15339                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15340    (clobber (reg:CC FLAGS_REG))]
15341   ""
15342   "bsr{l}\t{%1, %0|%0, %1}"
15343   [(set_attr "prefix_0f" "1")
15344    (set_attr "mode" "SI")])
15345
15346 (define_insn "popcountsi2"
15347   [(set (match_operand:SI 0 "register_operand" "=r")
15348         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15349    (clobber (reg:CC FLAGS_REG))]
15350   "TARGET_POPCNT"
15351   "popcnt{l}\t{%1, %0|%0, %1}"
15352   [(set_attr "prefix_rep" "1")
15353    (set_attr "type" "bitmanip")
15354    (set_attr "mode" "SI")])
15355
15356 (define_insn "*popcountsi2_cmp"
15357   [(set (reg FLAGS_REG)
15358         (compare
15359           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15360           (const_int 0)))
15361    (set (match_operand:SI 0 "register_operand" "=r")
15362         (popcount:SI (match_dup 1)))]
15363   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364   "popcnt{l}\t{%1, %0|%0, %1}"
15365   [(set_attr "prefix_rep" "1")
15366    (set_attr "type" "bitmanip")
15367    (set_attr "mode" "SI")])
15368
15369 (define_insn "*popcountsi2_cmp_zext"
15370   [(set (reg FLAGS_REG)
15371         (compare
15372           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15373           (const_int 0)))
15374    (set (match_operand:DI 0 "register_operand" "=r")
15375         (zero_extend:DI(popcount:SI (match_dup 1))))]
15376   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15377   "popcnt{l}\t{%1, %0|%0, %1}"
15378   [(set_attr "prefix_rep" "1")
15379    (set_attr "type" "bitmanip")
15380    (set_attr "mode" "SI")])
15381
15382 (define_expand "bswapsi2"
15383   [(set (match_operand:SI 0 "register_operand" "")
15384         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15385   ""
15386 {
15387   if (!TARGET_BSWAP)
15388     {
15389       rtx x = operands[0];
15390
15391       emit_move_insn (x, operands[1]);
15392       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15393       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15394       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15395       DONE;
15396     }
15397 })
15398
15399 (define_insn "*bswapsi_1"
15400   [(set (match_operand:SI 0 "register_operand" "=r")
15401         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15402   "TARGET_BSWAP"
15403   "bswap\t%0"
15404   [(set_attr "prefix_0f" "1")
15405    (set_attr "length" "2")])
15406
15407 (define_insn "*bswaphi_lowpart_1"
15408   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15409         (bswap:HI (match_dup 0)))
15410    (clobber (reg:CC FLAGS_REG))]
15411   "TARGET_USE_XCHGB || optimize_size"
15412   "@
15413     xchg{b}\t{%h0, %b0|%b0, %h0}
15414     rol{w}\t{$8, %0|%0, 8}"
15415   [(set_attr "length" "2,4")
15416    (set_attr "mode" "QI,HI")])
15417
15418 (define_insn "bswaphi_lowpart"
15419   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15420         (bswap:HI (match_dup 0)))
15421    (clobber (reg:CC FLAGS_REG))]
15422   ""
15423   "rol{w}\t{$8, %0|%0, 8}"
15424   [(set_attr "length" "4")
15425    (set_attr "mode" "HI")])
15426
15427 (define_insn "bswapdi2"
15428   [(set (match_operand:DI 0 "register_operand" "=r")
15429         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15430   "TARGET_64BIT"
15431   "bswap\t%0"
15432   [(set_attr "prefix_0f" "1")
15433    (set_attr "length" "3")])
15434
15435 (define_expand "clzdi2"
15436   [(parallel
15437      [(set (match_operand:DI 0 "register_operand" "")
15438            (minus:DI (const_int 63)
15439                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15440       (clobber (reg:CC FLAGS_REG))])
15441    (parallel
15442      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15443       (clobber (reg:CC FLAGS_REG))])]
15444   "TARGET_64BIT"
15445 {
15446   if (TARGET_ABM)
15447     {
15448       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15449       DONE;
15450     }
15451 })
15452
15453 (define_insn "clzdi2_abm"
15454   [(set (match_operand:DI 0 "register_operand" "=r")
15455         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15456    (clobber (reg:CC FLAGS_REG))]
15457   "TARGET_64BIT && TARGET_ABM"
15458   "lzcnt{q}\t{%1, %0|%0, %1}"
15459   [(set_attr "prefix_rep" "1")
15460    (set_attr "type" "bitmanip")
15461    (set_attr "mode" "DI")])
15462
15463 (define_insn "*bsr_rex64"
15464   [(set (match_operand:DI 0 "register_operand" "=r")
15465         (minus:DI (const_int 63)
15466                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15467    (clobber (reg:CC FLAGS_REG))]
15468   "TARGET_64BIT"
15469   "bsr{q}\t{%1, %0|%0, %1}"
15470   [(set_attr "prefix_0f" "1")
15471    (set_attr "mode" "DI")])
15472
15473 (define_insn "popcountdi2"
15474   [(set (match_operand:DI 0 "register_operand" "=r")
15475         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15476    (clobber (reg:CC FLAGS_REG))]
15477   "TARGET_64BIT && TARGET_POPCNT"
15478   "popcnt{q}\t{%1, %0|%0, %1}"
15479   [(set_attr "prefix_rep" "1")
15480    (set_attr "type" "bitmanip")
15481    (set_attr "mode" "DI")])
15482
15483 (define_insn "*popcountdi2_cmp"
15484   [(set (reg FLAGS_REG)
15485         (compare
15486           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15487           (const_int 0)))
15488    (set (match_operand:DI 0 "register_operand" "=r")
15489         (popcount:DI (match_dup 1)))]
15490   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15491   "popcnt{q}\t{%1, %0|%0, %1}"
15492   [(set_attr "prefix_rep" "1")
15493    (set_attr "type" "bitmanip")
15494    (set_attr "mode" "DI")])
15495
15496 (define_expand "clzhi2"
15497   [(parallel
15498      [(set (match_operand:HI 0 "register_operand" "")
15499            (minus:HI (const_int 15)
15500                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15501       (clobber (reg:CC FLAGS_REG))])
15502    (parallel
15503      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15504       (clobber (reg:CC FLAGS_REG))])]
15505   ""
15506 {
15507   if (TARGET_ABM)
15508     {
15509       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15510       DONE;
15511     }
15512 })
15513
15514 (define_insn "clzhi2_abm"
15515   [(set (match_operand:HI 0 "register_operand" "=r")
15516         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15517    (clobber (reg:CC FLAGS_REG))]
15518   "TARGET_ABM"
15519   "lzcnt{w}\t{%1, %0|%0, %1}"
15520   [(set_attr "prefix_rep" "1")
15521    (set_attr "type" "bitmanip")
15522    (set_attr "mode" "HI")])
15523
15524 (define_insn "*bsrhi"
15525   [(set (match_operand:HI 0 "register_operand" "=r")
15526         (minus:HI (const_int 15)
15527                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15528    (clobber (reg:CC FLAGS_REG))]
15529   ""
15530   "bsr{w}\t{%1, %0|%0, %1}"
15531   [(set_attr "prefix_0f" "1")
15532    (set_attr "mode" "HI")])
15533
15534 (define_insn "popcounthi2"
15535   [(set (match_operand:HI 0 "register_operand" "=r")
15536         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15537    (clobber (reg:CC FLAGS_REG))]
15538   "TARGET_POPCNT"
15539   "popcnt{w}\t{%1, %0|%0, %1}"
15540   [(set_attr "prefix_rep" "1")
15541    (set_attr "type" "bitmanip")
15542    (set_attr "mode" "HI")])
15543
15544 (define_insn "*popcounthi2_cmp"
15545   [(set (reg FLAGS_REG)
15546         (compare
15547           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15548           (const_int 0)))
15549    (set (match_operand:HI 0 "register_operand" "=r")
15550         (popcount:HI (match_dup 1)))]
15551   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15552   "popcnt{w}\t{%1, %0|%0, %1}"
15553   [(set_attr "prefix_rep" "1")
15554    (set_attr "type" "bitmanip")
15555    (set_attr "mode" "HI")])
15556
15557 (define_expand "paritydi2"
15558   [(set (match_operand:DI 0 "register_operand" "")
15559         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15560   "! TARGET_POPCNT"
15561 {
15562   rtx scratch = gen_reg_rtx (QImode);
15563   rtx cond;
15564
15565   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15566                                 NULL_RTX, operands[1]));
15567
15568   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15569                          gen_rtx_REG (CCmode, FLAGS_REG),
15570                          const0_rtx);
15571   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15572
15573   if (TARGET_64BIT)
15574     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15575   else
15576     {
15577       rtx tmp = gen_reg_rtx (SImode);
15578
15579       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15580       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15581     }
15582   DONE;
15583 })
15584
15585 (define_insn_and_split "paritydi2_cmp"
15586   [(set (reg:CC FLAGS_REG)
15587         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15588    (clobber (match_scratch:DI 0 "=r,X"))
15589    (clobber (match_scratch:SI 1 "=r,r"))
15590    (clobber (match_scratch:HI 2 "=Q,Q"))]
15591   "! TARGET_POPCNT"
15592   "#"
15593   "&& reload_completed"
15594   [(parallel
15595      [(set (match_dup 1)
15596            (xor:SI (match_dup 1) (match_dup 4)))
15597       (clobber (reg:CC FLAGS_REG))])
15598    (parallel
15599      [(set (reg:CC FLAGS_REG)
15600            (parity:CC (match_dup 1)))
15601       (clobber (match_dup 1))
15602       (clobber (match_dup 2))])]
15603 {
15604   operands[4] = gen_lowpart (SImode, operands[3]);
15605
15606   if (MEM_P (operands[3]))
15607     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15608   else if (! TARGET_64BIT)
15609     operands[1] = gen_highpart (SImode, operands[3]);
15610   else
15611     {
15612       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15613       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15614     }
15615 })
15616
15617 (define_expand "paritysi2"
15618   [(set (match_operand:SI 0 "register_operand" "")
15619         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15620   "! TARGET_POPCNT"
15621 {
15622   rtx scratch = gen_reg_rtx (QImode);
15623   rtx cond;
15624
15625   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15626
15627   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15628                          gen_rtx_REG (CCmode, FLAGS_REG),
15629                          const0_rtx);
15630   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15631
15632   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15633   DONE;
15634 })
15635
15636 (define_insn_and_split "paritysi2_cmp"
15637   [(set (reg:CC FLAGS_REG)
15638         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15639    (clobber (match_scratch:SI 0 "=r,X"))
15640    (clobber (match_scratch:HI 1 "=Q,Q"))]
15641   "! TARGET_POPCNT"
15642   "#"
15643   "&& reload_completed"
15644   [(parallel
15645      [(set (match_dup 1)
15646            (xor:HI (match_dup 1) (match_dup 3)))
15647       (clobber (reg:CC FLAGS_REG))])
15648    (parallel
15649      [(set (reg:CC FLAGS_REG)
15650            (parity:CC (match_dup 1)))
15651       (clobber (match_dup 1))])]
15652 {
15653   operands[3] = gen_lowpart (HImode, operands[2]);
15654
15655   if (MEM_P (operands[2]))
15656     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15657   else
15658     {
15659       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15660       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15661     }
15662 })
15663
15664 (define_insn "*parityhi2_cmp"
15665   [(set (reg:CC FLAGS_REG)
15666         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15667    (clobber (match_scratch:HI 0 "=Q"))]
15668   "! TARGET_POPCNT"
15669   "xor{b}\t{%h0, %b0|%b0, %h0}"
15670   [(set_attr "length" "2")
15671    (set_attr "mode" "HI")])
15672
15673 (define_insn "*parityqi2_cmp"
15674   [(set (reg:CC FLAGS_REG)
15675         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15676   "! TARGET_POPCNT"
15677   "test{b}\t%0, %0"
15678   [(set_attr "length" "2")
15679    (set_attr "mode" "QI")])
15680 \f
15681 ;; Thread-local storage patterns for ELF.
15682 ;;
15683 ;; Note that these code sequences must appear exactly as shown
15684 ;; in order to allow linker relaxation.
15685
15686 (define_insn "*tls_global_dynamic_32_gnu"
15687   [(set (match_operand:SI 0 "register_operand" "=a")
15688         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15689                     (match_operand:SI 2 "tls_symbolic_operand" "")
15690                     (match_operand:SI 3 "call_insn_operand" "")]
15691                     UNSPEC_TLS_GD))
15692    (clobber (match_scratch:SI 4 "=d"))
15693    (clobber (match_scratch:SI 5 "=c"))
15694    (clobber (reg:CC FLAGS_REG))]
15695   "!TARGET_64BIT && TARGET_GNU_TLS"
15696   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15697   [(set_attr "type" "multi")
15698    (set_attr "length" "12")])
15699
15700 (define_insn "*tls_global_dynamic_32_sun"
15701   [(set (match_operand:SI 0 "register_operand" "=a")
15702         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15703                     (match_operand:SI 2 "tls_symbolic_operand" "")
15704                     (match_operand:SI 3 "call_insn_operand" "")]
15705                     UNSPEC_TLS_GD))
15706    (clobber (match_scratch:SI 4 "=d"))
15707    (clobber (match_scratch:SI 5 "=c"))
15708    (clobber (reg:CC FLAGS_REG))]
15709   "!TARGET_64BIT && TARGET_SUN_TLS"
15710   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15711         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15712   [(set_attr "type" "multi")
15713    (set_attr "length" "14")])
15714
15715 (define_expand "tls_global_dynamic_32"
15716   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15717                    (unspec:SI
15718                     [(match_dup 2)
15719                      (match_operand:SI 1 "tls_symbolic_operand" "")
15720                      (match_dup 3)]
15721                     UNSPEC_TLS_GD))
15722               (clobber (match_scratch:SI 4 ""))
15723               (clobber (match_scratch:SI 5 ""))
15724               (clobber (reg:CC FLAGS_REG))])]
15725   ""
15726 {
15727   if (flag_pic)
15728     operands[2] = pic_offset_table_rtx;
15729   else
15730     {
15731       operands[2] = gen_reg_rtx (Pmode);
15732       emit_insn (gen_set_got (operands[2]));
15733     }
15734   if (TARGET_GNU2_TLS)
15735     {
15736        emit_insn (gen_tls_dynamic_gnu2_32
15737                   (operands[0], operands[1], operands[2]));
15738        DONE;
15739     }
15740   operands[3] = ix86_tls_get_addr ();
15741 })
15742
15743 (define_insn "*tls_global_dynamic_64"
15744   [(set (match_operand:DI 0 "register_operand" "=a")
15745         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15746                  (match_operand:DI 3 "" "")))
15747    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15748               UNSPEC_TLS_GD)]
15749   "TARGET_64BIT"
15750   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15751   [(set_attr "type" "multi")
15752    (set_attr "length" "16")])
15753
15754 (define_expand "tls_global_dynamic_64"
15755   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15756                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15757               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15758                          UNSPEC_TLS_GD)])]
15759   ""
15760 {
15761   if (TARGET_GNU2_TLS)
15762     {
15763        emit_insn (gen_tls_dynamic_gnu2_64
15764                   (operands[0], operands[1]));
15765        DONE;
15766     }
15767   operands[2] = ix86_tls_get_addr ();
15768 })
15769
15770 (define_insn "*tls_local_dynamic_base_32_gnu"
15771   [(set (match_operand:SI 0 "register_operand" "=a")
15772         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15773                     (match_operand:SI 2 "call_insn_operand" "")]
15774                    UNSPEC_TLS_LD_BASE))
15775    (clobber (match_scratch:SI 3 "=d"))
15776    (clobber (match_scratch:SI 4 "=c"))
15777    (clobber (reg:CC FLAGS_REG))]
15778   "!TARGET_64BIT && TARGET_GNU_TLS"
15779   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15780   [(set_attr "type" "multi")
15781    (set_attr "length" "11")])
15782
15783 (define_insn "*tls_local_dynamic_base_32_sun"
15784   [(set (match_operand:SI 0 "register_operand" "=a")
15785         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15786                     (match_operand:SI 2 "call_insn_operand" "")]
15787                    UNSPEC_TLS_LD_BASE))
15788    (clobber (match_scratch:SI 3 "=d"))
15789    (clobber (match_scratch:SI 4 "=c"))
15790    (clobber (reg:CC FLAGS_REG))]
15791   "!TARGET_64BIT && TARGET_SUN_TLS"
15792   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15793         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15794   [(set_attr "type" "multi")
15795    (set_attr "length" "13")])
15796
15797 (define_expand "tls_local_dynamic_base_32"
15798   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15799                    (unspec:SI [(match_dup 1) (match_dup 2)]
15800                               UNSPEC_TLS_LD_BASE))
15801               (clobber (match_scratch:SI 3 ""))
15802               (clobber (match_scratch:SI 4 ""))
15803               (clobber (reg:CC FLAGS_REG))])]
15804   ""
15805 {
15806   if (flag_pic)
15807     operands[1] = pic_offset_table_rtx;
15808   else
15809     {
15810       operands[1] = gen_reg_rtx (Pmode);
15811       emit_insn (gen_set_got (operands[1]));
15812     }
15813   if (TARGET_GNU2_TLS)
15814     {
15815        emit_insn (gen_tls_dynamic_gnu2_32
15816                   (operands[0], ix86_tls_module_base (), operands[1]));
15817        DONE;
15818     }
15819   operands[2] = ix86_tls_get_addr ();
15820 })
15821
15822 (define_insn "*tls_local_dynamic_base_64"
15823   [(set (match_operand:DI 0 "register_operand" "=a")
15824         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15825                  (match_operand:DI 2 "" "")))
15826    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15827   "TARGET_64BIT"
15828   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15829   [(set_attr "type" "multi")
15830    (set_attr "length" "12")])
15831
15832 (define_expand "tls_local_dynamic_base_64"
15833   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15834                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15835               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15836   ""
15837 {
15838   if (TARGET_GNU2_TLS)
15839     {
15840        emit_insn (gen_tls_dynamic_gnu2_64
15841                   (operands[0], ix86_tls_module_base ()));
15842        DONE;
15843     }
15844   operands[1] = ix86_tls_get_addr ();
15845 })
15846
15847 ;; Local dynamic of a single variable is a lose.  Show combine how
15848 ;; to convert that back to global dynamic.
15849
15850 (define_insn_and_split "*tls_local_dynamic_32_once"
15851   [(set (match_operand:SI 0 "register_operand" "=a")
15852         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15853                              (match_operand:SI 2 "call_insn_operand" "")]
15854                             UNSPEC_TLS_LD_BASE)
15855                  (const:SI (unspec:SI
15856                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15857                             UNSPEC_DTPOFF))))
15858    (clobber (match_scratch:SI 4 "=d"))
15859    (clobber (match_scratch:SI 5 "=c"))
15860    (clobber (reg:CC FLAGS_REG))]
15861   ""
15862   "#"
15863   ""
15864   [(parallel [(set (match_dup 0)
15865                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15866                               UNSPEC_TLS_GD))
15867               (clobber (match_dup 4))
15868               (clobber (match_dup 5))
15869               (clobber (reg:CC FLAGS_REG))])]
15870   "")
15871
15872 ;; Load and add the thread base pointer from %gs:0.
15873
15874 (define_insn "*load_tp_si"
15875   [(set (match_operand:SI 0 "register_operand" "=r")
15876         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15877   "!TARGET_64BIT"
15878   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15879   [(set_attr "type" "imov")
15880    (set_attr "modrm" "0")
15881    (set_attr "length" "7")
15882    (set_attr "memory" "load")
15883    (set_attr "imm_disp" "false")])
15884
15885 (define_insn "*add_tp_si"
15886   [(set (match_operand:SI 0 "register_operand" "=r")
15887         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15888                  (match_operand:SI 1 "register_operand" "0")))
15889    (clobber (reg:CC FLAGS_REG))]
15890   "!TARGET_64BIT"
15891   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15892   [(set_attr "type" "alu")
15893    (set_attr "modrm" "0")
15894    (set_attr "length" "7")
15895    (set_attr "memory" "load")
15896    (set_attr "imm_disp" "false")])
15897
15898 (define_insn "*load_tp_di"
15899   [(set (match_operand:DI 0 "register_operand" "=r")
15900         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15901   "TARGET_64BIT"
15902   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15903   [(set_attr "type" "imov")
15904    (set_attr "modrm" "0")
15905    (set_attr "length" "7")
15906    (set_attr "memory" "load")
15907    (set_attr "imm_disp" "false")])
15908
15909 (define_insn "*add_tp_di"
15910   [(set (match_operand:DI 0 "register_operand" "=r")
15911         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15912                  (match_operand:DI 1 "register_operand" "0")))
15913    (clobber (reg:CC FLAGS_REG))]
15914   "TARGET_64BIT"
15915   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15916   [(set_attr "type" "alu")
15917    (set_attr "modrm" "0")
15918    (set_attr "length" "7")
15919    (set_attr "memory" "load")
15920    (set_attr "imm_disp" "false")])
15921
15922 ;; GNU2 TLS patterns can be split.
15923
15924 (define_expand "tls_dynamic_gnu2_32"
15925   [(set (match_dup 3)
15926         (plus:SI (match_operand:SI 2 "register_operand" "")
15927                  (const:SI
15928                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15929                              UNSPEC_TLSDESC))))
15930    (parallel
15931     [(set (match_operand:SI 0 "register_operand" "")
15932           (unspec:SI [(match_dup 1) (match_dup 3)
15933                       (match_dup 2) (reg:SI SP_REG)]
15934                       UNSPEC_TLSDESC))
15935      (clobber (reg:CC FLAGS_REG))])]
15936   "!TARGET_64BIT && TARGET_GNU2_TLS"
15937 {
15938   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15939   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15940 })
15941
15942 (define_insn "*tls_dynamic_lea_32"
15943   [(set (match_operand:SI 0 "register_operand" "=r")
15944         (plus:SI (match_operand:SI 1 "register_operand" "b")
15945                  (const:SI
15946                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15947                               UNSPEC_TLSDESC))))]
15948   "!TARGET_64BIT && TARGET_GNU2_TLS"
15949   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15950   [(set_attr "type" "lea")
15951    (set_attr "mode" "SI")
15952    (set_attr "length" "6")
15953    (set_attr "length_address" "4")])
15954
15955 (define_insn "*tls_dynamic_call_32"
15956   [(set (match_operand:SI 0 "register_operand" "=a")
15957         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15958                     (match_operand:SI 2 "register_operand" "0")
15959                     ;; we have to make sure %ebx still points to the GOT
15960                     (match_operand:SI 3 "register_operand" "b")
15961                     (reg:SI SP_REG)]
15962                    UNSPEC_TLSDESC))
15963    (clobber (reg:CC FLAGS_REG))]
15964   "!TARGET_64BIT && TARGET_GNU2_TLS"
15965   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15966   [(set_attr "type" "call")
15967    (set_attr "length" "2")
15968    (set_attr "length_address" "0")])
15969
15970 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15971   [(set (match_operand:SI 0 "register_operand" "=&a")
15972         (plus:SI
15973          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15974                      (match_operand:SI 4 "" "")
15975                      (match_operand:SI 2 "register_operand" "b")
15976                      (reg:SI SP_REG)]
15977                     UNSPEC_TLSDESC)
15978          (const:SI (unspec:SI
15979                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15980                     UNSPEC_DTPOFF))))
15981    (clobber (reg:CC FLAGS_REG))]
15982   "!TARGET_64BIT && TARGET_GNU2_TLS"
15983   "#"
15984   ""
15985   [(set (match_dup 0) (match_dup 5))]
15986 {
15987   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15988   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15989 })
15990
15991 (define_expand "tls_dynamic_gnu2_64"
15992   [(set (match_dup 2)
15993         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15994                    UNSPEC_TLSDESC))
15995    (parallel
15996     [(set (match_operand:DI 0 "register_operand" "")
15997           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15998                      UNSPEC_TLSDESC))
15999      (clobber (reg:CC FLAGS_REG))])]
16000   "TARGET_64BIT && TARGET_GNU2_TLS"
16001 {
16002   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16003   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16004 })
16005
16006 (define_insn "*tls_dynamic_lea_64"
16007   [(set (match_operand:DI 0 "register_operand" "=r")
16008         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16009                    UNSPEC_TLSDESC))]
16010   "TARGET_64BIT && TARGET_GNU2_TLS"
16011   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
16012   [(set_attr "type" "lea")
16013    (set_attr "mode" "DI")
16014    (set_attr "length" "7")
16015    (set_attr "length_address" "4")])
16016
16017 (define_insn "*tls_dynamic_call_64"
16018   [(set (match_operand:DI 0 "register_operand" "=a")
16019         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16020                     (match_operand:DI 2 "register_operand" "0")
16021                     (reg:DI SP_REG)]
16022                    UNSPEC_TLSDESC))
16023    (clobber (reg:CC FLAGS_REG))]
16024   "TARGET_64BIT && TARGET_GNU2_TLS"
16025   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16026   [(set_attr "type" "call")
16027    (set_attr "length" "2")
16028    (set_attr "length_address" "0")])
16029
16030 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16031   [(set (match_operand:DI 0 "register_operand" "=&a")
16032         (plus:DI
16033          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16034                      (match_operand:DI 3 "" "")
16035                      (reg:DI SP_REG)]
16036                     UNSPEC_TLSDESC)
16037          (const:DI (unspec:DI
16038                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16039                     UNSPEC_DTPOFF))))
16040    (clobber (reg:CC FLAGS_REG))]
16041   "TARGET_64BIT && TARGET_GNU2_TLS"
16042   "#"
16043   ""
16044   [(set (match_dup 0) (match_dup 4))]
16045 {
16046   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16047   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16048 })
16049
16050 ;;
16051 \f
16052 ;; These patterns match the binary 387 instructions for addM3, subM3,
16053 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16054 ;; SFmode.  The first is the normal insn, the second the same insn but
16055 ;; with one operand a conversion, and the third the same insn but with
16056 ;; the other operand a conversion.  The conversion may be SFmode or
16057 ;; SImode if the target mode DFmode, but only SImode if the target mode
16058 ;; is SFmode.
16059
16060 ;; Gcc is slightly more smart about handling normal two address instructions
16061 ;; so use special patterns for add and mull.
16062
16063 (define_insn "*fop_sf_comm_mixed"
16064   [(set (match_operand:SF 0 "register_operand" "=f,x")
16065         (match_operator:SF 3 "binary_fp_operator"
16066                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
16067                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
16068   "TARGET_MIX_SSE_I387
16069    && COMMUTATIVE_ARITH_P (operands[3])
16070    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16071   "* return output_387_binary_op (insn, operands);"
16072   [(set (attr "type")
16073         (if_then_else (eq_attr "alternative" "1")
16074            (if_then_else (match_operand:SF 3 "mult_operator" "")
16075               (const_string "ssemul")
16076               (const_string "sseadd"))
16077            (if_then_else (match_operand:SF 3 "mult_operator" "")
16078               (const_string "fmul")
16079               (const_string "fop"))))
16080    (set_attr "mode" "SF")])
16081
16082 (define_insn "*fop_sf_comm_sse"
16083   [(set (match_operand:SF 0 "register_operand" "=x")
16084         (match_operator:SF 3 "binary_fp_operator"
16085                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
16086                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16087   "TARGET_SSE_MATH
16088    && COMMUTATIVE_ARITH_P (operands[3])
16089    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16090   "* return output_387_binary_op (insn, operands);"
16091   [(set (attr "type")
16092         (if_then_else (match_operand:SF 3 "mult_operator" "")
16093            (const_string "ssemul")
16094            (const_string "sseadd")))
16095    (set_attr "mode" "SF")])
16096
16097 (define_insn "*fop_sf_comm_i387"
16098   [(set (match_operand:SF 0 "register_operand" "=f")
16099         (match_operator:SF 3 "binary_fp_operator"
16100                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
16101                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
16102   "TARGET_80387
16103    && COMMUTATIVE_ARITH_P (operands[3])
16104    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16105   "* return output_387_binary_op (insn, operands);"
16106   [(set (attr "type")
16107         (if_then_else (match_operand:SF 3 "mult_operator" "")
16108            (const_string "fmul")
16109            (const_string "fop")))
16110    (set_attr "mode" "SF")])
16111
16112 (define_insn "*fop_sf_1_mixed"
16113   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16114         (match_operator:SF 3 "binary_fp_operator"
16115                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16116                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16117   "TARGET_MIX_SSE_I387
16118    && !COMMUTATIVE_ARITH_P (operands[3])
16119    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16120   "* return output_387_binary_op (insn, operands);"
16121   [(set (attr "type")
16122         (cond [(and (eq_attr "alternative" "2")
16123                     (match_operand:SF 3 "mult_operator" ""))
16124                  (const_string "ssemul")
16125                (and (eq_attr "alternative" "2")
16126                     (match_operand:SF 3 "div_operator" ""))
16127                  (const_string "ssediv")
16128                (eq_attr "alternative" "2")
16129                  (const_string "sseadd")
16130                (match_operand:SF 3 "mult_operator" "")
16131                  (const_string "fmul")
16132                (match_operand:SF 3 "div_operator" "")
16133                  (const_string "fdiv")
16134               ]
16135               (const_string "fop")))
16136    (set_attr "mode" "SF")])
16137
16138 (define_insn "*rcpsf2_sse"
16139   [(set (match_operand:SF 0 "register_operand" "=x")
16140         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16141                    UNSPEC_RCP))]
16142   "TARGET_SSE_MATH"
16143   "rcpss\t{%1, %0|%0, %1}"
16144   [(set_attr "type" "sse")
16145    (set_attr "mode" "SF")])
16146
16147 (define_insn "*fop_sf_1_sse"
16148   [(set (match_operand:SF 0 "register_operand" "=x")
16149         (match_operator:SF 3 "binary_fp_operator"
16150                         [(match_operand:SF 1 "register_operand" "0")
16151                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16152   "TARGET_SSE_MATH
16153    && !COMMUTATIVE_ARITH_P (operands[3])"
16154   "* return output_387_binary_op (insn, operands);"
16155   [(set (attr "type")
16156         (cond [(match_operand:SF 3 "mult_operator" "")
16157                  (const_string "ssemul")
16158                (match_operand:SF 3 "div_operator" "")
16159                  (const_string "ssediv")
16160               ]
16161               (const_string "sseadd")))
16162    (set_attr "mode" "SF")])
16163
16164 ;; This pattern is not fully shadowed by the pattern above.
16165 (define_insn "*fop_sf_1_i387"
16166   [(set (match_operand:SF 0 "register_operand" "=f,f")
16167         (match_operator:SF 3 "binary_fp_operator"
16168                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16169                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16170   "TARGET_80387 && !TARGET_SSE_MATH
16171    && !COMMUTATIVE_ARITH_P (operands[3])
16172    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16173   "* return output_387_binary_op (insn, operands);"
16174   [(set (attr "type")
16175         (cond [(match_operand:SF 3 "mult_operator" "")
16176                  (const_string "fmul")
16177                (match_operand:SF 3 "div_operator" "")
16178                  (const_string "fdiv")
16179               ]
16180               (const_string "fop")))
16181    (set_attr "mode" "SF")])
16182
16183 ;; ??? Add SSE splitters for these!
16184 (define_insn "*fop_sf_2<mode>_i387"
16185   [(set (match_operand:SF 0 "register_operand" "=f,f")
16186         (match_operator:SF 3 "binary_fp_operator"
16187           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16188            (match_operand:SF 2 "register_operand" "0,0")]))]
16189   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16190   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16191   [(set (attr "type")
16192         (cond [(match_operand:SF 3 "mult_operator" "")
16193                  (const_string "fmul")
16194                (match_operand:SF 3 "div_operator" "")
16195                  (const_string "fdiv")
16196               ]
16197               (const_string "fop")))
16198    (set_attr "fp_int_src" "true")
16199    (set_attr "mode" "<MODE>")])
16200
16201 (define_insn "*fop_sf_3<mode>_i387"
16202   [(set (match_operand:SF 0 "register_operand" "=f,f")
16203         (match_operator:SF 3 "binary_fp_operator"
16204           [(match_operand:SF 1 "register_operand" "0,0")
16205            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16206   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16207   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16208   [(set (attr "type")
16209         (cond [(match_operand:SF 3 "mult_operator" "")
16210                  (const_string "fmul")
16211                (match_operand:SF 3 "div_operator" "")
16212                  (const_string "fdiv")
16213               ]
16214               (const_string "fop")))
16215    (set_attr "fp_int_src" "true")
16216    (set_attr "mode" "<MODE>")])
16217
16218 (define_insn "*fop_df_comm_mixed"
16219   [(set (match_operand:DF 0 "register_operand" "=f,x")
16220         (match_operator:DF 3 "binary_fp_operator"
16221           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16222            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16223   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16224    && COMMUTATIVE_ARITH_P (operands[3])
16225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16226   "* return output_387_binary_op (insn, operands);"
16227   [(set (attr "type")
16228         (if_then_else (eq_attr "alternative" "1")
16229            (if_then_else (match_operand:DF 3 "mult_operator" "")
16230               (const_string "ssemul")
16231               (const_string "sseadd"))
16232            (if_then_else (match_operand:DF 3 "mult_operator" "")
16233               (const_string "fmul")
16234               (const_string "fop"))))
16235    (set_attr "mode" "DF")])
16236
16237 (define_insn "*fop_df_comm_sse"
16238   [(set (match_operand:DF 0 "register_operand" "=x")
16239         (match_operator:DF 3 "binary_fp_operator"
16240           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16241            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16242   "TARGET_SSE2 && TARGET_SSE_MATH
16243    && COMMUTATIVE_ARITH_P (operands[3])
16244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16245   "* return output_387_binary_op (insn, operands);"
16246   [(set (attr "type")
16247         (if_then_else (match_operand:DF 3 "mult_operator" "")
16248            (const_string "ssemul")
16249            (const_string "sseadd")))
16250    (set_attr "mode" "DF")])
16251
16252 (define_insn "*fop_df_comm_i387"
16253   [(set (match_operand:DF 0 "register_operand" "=f")
16254         (match_operator:DF 3 "binary_fp_operator"
16255                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16256                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16257   "TARGET_80387
16258    && COMMUTATIVE_ARITH_P (operands[3])
16259    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16260   "* return output_387_binary_op (insn, operands);"
16261   [(set (attr "type")
16262         (if_then_else (match_operand:DF 3 "mult_operator" "")
16263            (const_string "fmul")
16264            (const_string "fop")))
16265    (set_attr "mode" "DF")])
16266
16267 (define_insn "*fop_df_1_mixed"
16268   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16269         (match_operator:DF 3 "binary_fp_operator"
16270           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16271            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16272   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16273    && !COMMUTATIVE_ARITH_P (operands[3])
16274    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16275   "* return output_387_binary_op (insn, operands);"
16276   [(set (attr "type")
16277         (cond [(and (eq_attr "alternative" "2")
16278                     (match_operand:DF 3 "mult_operator" ""))
16279                  (const_string "ssemul")
16280                (and (eq_attr "alternative" "2")
16281                     (match_operand:DF 3 "div_operator" ""))
16282                  (const_string "ssediv")
16283                (eq_attr "alternative" "2")
16284                  (const_string "sseadd")
16285                (match_operand:DF 3 "mult_operator" "")
16286                  (const_string "fmul")
16287                (match_operand:DF 3 "div_operator" "")
16288                  (const_string "fdiv")
16289               ]
16290               (const_string "fop")))
16291    (set_attr "mode" "DF")])
16292
16293 (define_insn "*fop_df_1_sse"
16294   [(set (match_operand:DF 0 "register_operand" "=x")
16295         (match_operator:DF 3 "binary_fp_operator"
16296           [(match_operand:DF 1 "register_operand" "0")
16297            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16298   "TARGET_SSE2 && TARGET_SSE_MATH
16299    && !COMMUTATIVE_ARITH_P (operands[3])"
16300   "* return output_387_binary_op (insn, operands);"
16301   [(set_attr "mode" "DF")
16302    (set (attr "type")
16303         (cond [(match_operand:DF 3 "mult_operator" "")
16304                  (const_string "ssemul")
16305                (match_operand:DF 3 "div_operator" "")
16306                  (const_string "ssediv")
16307               ]
16308               (const_string "sseadd")))])
16309
16310 ;; This pattern is not fully shadowed by the pattern above.
16311 (define_insn "*fop_df_1_i387"
16312   [(set (match_operand:DF 0 "register_operand" "=f,f")
16313         (match_operator:DF 3 "binary_fp_operator"
16314                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16315                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16316   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16317    && !COMMUTATIVE_ARITH_P (operands[3])
16318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16319   "* return output_387_binary_op (insn, operands);"
16320   [(set (attr "type")
16321         (cond [(match_operand:DF 3 "mult_operator" "")
16322                  (const_string "fmul")
16323                (match_operand:DF 3 "div_operator" "")
16324                  (const_string "fdiv")
16325               ]
16326               (const_string "fop")))
16327    (set_attr "mode" "DF")])
16328
16329 ;; ??? Add SSE splitters for these!
16330 (define_insn "*fop_df_2<mode>_i387"
16331   [(set (match_operand:DF 0 "register_operand" "=f,f")
16332         (match_operator:DF 3 "binary_fp_operator"
16333            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16334             (match_operand:DF 2 "register_operand" "0,0")]))]
16335   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16336    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16337   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16338   [(set (attr "type")
16339         (cond [(match_operand:DF 3 "mult_operator" "")
16340                  (const_string "fmul")
16341                (match_operand:DF 3 "div_operator" "")
16342                  (const_string "fdiv")
16343               ]
16344               (const_string "fop")))
16345    (set_attr "fp_int_src" "true")
16346    (set_attr "mode" "<MODE>")])
16347
16348 (define_insn "*fop_df_3<mode>_i387"
16349   [(set (match_operand:DF 0 "register_operand" "=f,f")
16350         (match_operator:DF 3 "binary_fp_operator"
16351            [(match_operand:DF 1 "register_operand" "0,0")
16352             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16353   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16354    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16355   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16356   [(set (attr "type")
16357         (cond [(match_operand:DF 3 "mult_operator" "")
16358                  (const_string "fmul")
16359                (match_operand:DF 3 "div_operator" "")
16360                  (const_string "fdiv")
16361               ]
16362               (const_string "fop")))
16363    (set_attr "fp_int_src" "true")
16364    (set_attr "mode" "<MODE>")])
16365
16366 (define_insn "*fop_df_4_i387"
16367   [(set (match_operand:DF 0 "register_operand" "=f,f")
16368         (match_operator:DF 3 "binary_fp_operator"
16369            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16370             (match_operand:DF 2 "register_operand" "0,f")]))]
16371   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16372    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16373   "* return output_387_binary_op (insn, operands);"
16374   [(set (attr "type")
16375         (cond [(match_operand:DF 3 "mult_operator" "")
16376                  (const_string "fmul")
16377                (match_operand:DF 3 "div_operator" "")
16378                  (const_string "fdiv")
16379               ]
16380               (const_string "fop")))
16381    (set_attr "mode" "SF")])
16382
16383 (define_insn "*fop_df_5_i387"
16384   [(set (match_operand:DF 0 "register_operand" "=f,f")
16385         (match_operator:DF 3 "binary_fp_operator"
16386           [(match_operand:DF 1 "register_operand" "0,f")
16387            (float_extend:DF
16388             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16389   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16390   "* return output_387_binary_op (insn, operands);"
16391   [(set (attr "type")
16392         (cond [(match_operand:DF 3 "mult_operator" "")
16393                  (const_string "fmul")
16394                (match_operand:DF 3 "div_operator" "")
16395                  (const_string "fdiv")
16396               ]
16397               (const_string "fop")))
16398    (set_attr "mode" "SF")])
16399
16400 (define_insn "*fop_df_6_i387"
16401   [(set (match_operand:DF 0 "register_operand" "=f,f")
16402         (match_operator:DF 3 "binary_fp_operator"
16403           [(float_extend:DF
16404             (match_operand:SF 1 "register_operand" "0,f"))
16405            (float_extend:DF
16406             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16407   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16408   "* return output_387_binary_op (insn, operands);"
16409   [(set (attr "type")
16410         (cond [(match_operand:DF 3 "mult_operator" "")
16411                  (const_string "fmul")
16412                (match_operand:DF 3 "div_operator" "")
16413                  (const_string "fdiv")
16414               ]
16415               (const_string "fop")))
16416    (set_attr "mode" "SF")])
16417
16418 (define_insn "*fop_xf_comm_i387"
16419   [(set (match_operand:XF 0 "register_operand" "=f")
16420         (match_operator:XF 3 "binary_fp_operator"
16421                         [(match_operand:XF 1 "register_operand" "%0")
16422                          (match_operand:XF 2 "register_operand" "f")]))]
16423   "TARGET_80387
16424    && COMMUTATIVE_ARITH_P (operands[3])"
16425   "* return output_387_binary_op (insn, operands);"
16426   [(set (attr "type")
16427         (if_then_else (match_operand:XF 3 "mult_operator" "")
16428            (const_string "fmul")
16429            (const_string "fop")))
16430    (set_attr "mode" "XF")])
16431
16432 (define_insn "*fop_xf_1_i387"
16433   [(set (match_operand:XF 0 "register_operand" "=f,f")
16434         (match_operator:XF 3 "binary_fp_operator"
16435                         [(match_operand:XF 1 "register_operand" "0,f")
16436                          (match_operand:XF 2 "register_operand" "f,0")]))]
16437   "TARGET_80387
16438    && !COMMUTATIVE_ARITH_P (operands[3])"
16439   "* return output_387_binary_op (insn, operands);"
16440   [(set (attr "type")
16441         (cond [(match_operand:XF 3 "mult_operator" "")
16442                  (const_string "fmul")
16443                (match_operand:XF 3 "div_operator" "")
16444                  (const_string "fdiv")
16445               ]
16446               (const_string "fop")))
16447    (set_attr "mode" "XF")])
16448
16449 (define_insn "*fop_xf_2<mode>_i387"
16450   [(set (match_operand:XF 0 "register_operand" "=f,f")
16451         (match_operator:XF 3 "binary_fp_operator"
16452            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16453             (match_operand:XF 2 "register_operand" "0,0")]))]
16454   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16455   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16456   [(set (attr "type")
16457         (cond [(match_operand:XF 3 "mult_operator" "")
16458                  (const_string "fmul")
16459                (match_operand:XF 3 "div_operator" "")
16460                  (const_string "fdiv")
16461               ]
16462               (const_string "fop")))
16463    (set_attr "fp_int_src" "true")
16464    (set_attr "mode" "<MODE>")])
16465
16466 (define_insn "*fop_xf_3<mode>_i387"
16467   [(set (match_operand:XF 0 "register_operand" "=f,f")
16468         (match_operator:XF 3 "binary_fp_operator"
16469           [(match_operand:XF 1 "register_operand" "0,0")
16470            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16471   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16472   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16473   [(set (attr "type")
16474         (cond [(match_operand:XF 3 "mult_operator" "")
16475                  (const_string "fmul")
16476                (match_operand:XF 3 "div_operator" "")
16477                  (const_string "fdiv")
16478               ]
16479               (const_string "fop")))
16480    (set_attr "fp_int_src" "true")
16481    (set_attr "mode" "<MODE>")])
16482
16483 (define_insn "*fop_xf_4_i387"
16484   [(set (match_operand:XF 0 "register_operand" "=f,f")
16485         (match_operator:XF 3 "binary_fp_operator"
16486            [(float_extend:XF
16487               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16488             (match_operand:XF 2 "register_operand" "0,f")]))]
16489   "TARGET_80387"
16490   "* return output_387_binary_op (insn, operands);"
16491   [(set (attr "type")
16492         (cond [(match_operand:XF 3 "mult_operator" "")
16493                  (const_string "fmul")
16494                (match_operand:XF 3 "div_operator" "")
16495                  (const_string "fdiv")
16496               ]
16497               (const_string "fop")))
16498    (set_attr "mode" "SF")])
16499
16500 (define_insn "*fop_xf_5_i387"
16501   [(set (match_operand:XF 0 "register_operand" "=f,f")
16502         (match_operator:XF 3 "binary_fp_operator"
16503           [(match_operand:XF 1 "register_operand" "0,f")
16504            (float_extend:XF
16505              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16506   "TARGET_80387"
16507   "* return output_387_binary_op (insn, operands);"
16508   [(set (attr "type")
16509         (cond [(match_operand:XF 3 "mult_operator" "")
16510                  (const_string "fmul")
16511                (match_operand:XF 3 "div_operator" "")
16512                  (const_string "fdiv")
16513               ]
16514               (const_string "fop")))
16515    (set_attr "mode" "SF")])
16516
16517 (define_insn "*fop_xf_6_i387"
16518   [(set (match_operand:XF 0 "register_operand" "=f,f")
16519         (match_operator:XF 3 "binary_fp_operator"
16520           [(float_extend:XF
16521              (match_operand:MODEF 1 "register_operand" "0,f"))
16522            (float_extend:XF
16523              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16524   "TARGET_80387"
16525   "* return output_387_binary_op (insn, operands);"
16526   [(set (attr "type")
16527         (cond [(match_operand:XF 3 "mult_operator" "")
16528                  (const_string "fmul")
16529                (match_operand:XF 3 "div_operator" "")
16530                  (const_string "fdiv")
16531               ]
16532               (const_string "fop")))
16533    (set_attr "mode" "SF")])
16534
16535 (define_split
16536   [(set (match_operand 0 "register_operand" "")
16537         (match_operator 3 "binary_fp_operator"
16538            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16539             (match_operand 2 "register_operand" "")]))]
16540   "reload_completed
16541    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16542   [(const_int 0)]
16543 {
16544   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16545   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16546   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16547                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16548                                           GET_MODE (operands[3]),
16549                                           operands[4],
16550                                           operands[2])));
16551   ix86_free_from_memory (GET_MODE (operands[1]));
16552   DONE;
16553 })
16554
16555 (define_split
16556   [(set (match_operand 0 "register_operand" "")
16557         (match_operator 3 "binary_fp_operator"
16558            [(match_operand 1 "register_operand" "")
16559             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16560   "reload_completed
16561    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16562   [(const_int 0)]
16563 {
16564   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16565   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16566   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16567                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16568                                           GET_MODE (operands[3]),
16569                                           operands[1],
16570                                           operands[4])));
16571   ix86_free_from_memory (GET_MODE (operands[2]));
16572   DONE;
16573 })
16574 \f
16575 ;; FPU special functions.
16576
16577 ;; This pattern implements a no-op XFmode truncation for
16578 ;; all fancy i386 XFmode math functions.
16579
16580 (define_insn "truncxf<mode>2_i387_noop_unspec"
16581   [(set (match_operand:MODEF 0 "register_operand" "=f")
16582         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16583         UNSPEC_TRUNC_NOOP))]
16584   "TARGET_USE_FANCY_MATH_387"
16585   "* return output_387_reg_move (insn, operands);"
16586   [(set_attr "type" "fmov")
16587    (set_attr "mode" "<MODE>")])
16588
16589 (define_insn "sqrtxf2"
16590   [(set (match_operand:XF 0 "register_operand" "=f")
16591         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16592   "TARGET_USE_FANCY_MATH_387"
16593   "fsqrt"
16594   [(set_attr "type" "fpspc")
16595    (set_attr "mode" "XF")
16596    (set_attr "athlon_decode" "direct")
16597    (set_attr "amdfam10_decode" "direct")])
16598
16599 (define_insn "sqrt_extend<mode>xf2_i387"
16600   [(set (match_operand:XF 0 "register_operand" "=f")
16601         (sqrt:XF
16602           (float_extend:XF
16603             (match_operand:MODEF 1 "register_operand" "0"))))]
16604   "TARGET_USE_FANCY_MATH_387"
16605   "fsqrt"
16606   [(set_attr "type" "fpspc")
16607    (set_attr "mode" "XF")
16608    (set_attr "athlon_decode" "direct")   
16609    (set_attr "amdfam10_decode" "direct")])
16610
16611 (define_insn "*rsqrtsf2_sse"
16612   [(set (match_operand:SF 0 "register_operand" "=x")
16613         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16614                    UNSPEC_RSQRT))]
16615   "TARGET_SSE_MATH"
16616   "rsqrtss\t{%1, %0|%0, %1}"
16617   [(set_attr "type" "sse")
16618    (set_attr "mode" "SF")])
16619
16620 (define_expand "rsqrtsf2"
16621   [(set (match_operand:SF 0 "register_operand" "")
16622         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16623                    UNSPEC_RSQRT))]
16624   "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16625    && flag_finite_math_only && !flag_trapping_math
16626    && flag_unsafe_math_optimizations"
16627 {
16628   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16629   DONE;
16630 })
16631
16632 (define_insn "*sqrt<mode>2_sse"
16633   [(set (match_operand:MODEF 0 "register_operand" "=x")
16634         (sqrt:MODEF
16635           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16636   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16637   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16638   [(set_attr "type" "sse")
16639    (set_attr "mode" "<MODE>")
16640    (set_attr "athlon_decode" "*")
16641    (set_attr "amdfam10_decode" "*")])
16642
16643 (define_expand "sqrt<mode>2"
16644   [(set (match_operand:MODEF 0 "register_operand" "")
16645         (sqrt:MODEF
16646           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16647   "TARGET_USE_FANCY_MATH_387
16648    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16649 {
16650   if (<MODE>mode == SFmode
16651       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16652       && flag_finite_math_only && !flag_trapping_math
16653       && flag_unsafe_math_optimizations)
16654     {
16655       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16656       DONE;
16657     }
16658
16659   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16660     {
16661       rtx op0 = gen_reg_rtx (XFmode);
16662       rtx op1 = force_reg (<MODE>mode, operands[1]);
16663
16664       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16665       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16666       DONE;
16667    }
16668 })
16669
16670 (define_insn "fpremxf4_i387"
16671   [(set (match_operand:XF 0 "register_operand" "=f")
16672         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16673                     (match_operand:XF 3 "register_operand" "1")]
16674                    UNSPEC_FPREM_F))
16675    (set (match_operand:XF 1 "register_operand" "=u")
16676         (unspec:XF [(match_dup 2) (match_dup 3)]
16677                    UNSPEC_FPREM_U))
16678    (set (reg:CCFP FPSR_REG)
16679         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16680                      UNSPEC_C2_FLAG))]
16681   "TARGET_USE_FANCY_MATH_387"
16682   "fprem"
16683   [(set_attr "type" "fpspc")
16684    (set_attr "mode" "XF")])
16685
16686 (define_expand "fmodxf3"
16687   [(use (match_operand:XF 0 "register_operand" ""))
16688    (use (match_operand:XF 1 "register_operand" ""))
16689    (use (match_operand:XF 2 "register_operand" ""))]
16690   "TARGET_USE_FANCY_MATH_387"
16691 {
16692   rtx label = gen_label_rtx ();
16693
16694   rtx op2;
16695
16696   if (rtx_equal_p (operands[1], operands[2]))
16697     {
16698       op2 = gen_reg_rtx (XFmode);
16699       emit_move_insn (op2, operands[2]);
16700     }
16701   else
16702     op2 = operands[2];
16703
16704   emit_label (label);
16705   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16706   ix86_emit_fp_unordered_jump (label);
16707   LABEL_NUSES (label) = 1;
16708
16709   emit_move_insn (operands[0], operands[1]);
16710   DONE;
16711 })
16712
16713 (define_expand "fmod<mode>3"
16714   [(use (match_operand:MODEF 0 "register_operand" ""))
16715    (use (match_operand:MODEF 1 "general_operand" ""))
16716    (use (match_operand:MODEF 2 "general_operand" ""))]
16717   "TARGET_USE_FANCY_MATH_387"
16718 {
16719   rtx label = gen_label_rtx ();
16720
16721   rtx op1 = gen_reg_rtx (XFmode);
16722   rtx op2 = gen_reg_rtx (XFmode);
16723
16724   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16725   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16726
16727   emit_label (label);
16728   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16729   ix86_emit_fp_unordered_jump (label);
16730   LABEL_NUSES (label) = 1;
16731
16732   /* Truncate the result properly for strict SSE math.  */
16733   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16734       && !TARGET_MIX_SSE_I387)
16735     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16736   else
16737     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16738
16739   DONE;
16740 })
16741
16742 (define_insn "fprem1xf4_i387"
16743   [(set (match_operand:XF 0 "register_operand" "=f")
16744         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16745                     (match_operand:XF 3 "register_operand" "1")]
16746                    UNSPEC_FPREM1_F))
16747    (set (match_operand:XF 1 "register_operand" "=u")
16748         (unspec:XF [(match_dup 2) (match_dup 3)]
16749                    UNSPEC_FPREM1_U))
16750    (set (reg:CCFP FPSR_REG)
16751         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16752                      UNSPEC_C2_FLAG))]
16753   "TARGET_USE_FANCY_MATH_387"
16754   "fprem1"
16755   [(set_attr "type" "fpspc")
16756    (set_attr "mode" "XF")])
16757
16758 (define_expand "remainderxf3"
16759   [(use (match_operand:XF 0 "register_operand" ""))
16760    (use (match_operand:XF 1 "register_operand" ""))
16761    (use (match_operand:XF 2 "register_operand" ""))]
16762   "TARGET_USE_FANCY_MATH_387"
16763 {
16764   rtx label = gen_label_rtx ();
16765
16766   rtx op2;
16767
16768   if (rtx_equal_p (operands[1], operands[2]))
16769     {
16770       op2 = gen_reg_rtx (XFmode);
16771       emit_move_insn (op2, operands[2]);
16772     }
16773   else
16774     op2 = operands[2];
16775
16776   emit_label (label);
16777   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16778   ix86_emit_fp_unordered_jump (label);
16779   LABEL_NUSES (label) = 1;
16780
16781   emit_move_insn (operands[0], operands[1]);
16782   DONE;
16783 })
16784
16785 (define_expand "remainder<mode>3"
16786   [(use (match_operand:MODEF 0 "register_operand" ""))
16787    (use (match_operand:MODEF 1 "general_operand" ""))
16788    (use (match_operand:MODEF 2 "general_operand" ""))]
16789   "TARGET_USE_FANCY_MATH_387"
16790 {
16791   rtx label = gen_label_rtx ();
16792
16793   rtx op1 = gen_reg_rtx (XFmode);
16794   rtx op2 = gen_reg_rtx (XFmode);
16795
16796   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16797   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16798
16799   emit_label (label);
16800
16801   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16802   ix86_emit_fp_unordered_jump (label);
16803   LABEL_NUSES (label) = 1;
16804
16805   /* Truncate the result properly for strict SSE math.  */
16806   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16807       && !TARGET_MIX_SSE_I387)
16808     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16809   else
16810     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16811
16812   DONE;
16813 })
16814
16815 (define_insn "*sinxf2_i387"
16816   [(set (match_operand:XF 0 "register_operand" "=f")
16817         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16818   "TARGET_USE_FANCY_MATH_387
16819    && flag_unsafe_math_optimizations"
16820   "fsin"
16821   [(set_attr "type" "fpspc")
16822    (set_attr "mode" "XF")])
16823
16824 (define_insn "*sin_extend<mode>xf2_i387"
16825   [(set (match_operand:XF 0 "register_operand" "=f")
16826         (unspec:XF [(float_extend:XF
16827                       (match_operand:MODEF 1 "register_operand" "0"))]
16828                    UNSPEC_SIN))]
16829   "TARGET_USE_FANCY_MATH_387
16830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831        || TARGET_MIX_SSE_I387)
16832    && flag_unsafe_math_optimizations"
16833   "fsin"
16834   [(set_attr "type" "fpspc")
16835    (set_attr "mode" "XF")])
16836
16837 (define_insn "*cosxf2_i387"
16838   [(set (match_operand:XF 0 "register_operand" "=f")
16839         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "fcos"
16843   [(set_attr "type" "fpspc")
16844    (set_attr "mode" "XF")])
16845
16846 (define_insn "*cos_extend<mode>xf2_i387"
16847   [(set (match_operand:XF 0 "register_operand" "=f")
16848         (unspec:XF [(float_extend:XF
16849                       (match_operand:MODEF 1 "register_operand" "0"))]
16850                    UNSPEC_COS))]
16851   "TARGET_USE_FANCY_MATH_387
16852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853        || TARGET_MIX_SSE_I387)
16854    && flag_unsafe_math_optimizations"
16855   "fcos"
16856   [(set_attr "type" "fpspc")
16857    (set_attr "mode" "XF")])
16858
16859 ;; When sincos pattern is defined, sin and cos builtin functions will be
16860 ;; expanded to sincos pattern with one of its outputs left unused.
16861 ;; CSE pass will figure out if two sincos patterns can be combined,
16862 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16863 ;; depending on the unused output.
16864
16865 (define_insn "sincosxf3"
16866   [(set (match_operand:XF 0 "register_operand" "=f")
16867         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16868                    UNSPEC_SINCOS_COS))
16869    (set (match_operand:XF 1 "register_operand" "=u")
16870         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16871   "TARGET_USE_FANCY_MATH_387
16872    && flag_unsafe_math_optimizations"
16873   "fsincos"
16874   [(set_attr "type" "fpspc")
16875    (set_attr "mode" "XF")])
16876
16877 (define_split
16878   [(set (match_operand:XF 0 "register_operand" "")
16879         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16880                    UNSPEC_SINCOS_COS))
16881    (set (match_operand:XF 1 "register_operand" "")
16882         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16883   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16884    && !(reload_completed || reload_in_progress)"
16885   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16886   "")
16887
16888 (define_split
16889   [(set (match_operand:XF 0 "register_operand" "")
16890         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16891                    UNSPEC_SINCOS_COS))
16892    (set (match_operand:XF 1 "register_operand" "")
16893         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16894   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16895    && !(reload_completed || reload_in_progress)"
16896   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16897   "")
16898
16899 (define_insn "sincos_extend<mode>xf3_i387"
16900   [(set (match_operand:XF 0 "register_operand" "=f")
16901         (unspec:XF [(float_extend:XF
16902                       (match_operand:MODEF 2 "register_operand" "0"))]
16903                    UNSPEC_SINCOS_COS))
16904    (set (match_operand:XF 1 "register_operand" "=u")
16905         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908        || TARGET_MIX_SSE_I387)
16909    && flag_unsafe_math_optimizations"
16910   "fsincos"
16911   [(set_attr "type" "fpspc")
16912    (set_attr "mode" "XF")])
16913
16914 (define_split
16915   [(set (match_operand:XF 0 "register_operand" "")
16916         (unspec:XF [(float_extend:XF
16917                       (match_operand:MODEF 2 "register_operand" ""))]
16918                    UNSPEC_SINCOS_COS))
16919    (set (match_operand:XF 1 "register_operand" "")
16920         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16921   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16922    && !(reload_completed || reload_in_progress)"
16923   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16924   "")
16925
16926 (define_split
16927   [(set (match_operand:XF 0 "register_operand" "")
16928         (unspec:XF [(float_extend:XF
16929                       (match_operand:MODEF 2 "register_operand" ""))]
16930                    UNSPEC_SINCOS_COS))
16931    (set (match_operand:XF 1 "register_operand" "")
16932         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16933   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16934    && !(reload_completed || reload_in_progress)"
16935   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16936   "")
16937
16938 (define_expand "sincos<mode>3"
16939   [(use (match_operand:MODEF 0 "register_operand" ""))
16940    (use (match_operand:MODEF 1 "register_operand" ""))
16941    (use (match_operand:MODEF 2 "register_operand" ""))]
16942   "TARGET_USE_FANCY_MATH_387
16943    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944        || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16946 {
16947   rtx op0 = gen_reg_rtx (XFmode);
16948   rtx op1 = gen_reg_rtx (XFmode);
16949
16950   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16951   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16952   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16953   DONE;
16954 })
16955
16956 (define_insn "fptanxf4_i387"
16957   [(set (match_operand:XF 0 "register_operand" "=f")
16958         (match_operand:XF 3 "const_double_operand" "F"))
16959    (set (match_operand:XF 1 "register_operand" "=u")
16960         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16961                    UNSPEC_TAN))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && flag_unsafe_math_optimizations
16964    && standard_80387_constant_p (operands[3]) == 2"
16965   "fptan"
16966   [(set_attr "type" "fpspc")
16967    (set_attr "mode" "XF")])
16968
16969 (define_insn "fptan_extend<mode>xf4_i387"
16970   [(set (match_operand:MODEF 0 "register_operand" "=f")
16971         (match_operand:MODEF 3 "const_double_operand" "F"))
16972    (set (match_operand:XF 1 "register_operand" "=u")
16973         (unspec:XF [(float_extend:XF
16974                       (match_operand:MODEF 2 "register_operand" "0"))]
16975                    UNSPEC_TAN))]
16976   "TARGET_USE_FANCY_MATH_387
16977    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16978        || TARGET_MIX_SSE_I387)
16979    && flag_unsafe_math_optimizations
16980    && standard_80387_constant_p (operands[3]) == 2"
16981   "fptan"
16982   [(set_attr "type" "fpspc")
16983    (set_attr "mode" "XF")])
16984
16985 (define_expand "tanxf2"
16986   [(use (match_operand:XF 0 "register_operand" ""))
16987    (use (match_operand:XF 1 "register_operand" ""))]
16988   "TARGET_USE_FANCY_MATH_387
16989    && flag_unsafe_math_optimizations"
16990 {
16991   rtx one = gen_reg_rtx (XFmode);
16992   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16993
16994   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16995   DONE;
16996 })
16997
16998 (define_expand "tan<mode>2"
16999   [(use (match_operand:MODEF 0 "register_operand" ""))
17000    (use (match_operand:MODEF 1 "register_operand" ""))]
17001   "TARGET_USE_FANCY_MATH_387
17002    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17003        || TARGET_MIX_SSE_I387)
17004    && flag_unsafe_math_optimizations"
17005 {
17006   rtx op0 = gen_reg_rtx (XFmode);
17007
17008   rtx one = gen_reg_rtx (<MODE>mode);
17009   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17010
17011   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17012                                              operands[1], op2));
17013   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17014   DONE;
17015 })
17016
17017 (define_insn "*fpatanxf3_i387"
17018   [(set (match_operand:XF 0 "register_operand" "=f")
17019         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17020                     (match_operand:XF 2 "register_operand" "u")]
17021                    UNSPEC_FPATAN))
17022    (clobber (match_scratch:XF 3 "=2"))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && flag_unsafe_math_optimizations"
17025   "fpatan"
17026   [(set_attr "type" "fpspc")
17027    (set_attr "mode" "XF")])
17028
17029 (define_insn "fpatan_extend<mode>xf3_i387"
17030   [(set (match_operand:XF 0 "register_operand" "=f")
17031         (unspec:XF [(float_extend:XF
17032                       (match_operand:MODEF 1 "register_operand" "0"))
17033                     (float_extend:XF
17034                       (match_operand:MODEF 2 "register_operand" "u"))]
17035                    UNSPEC_FPATAN))
17036    (clobber (match_scratch:XF 3 "=2"))]
17037   "TARGET_USE_FANCY_MATH_387
17038    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17039        || TARGET_MIX_SSE_I387)
17040    && flag_unsafe_math_optimizations"
17041   "fpatan"
17042   [(set_attr "type" "fpspc")
17043    (set_attr "mode" "XF")])
17044
17045 (define_expand "atan2xf3"
17046   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17047                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17048                                (match_operand:XF 1 "register_operand" "")]
17049                               UNSPEC_FPATAN))
17050               (clobber (match_scratch:XF 3 ""))])]
17051   "TARGET_USE_FANCY_MATH_387
17052    && flag_unsafe_math_optimizations"
17053   "")
17054
17055 (define_expand "atan2<mode>3"
17056   [(use (match_operand:MODEF 0 "register_operand" ""))
17057    (use (match_operand:MODEF 1 "register_operand" ""))
17058    (use (match_operand:MODEF 2 "register_operand" ""))]
17059   "TARGET_USE_FANCY_MATH_387
17060    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17061        || TARGET_MIX_SSE_I387)
17062    && flag_unsafe_math_optimizations"
17063 {
17064   rtx op0 = gen_reg_rtx (XFmode);
17065
17066   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17067   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17068   DONE;
17069 })
17070
17071 (define_expand "atanxf2"
17072   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17073                    (unspec:XF [(match_dup 2)
17074                                (match_operand:XF 1 "register_operand" "")]
17075                               UNSPEC_FPATAN))
17076               (clobber (match_scratch:XF 3 ""))])]
17077   "TARGET_USE_FANCY_MATH_387
17078    && flag_unsafe_math_optimizations"
17079 {
17080   operands[2] = gen_reg_rtx (XFmode);
17081   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17082 })
17083
17084 (define_expand "atan<mode>2"
17085   [(use (match_operand:MODEF 0 "register_operand" ""))
17086    (use (match_operand:MODEF 1 "register_operand" ""))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17089        || TARGET_MIX_SSE_I387)
17090    && flag_unsafe_math_optimizations"
17091 {
17092   rtx op0 = gen_reg_rtx (XFmode);
17093
17094   rtx op2 = gen_reg_rtx (<MODE>mode);
17095   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17096
17097   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17098   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17099   DONE;
17100 })
17101
17102 (define_expand "asinxf2"
17103   [(set (match_dup 2)
17104         (mult:XF (match_operand:XF 1 "register_operand" "")
17105                  (match_dup 1)))
17106    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17107    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17108    (parallel [(set (match_operand:XF 0 "register_operand" "")
17109                    (unspec:XF [(match_dup 5) (match_dup 1)]
17110                               UNSPEC_FPATAN))
17111               (clobber (match_scratch:XF 6 ""))])]
17112   "TARGET_USE_FANCY_MATH_387
17113    && flag_unsafe_math_optimizations && !optimize_size"
17114 {
17115   int i;
17116
17117   for (i = 2; i < 6; i++)
17118     operands[i] = gen_reg_rtx (XFmode);
17119
17120   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17121 })
17122
17123 (define_expand "asin<mode>2"
17124   [(use (match_operand:MODEF 0 "register_operand" ""))
17125    (use (match_operand:MODEF 1 "general_operand" ""))]
17126  "TARGET_USE_FANCY_MATH_387
17127    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17128        || TARGET_MIX_SSE_I387)
17129    && flag_unsafe_math_optimizations && !optimize_size"
17130 {
17131   rtx op0 = gen_reg_rtx (XFmode);
17132   rtx op1 = gen_reg_rtx (XFmode);
17133
17134   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17135   emit_insn (gen_asinxf2 (op0, op1));
17136   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17137   DONE;
17138 })
17139
17140 (define_expand "acosxf2"
17141   [(set (match_dup 2)
17142         (mult:XF (match_operand:XF 1 "register_operand" "")
17143                  (match_dup 1)))
17144    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17145    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17146    (parallel [(set (match_operand:XF 0 "register_operand" "")
17147                    (unspec:XF [(match_dup 1) (match_dup 5)]
17148                               UNSPEC_FPATAN))
17149               (clobber (match_scratch:XF 6 ""))])]
17150   "TARGET_USE_FANCY_MATH_387
17151    && flag_unsafe_math_optimizations && !optimize_size"
17152 {
17153   int i;
17154
17155   for (i = 2; i < 6; i++)
17156     operands[i] = gen_reg_rtx (XFmode);
17157
17158   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17159 })
17160
17161 (define_expand "acos<mode>2"
17162   [(use (match_operand:MODEF 0 "register_operand" ""))
17163    (use (match_operand:MODEF 1 "general_operand" ""))]
17164  "TARGET_USE_FANCY_MATH_387
17165    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17166        || TARGET_MIX_SSE_I387)
17167    && flag_unsafe_math_optimizations && !optimize_size"
17168 {
17169   rtx op0 = gen_reg_rtx (XFmode);
17170   rtx op1 = gen_reg_rtx (XFmode);
17171
17172   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17173   emit_insn (gen_acosxf2 (op0, op1));
17174   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17175   DONE;
17176 })
17177
17178 (define_insn "fyl2xxf3_i387"
17179   [(set (match_operand:XF 0 "register_operand" "=f")
17180         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17181                     (match_operand:XF 2 "register_operand" "u")]
17182                    UNSPEC_FYL2X))
17183    (clobber (match_scratch:XF 3 "=2"))]
17184   "TARGET_USE_FANCY_MATH_387
17185    && flag_unsafe_math_optimizations"
17186   "fyl2x"
17187   [(set_attr "type" "fpspc")
17188    (set_attr "mode" "XF")])
17189
17190 (define_insn "fyl2x_extend<mode>xf3_i387"
17191   [(set (match_operand:XF 0 "register_operand" "=f")
17192         (unspec:XF [(float_extend:XF
17193                       (match_operand:MODEF 1 "register_operand" "0"))
17194                     (match_operand:XF 2 "register_operand" "u")]
17195                    UNSPEC_FYL2X))
17196    (clobber (match_scratch:XF 3 "=2"))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17199        || TARGET_MIX_SSE_I387)
17200    && flag_unsafe_math_optimizations"
17201   "fyl2x"
17202   [(set_attr "type" "fpspc")
17203    (set_attr "mode" "XF")])
17204
17205 (define_expand "logxf2"
17206   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17207                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17208                                (match_dup 2)] UNSPEC_FYL2X))
17209               (clobber (match_scratch:XF 3 ""))])]
17210   "TARGET_USE_FANCY_MATH_387
17211    && flag_unsafe_math_optimizations"
17212 {
17213   operands[2] = gen_reg_rtx (XFmode);
17214   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17215 })
17216
17217 (define_expand "log<mode>2"
17218   [(use (match_operand:MODEF 0 "register_operand" ""))
17219    (use (match_operand:MODEF 1 "register_operand" ""))]
17220   "TARGET_USE_FANCY_MATH_387
17221    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17222        || TARGET_MIX_SSE_I387)
17223    && flag_unsafe_math_optimizations"
17224 {
17225   rtx op0 = gen_reg_rtx (XFmode);
17226
17227   rtx op2 = gen_reg_rtx (XFmode);
17228   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17229
17230   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17231   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17232   DONE;
17233 })
17234
17235 (define_expand "log10xf2"
17236   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17237                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17238                                (match_dup 2)] UNSPEC_FYL2X))
17239               (clobber (match_scratch:XF 3 ""))])]
17240   "TARGET_USE_FANCY_MATH_387
17241    && flag_unsafe_math_optimizations"
17242 {
17243   operands[2] = gen_reg_rtx (XFmode);
17244   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17245 })
17246
17247 (define_expand "log10<mode>2"
17248   [(use (match_operand:MODEF 0 "register_operand" ""))
17249    (use (match_operand:MODEF 1 "register_operand" ""))]
17250   "TARGET_USE_FANCY_MATH_387
17251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252        || TARGET_MIX_SSE_I387)
17253    && flag_unsafe_math_optimizations"
17254 {
17255   rtx op0 = gen_reg_rtx (XFmode);
17256
17257   rtx op2 = gen_reg_rtx (XFmode);
17258   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17259
17260   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17261   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17262   DONE;
17263 })
17264
17265 (define_expand "log2xf2"
17266   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17267                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17268                                (match_dup 2)] UNSPEC_FYL2X))
17269               (clobber (match_scratch:XF 3 ""))])]
17270   "TARGET_USE_FANCY_MATH_387
17271    && flag_unsafe_math_optimizations"
17272 {
17273   operands[2] = gen_reg_rtx (XFmode);
17274   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17275 })
17276
17277 (define_expand "log2<mode>2"
17278   [(use (match_operand:MODEF 0 "register_operand" ""))
17279    (use (match_operand:MODEF 1 "register_operand" ""))]
17280   "TARGET_USE_FANCY_MATH_387
17281    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17282        || TARGET_MIX_SSE_I387)
17283    && flag_unsafe_math_optimizations"
17284 {
17285   rtx op0 = gen_reg_rtx (XFmode);
17286
17287   rtx op2 = gen_reg_rtx (XFmode);
17288   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17289
17290   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17291   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17292   DONE;
17293 })
17294
17295 (define_insn "fyl2xp1xf3_i387"
17296   [(set (match_operand:XF 0 "register_operand" "=f")
17297         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17298                     (match_operand:XF 2 "register_operand" "u")]
17299                    UNSPEC_FYL2XP1))
17300    (clobber (match_scratch:XF 3 "=2"))]
17301   "TARGET_USE_FANCY_MATH_387
17302    && flag_unsafe_math_optimizations"
17303   "fyl2xp1"
17304   [(set_attr "type" "fpspc")
17305    (set_attr "mode" "XF")])
17306
17307 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17308   [(set (match_operand:XF 0 "register_operand" "=f")
17309         (unspec:XF [(float_extend:XF
17310                       (match_operand:MODEF 1 "register_operand" "0"))
17311                     (match_operand:XF 2 "register_operand" "u")]
17312                    UNSPEC_FYL2XP1))
17313    (clobber (match_scratch:XF 3 "=2"))]
17314   "TARGET_USE_FANCY_MATH_387
17315    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17316        || TARGET_MIX_SSE_I387)
17317    && flag_unsafe_math_optimizations"
17318   "fyl2xp1"
17319   [(set_attr "type" "fpspc")
17320    (set_attr "mode" "XF")])
17321
17322 (define_expand "log1pxf2"
17323   [(use (match_operand:XF 0 "register_operand" ""))
17324    (use (match_operand:XF 1 "register_operand" ""))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && flag_unsafe_math_optimizations && !optimize_size"
17327 {
17328   ix86_emit_i387_log1p (operands[0], operands[1]);
17329   DONE;
17330 })
17331
17332 (define_expand "log1p<mode>2"
17333   [(use (match_operand:MODEF 0 "register_operand" ""))
17334    (use (match_operand:MODEF 1 "register_operand" ""))]
17335   "TARGET_USE_FANCY_MATH_387
17336    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17337        || TARGET_MIX_SSE_I387)
17338    && flag_unsafe_math_optimizations && !optimize_size"
17339 {
17340   rtx op0 = gen_reg_rtx (XFmode);
17341
17342   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17343
17344   ix86_emit_i387_log1p (op0, operands[1]);
17345   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17346   DONE;
17347 })
17348
17349 (define_insn "fxtractxf3_i387"
17350   [(set (match_operand:XF 0 "register_operand" "=f")
17351         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17352                    UNSPEC_XTRACT_FRACT))
17353    (set (match_operand:XF 1 "register_operand" "=u")
17354         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17355   "TARGET_USE_FANCY_MATH_387
17356    && flag_unsafe_math_optimizations"
17357   "fxtract"
17358   [(set_attr "type" "fpspc")
17359    (set_attr "mode" "XF")])
17360
17361 (define_insn "fxtract_extend<mode>xf3_i387"
17362   [(set (match_operand:XF 0 "register_operand" "=f")
17363         (unspec:XF [(float_extend:XF
17364                       (match_operand:MODEF 2 "register_operand" "0"))]
17365                    UNSPEC_XTRACT_FRACT))
17366    (set (match_operand:XF 1 "register_operand" "=u")
17367         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17368   "TARGET_USE_FANCY_MATH_387
17369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370        || TARGET_MIX_SSE_I387)
17371    && flag_unsafe_math_optimizations"
17372   "fxtract"
17373   [(set_attr "type" "fpspc")
17374    (set_attr "mode" "XF")])
17375
17376 (define_expand "logbxf2"
17377   [(parallel [(set (match_dup 2)
17378                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17379                               UNSPEC_XTRACT_FRACT))
17380               (set (match_operand:XF 0 "register_operand" "")
17381                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17382   "TARGET_USE_FANCY_MATH_387
17383    && flag_unsafe_math_optimizations"
17384 {
17385   operands[2] = gen_reg_rtx (XFmode);
17386 })
17387
17388 (define_expand "logb<mode>2"
17389   [(use (match_operand:MODEF 0 "register_operand" ""))
17390    (use (match_operand:MODEF 1 "register_operand" ""))]
17391   "TARGET_USE_FANCY_MATH_387
17392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17393        || TARGET_MIX_SSE_I387)
17394    && flag_unsafe_math_optimizations"
17395 {
17396   rtx op0 = gen_reg_rtx (XFmode);
17397   rtx op1 = gen_reg_rtx (XFmode);
17398
17399   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17400   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17401   DONE;
17402 })
17403
17404 (define_expand "ilogbxf2"
17405   [(use (match_operand:SI 0 "register_operand" ""))
17406    (use (match_operand:XF 1 "register_operand" ""))]
17407   "TARGET_USE_FANCY_MATH_387
17408    && flag_unsafe_math_optimizations && !optimize_size"
17409 {
17410   rtx op0 = gen_reg_rtx (XFmode);
17411   rtx op1 = gen_reg_rtx (XFmode);
17412
17413   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17414   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17415   DONE;
17416 })
17417
17418 (define_expand "ilogb<mode>2"
17419   [(use (match_operand:SI 0 "register_operand" ""))
17420    (use (match_operand:MODEF 1 "register_operand" ""))]
17421   "TARGET_USE_FANCY_MATH_387
17422    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17423        || TARGET_MIX_SSE_I387)
17424    && flag_unsafe_math_optimizations && !optimize_size"
17425 {
17426   rtx op0 = gen_reg_rtx (XFmode);
17427   rtx op1 = gen_reg_rtx (XFmode);
17428
17429   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17430   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17431   DONE;
17432 })
17433
17434 (define_insn "*f2xm1xf2_i387"
17435   [(set (match_operand:XF 0 "register_operand" "=f")
17436         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17437                    UNSPEC_F2XM1))]
17438   "TARGET_USE_FANCY_MATH_387
17439    && flag_unsafe_math_optimizations"
17440   "f2xm1"
17441   [(set_attr "type" "fpspc")
17442    (set_attr "mode" "XF")])
17443
17444 (define_insn "*fscalexf4_i387"
17445   [(set (match_operand:XF 0 "register_operand" "=f")
17446         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17447                     (match_operand:XF 3 "register_operand" "1")]
17448                    UNSPEC_FSCALE_FRACT))
17449    (set (match_operand:XF 1 "register_operand" "=u")
17450         (unspec:XF [(match_dup 2) (match_dup 3)]
17451                    UNSPEC_FSCALE_EXP))]
17452   "TARGET_USE_FANCY_MATH_387
17453    && flag_unsafe_math_optimizations"
17454   "fscale"
17455   [(set_attr "type" "fpspc")
17456    (set_attr "mode" "XF")])
17457
17458 (define_expand "expNcorexf3"
17459   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17460                                (match_operand:XF 2 "register_operand" "")))
17461    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17462    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17463    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17464    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17465    (parallel [(set (match_operand:XF 0 "register_operand" "")
17466                    (unspec:XF [(match_dup 8) (match_dup 4)]
17467                               UNSPEC_FSCALE_FRACT))
17468               (set (match_dup 9)
17469                    (unspec:XF [(match_dup 8) (match_dup 4)]
17470                               UNSPEC_FSCALE_EXP))])]
17471   "TARGET_USE_FANCY_MATH_387
17472    && flag_unsafe_math_optimizations && !optimize_size"
17473 {
17474   int i;
17475
17476   for (i = 3; i < 10; i++)
17477     operands[i] = gen_reg_rtx (XFmode);
17478
17479   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17480 })
17481
17482 (define_expand "expxf2"
17483   [(use (match_operand:XF 0 "register_operand" ""))
17484    (use (match_operand:XF 1 "register_operand" ""))]
17485   "TARGET_USE_FANCY_MATH_387
17486    && flag_unsafe_math_optimizations && !optimize_size"
17487 {
17488   rtx op2 = gen_reg_rtx (XFmode);
17489   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17490
17491   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17492   DONE;
17493 })
17494
17495 (define_expand "exp<mode>2"
17496   [(use (match_operand:MODEF 0 "register_operand" ""))
17497    (use (match_operand:MODEF 1 "general_operand" ""))]
17498  "TARGET_USE_FANCY_MATH_387
17499    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17500        || TARGET_MIX_SSE_I387)
17501    && flag_unsafe_math_optimizations && !optimize_size"
17502 {
17503   rtx op0 = gen_reg_rtx (XFmode);
17504   rtx op1 = gen_reg_rtx (XFmode);
17505
17506   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17507   emit_insn (gen_expxf2 (op0, op1));
17508   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17509   DONE;
17510 })
17511
17512 (define_expand "exp10xf2"
17513   [(use (match_operand:XF 0 "register_operand" ""))
17514    (use (match_operand:XF 1 "register_operand" ""))]
17515   "TARGET_USE_FANCY_MATH_387
17516    && flag_unsafe_math_optimizations && !optimize_size"
17517 {
17518   rtx op2 = gen_reg_rtx (XFmode);
17519   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17520
17521   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17522   DONE;
17523 })
17524
17525 (define_expand "exp10<mode>2"
17526   [(use (match_operand:MODEF 0 "register_operand" ""))
17527    (use (match_operand:MODEF 1 "general_operand" ""))]
17528  "TARGET_USE_FANCY_MATH_387
17529    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17530        || TARGET_MIX_SSE_I387)
17531    && flag_unsafe_math_optimizations && !optimize_size"
17532 {
17533   rtx op0 = gen_reg_rtx (XFmode);
17534   rtx op1 = gen_reg_rtx (XFmode);
17535
17536   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17537   emit_insn (gen_exp10xf2 (op0, op1));
17538   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17539   DONE;
17540 })
17541
17542 (define_expand "exp2xf2"
17543   [(use (match_operand:XF 0 "register_operand" ""))
17544    (use (match_operand:XF 1 "register_operand" ""))]
17545   "TARGET_USE_FANCY_MATH_387
17546    && flag_unsafe_math_optimizations && !optimize_size"
17547 {
17548   rtx op2 = gen_reg_rtx (XFmode);
17549   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17550
17551   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17552   DONE;
17553 })
17554
17555 (define_expand "exp2<mode>2"
17556   [(use (match_operand:MODEF 0 "register_operand" ""))
17557    (use (match_operand:MODEF 1 "general_operand" ""))]
17558  "TARGET_USE_FANCY_MATH_387
17559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17560        || TARGET_MIX_SSE_I387)
17561    && flag_unsafe_math_optimizations && !optimize_size"
17562 {
17563   rtx op0 = gen_reg_rtx (XFmode);
17564   rtx op1 = gen_reg_rtx (XFmode);
17565
17566   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17567   emit_insn (gen_exp2xf2 (op0, op1));
17568   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17569   DONE;
17570 })
17571
17572 (define_expand "expm1xf2"
17573   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17574                                (match_dup 2)))
17575    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17576    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17577    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17578    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17579    (parallel [(set (match_dup 7)
17580                    (unspec:XF [(match_dup 6) (match_dup 4)]
17581                               UNSPEC_FSCALE_FRACT))
17582               (set (match_dup 8)
17583                    (unspec:XF [(match_dup 6) (match_dup 4)]
17584                               UNSPEC_FSCALE_EXP))])
17585    (parallel [(set (match_dup 10)
17586                    (unspec:XF [(match_dup 9) (match_dup 8)]
17587                               UNSPEC_FSCALE_FRACT))
17588               (set (match_dup 11)
17589                    (unspec:XF [(match_dup 9) (match_dup 8)]
17590                               UNSPEC_FSCALE_EXP))])
17591    (set (match_dup 12) (minus:XF (match_dup 10)
17592                                  (float_extend:XF (match_dup 13))))
17593    (set (match_operand:XF 0 "register_operand" "")
17594         (plus:XF (match_dup 12) (match_dup 7)))]
17595   "TARGET_USE_FANCY_MATH_387
17596    && flag_unsafe_math_optimizations && !optimize_size"
17597 {
17598   int i;
17599
17600   for (i = 2; i < 13; i++)
17601     operands[i] = gen_reg_rtx (XFmode);
17602
17603   operands[13]
17604     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17605
17606   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17607 })
17608
17609 (define_expand "expm1<mode>2"
17610   [(use (match_operand:MODEF 0 "register_operand" ""))
17611    (use (match_operand:MODEF 1 "general_operand" ""))]
17612  "TARGET_USE_FANCY_MATH_387
17613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614        || TARGET_MIX_SSE_I387)
17615    && flag_unsafe_math_optimizations && !optimize_size"
17616 {
17617   rtx op0 = gen_reg_rtx (XFmode);
17618   rtx op1 = gen_reg_rtx (XFmode);
17619
17620   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17621   emit_insn (gen_expm1xf2 (op0, op1));
17622   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17623   DONE;
17624 })
17625
17626 (define_expand "ldexpxf3"
17627   [(set (match_dup 3)
17628         (float:XF (match_operand:SI 2 "register_operand" "")))
17629    (parallel [(set (match_operand:XF 0 " register_operand" "")
17630                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17631                                (match_dup 3)]
17632                               UNSPEC_FSCALE_FRACT))
17633               (set (match_dup 4)
17634                    (unspec:XF [(match_dup 1) (match_dup 3)]
17635                               UNSPEC_FSCALE_EXP))])]
17636   "TARGET_USE_FANCY_MATH_387
17637    && flag_unsafe_math_optimizations && !optimize_size"
17638 {
17639   operands[3] = gen_reg_rtx (XFmode);
17640   operands[4] = gen_reg_rtx (XFmode);
17641 })
17642
17643 (define_expand "ldexp<mode>3"
17644   [(use (match_operand:MODEF 0 "register_operand" ""))
17645    (use (match_operand:MODEF 1 "general_operand" ""))
17646    (use (match_operand:SI 2 "register_operand" ""))]
17647  "TARGET_USE_FANCY_MATH_387
17648    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17649        || TARGET_MIX_SSE_I387)
17650    && flag_unsafe_math_optimizations && !optimize_size"
17651 {
17652   rtx op0 = gen_reg_rtx (XFmode);
17653   rtx op1 = gen_reg_rtx (XFmode);
17654
17655   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17656   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17657   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17658   DONE;
17659 })
17660
17661 (define_expand "scalbxf3"
17662   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17663                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17664                                (match_operand:XF 2 "register_operand" "")]
17665                               UNSPEC_FSCALE_FRACT))
17666               (set (match_dup 3)
17667                    (unspec:XF [(match_dup 1) (match_dup 2)]
17668                               UNSPEC_FSCALE_EXP))])]
17669   "TARGET_USE_FANCY_MATH_387
17670    && flag_unsafe_math_optimizations && !optimize_size"
17671 {
17672   operands[3] = gen_reg_rtx (XFmode);
17673 })
17674
17675 (define_expand "scalb<mode>3"
17676   [(use (match_operand:MODEF 0 "register_operand" ""))
17677    (use (match_operand:MODEF 1 "general_operand" ""))
17678    (use (match_operand:MODEF 2 "register_operand" ""))]
17679  "TARGET_USE_FANCY_MATH_387
17680    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17681        || TARGET_MIX_SSE_I387)
17682    && flag_unsafe_math_optimizations && !optimize_size"
17683 {
17684   rtx op0 = gen_reg_rtx (XFmode);
17685   rtx op1 = gen_reg_rtx (XFmode);
17686   rtx op2 = gen_reg_rtx (XFmode);
17687
17688   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17689   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17690   emit_insn (gen_scalbxf3 (op0, op1, op2));
17691   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17692   DONE;
17693 })
17694 \f
17695
17696 (define_insn "sse4_1_round<mode>2"
17697   [(set (match_operand:MODEF 0 "register_operand" "=x")
17698         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17699                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17700                       UNSPEC_ROUND))]
17701   "TARGET_ROUND"
17702   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17703   [(set_attr "type" "ssecvt")
17704    (set_attr "prefix_extra" "1")
17705    (set_attr "mode" "<MODE>")])
17706
17707 (define_insn "rintxf2"
17708   [(set (match_operand:XF 0 "register_operand" "=f")
17709         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17710                    UNSPEC_FRNDINT))]
17711   "TARGET_USE_FANCY_MATH_387
17712    && flag_unsafe_math_optimizations"
17713   "frndint"
17714   [(set_attr "type" "fpspc")
17715    (set_attr "mode" "XF")])
17716
17717 (define_expand "rint<mode>2"
17718   [(use (match_operand:MODEF 0 "register_operand" ""))
17719    (use (match_operand:MODEF 1 "register_operand" ""))]
17720   "(TARGET_USE_FANCY_MATH_387
17721     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17722         || TARGET_MIX_SSE_I387)
17723     && flag_unsafe_math_optimizations)
17724    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17725        && !flag_trapping_math
17726        && (TARGET_ROUND || !optimize_size))"
17727 {
17728   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17729       && !flag_trapping_math
17730       && (TARGET_ROUND || !optimize_size))
17731     {
17732       if (TARGET_ROUND)
17733         emit_insn (gen_sse4_1_round<mode>2
17734                    (operands[0], operands[1], GEN_INT (0x04)));
17735       else
17736         ix86_expand_rint (operand0, operand1);
17737     }
17738   else
17739     {
17740       rtx op0 = gen_reg_rtx (XFmode);
17741       rtx op1 = gen_reg_rtx (XFmode);
17742
17743       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17744       emit_insn (gen_rintxf2 (op0, op1));
17745
17746       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17747     }
17748   DONE;
17749 })
17750
17751 (define_expand "round<mode>2"
17752   [(match_operand:MODEF 0 "register_operand" "")
17753    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17754   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17755    && !flag_trapping_math && !flag_rounding_math
17756    && !optimize_size"
17757 {
17758   if (TARGET_64BIT || (<MODE>mode != DFmode))
17759     ix86_expand_round (operand0, operand1);
17760   else
17761     ix86_expand_rounddf_32 (operand0, operand1);
17762   DONE;
17763 })
17764
17765 (define_insn_and_split "*fistdi2_1"
17766   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17767         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17768                    UNSPEC_FIST))]
17769   "TARGET_USE_FANCY_MATH_387
17770    && !(reload_completed || reload_in_progress)"
17771   "#"
17772   "&& 1"
17773   [(const_int 0)]
17774 {
17775   if (memory_operand (operands[0], VOIDmode))
17776     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17777   else
17778     {
17779       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17780       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17781                                          operands[2]));
17782     }
17783   DONE;
17784 }
17785   [(set_attr "type" "fpspc")
17786    (set_attr "mode" "DI")])
17787
17788 (define_insn "fistdi2"
17789   [(set (match_operand:DI 0 "memory_operand" "=m")
17790         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17791                    UNSPEC_FIST))
17792    (clobber (match_scratch:XF 2 "=&1f"))]
17793   "TARGET_USE_FANCY_MATH_387"
17794   "* return output_fix_trunc (insn, operands, 0);"
17795   [(set_attr "type" "fpspc")
17796    (set_attr "mode" "DI")])
17797
17798 (define_insn "fistdi2_with_temp"
17799   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17800         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17801                    UNSPEC_FIST))
17802    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17803    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17804   "TARGET_USE_FANCY_MATH_387"
17805   "#"
17806   [(set_attr "type" "fpspc")
17807    (set_attr "mode" "DI")])
17808
17809 (define_split
17810   [(set (match_operand:DI 0 "register_operand" "")
17811         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17812                    UNSPEC_FIST))
17813    (clobber (match_operand:DI 2 "memory_operand" ""))
17814    (clobber (match_scratch 3 ""))]
17815   "reload_completed"
17816   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17817               (clobber (match_dup 3))])
17818    (set (match_dup 0) (match_dup 2))]
17819   "")
17820
17821 (define_split
17822   [(set (match_operand:DI 0 "memory_operand" "")
17823         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17824                    UNSPEC_FIST))
17825    (clobber (match_operand:DI 2 "memory_operand" ""))
17826    (clobber (match_scratch 3 ""))]
17827   "reload_completed"
17828   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17829               (clobber (match_dup 3))])]
17830   "")
17831
17832 (define_insn_and_split "*fist<mode>2_1"
17833   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17834         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17835                            UNSPEC_FIST))]
17836   "TARGET_USE_FANCY_MATH_387
17837    && !(reload_completed || reload_in_progress)"
17838   "#"
17839   "&& 1"
17840   [(const_int 0)]
17841 {
17842   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17843   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17844                                         operands[2]));
17845   DONE;
17846 }
17847   [(set_attr "type" "fpspc")
17848    (set_attr "mode" "<MODE>")])
17849
17850 (define_insn "fist<mode>2"
17851   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17852         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17853                            UNSPEC_FIST))]
17854   "TARGET_USE_FANCY_MATH_387"
17855   "* return output_fix_trunc (insn, operands, 0);"
17856   [(set_attr "type" "fpspc")
17857    (set_attr "mode" "<MODE>")])
17858
17859 (define_insn "fist<mode>2_with_temp"
17860   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17861         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17862                            UNSPEC_FIST))
17863    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17864   "TARGET_USE_FANCY_MATH_387"
17865   "#"
17866   [(set_attr "type" "fpspc")
17867    (set_attr "mode" "<MODE>")])
17868
17869 (define_split
17870   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17871         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17872                            UNSPEC_FIST))
17873    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17874   "reload_completed"
17875   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17876    (set (match_dup 0) (match_dup 2))]
17877   "")
17878
17879 (define_split
17880   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17881         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17882                            UNSPEC_FIST))
17883    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17884   "reload_completed"
17885   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17886   "")
17887
17888 (define_expand "lrintxf<mode>2"
17889   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17890      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17891                       UNSPEC_FIST))]
17892   "TARGET_USE_FANCY_MATH_387"
17893   "")
17894
17895 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17896   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17897      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17898                         UNSPEC_FIX_NOTRUNC))]
17899   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17900    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17901   "")
17902
17903 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17904   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17905    (match_operand:MODEF 1 "register_operand" "")]
17906   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17907    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17908    && !flag_trapping_math && !flag_rounding_math
17909    && !optimize_size"
17910 {
17911   ix86_expand_lround (operand0, operand1);
17912   DONE;
17913 })
17914
17915 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17916 (define_insn_and_split "frndintxf2_floor"
17917   [(set (match_operand:XF 0 "register_operand" "")
17918         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17919          UNSPEC_FRNDINT_FLOOR))
17920    (clobber (reg:CC FLAGS_REG))]
17921   "TARGET_USE_FANCY_MATH_387
17922    && flag_unsafe_math_optimizations
17923    && !(reload_completed || reload_in_progress)"
17924   "#"
17925   "&& 1"
17926   [(const_int 0)]
17927 {
17928   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17929
17930   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17931   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17932
17933   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17934                                         operands[2], operands[3]));
17935   DONE;
17936 }
17937   [(set_attr "type" "frndint")
17938    (set_attr "i387_cw" "floor")
17939    (set_attr "mode" "XF")])
17940
17941 (define_insn "frndintxf2_floor_i387"
17942   [(set (match_operand:XF 0 "register_operand" "=f")
17943         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17944          UNSPEC_FRNDINT_FLOOR))
17945    (use (match_operand:HI 2 "memory_operand" "m"))
17946    (use (match_operand:HI 3 "memory_operand" "m"))]
17947   "TARGET_USE_FANCY_MATH_387
17948    && flag_unsafe_math_optimizations"
17949   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17950   [(set_attr "type" "frndint")
17951    (set_attr "i387_cw" "floor")
17952    (set_attr "mode" "XF")])
17953
17954 (define_expand "floorxf2"
17955   [(use (match_operand:XF 0 "register_operand" ""))
17956    (use (match_operand:XF 1 "register_operand" ""))]
17957   "TARGET_USE_FANCY_MATH_387
17958    && flag_unsafe_math_optimizations && !optimize_size"
17959 {
17960   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17961   DONE;
17962 })
17963
17964 (define_expand "floor<mode>2"
17965   [(use (match_operand:MODEF 0 "register_operand" ""))
17966    (use (match_operand:MODEF 1 "register_operand" ""))]
17967   "(TARGET_USE_FANCY_MATH_387
17968     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17969         || TARGET_MIX_SSE_I387)
17970     && flag_unsafe_math_optimizations && !optimize_size)
17971    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17972        && !flag_trapping_math
17973        && (TARGET_ROUND || !optimize_size))"
17974 {
17975   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17976       && !flag_trapping_math
17977       && (TARGET_ROUND || !optimize_size))
17978     {
17979       if (TARGET_ROUND)
17980         emit_insn (gen_sse4_1_round<mode>2
17981                    (operands[0], operands[1], GEN_INT (0x01)));
17982       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17983         ix86_expand_floorceil (operand0, operand1, true);
17984       else
17985         ix86_expand_floorceildf_32 (operand0, operand1, true);
17986     }
17987   else
17988     {
17989       rtx op0 = gen_reg_rtx (XFmode);
17990       rtx op1 = gen_reg_rtx (XFmode);
17991
17992       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17993       emit_insn (gen_frndintxf2_floor (op0, op1));
17994
17995       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17996     }
17997   DONE;
17998 })
17999
18000 (define_insn_and_split "*fist<mode>2_floor_1"
18001   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18002         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18003          UNSPEC_FIST_FLOOR))
18004    (clobber (reg:CC FLAGS_REG))]
18005   "TARGET_USE_FANCY_MATH_387
18006    && flag_unsafe_math_optimizations
18007    && !(reload_completed || reload_in_progress)"
18008   "#"
18009   "&& 1"
18010   [(const_int 0)]
18011 {
18012   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18013
18014   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18015   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18016   if (memory_operand (operands[0], VOIDmode))
18017     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18018                                       operands[2], operands[3]));
18019   else
18020     {
18021       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18022       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18023                                                   operands[2], operands[3],
18024                                                   operands[4]));
18025     }
18026   DONE;
18027 }
18028   [(set_attr "type" "fistp")
18029    (set_attr "i387_cw" "floor")
18030    (set_attr "mode" "<MODE>")])
18031
18032 (define_insn "fistdi2_floor"
18033   [(set (match_operand:DI 0 "memory_operand" "=m")
18034         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18035          UNSPEC_FIST_FLOOR))
18036    (use (match_operand:HI 2 "memory_operand" "m"))
18037    (use (match_operand:HI 3 "memory_operand" "m"))
18038    (clobber (match_scratch:XF 4 "=&1f"))]
18039   "TARGET_USE_FANCY_MATH_387
18040    && flag_unsafe_math_optimizations"
18041   "* return output_fix_trunc (insn, operands, 0);"
18042   [(set_attr "type" "fistp")
18043    (set_attr "i387_cw" "floor")
18044    (set_attr "mode" "DI")])
18045
18046 (define_insn "fistdi2_floor_with_temp"
18047   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18048         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18049          UNSPEC_FIST_FLOOR))
18050    (use (match_operand:HI 2 "memory_operand" "m,m"))
18051    (use (match_operand:HI 3 "memory_operand" "m,m"))
18052    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18053    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18054   "TARGET_USE_FANCY_MATH_387
18055    && flag_unsafe_math_optimizations"
18056   "#"
18057   [(set_attr "type" "fistp")
18058    (set_attr "i387_cw" "floor")
18059    (set_attr "mode" "DI")])
18060
18061 (define_split
18062   [(set (match_operand:DI 0 "register_operand" "")
18063         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18064          UNSPEC_FIST_FLOOR))
18065    (use (match_operand:HI 2 "memory_operand" ""))
18066    (use (match_operand:HI 3 "memory_operand" ""))
18067    (clobber (match_operand:DI 4 "memory_operand" ""))
18068    (clobber (match_scratch 5 ""))]
18069   "reload_completed"
18070   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18071               (use (match_dup 2))
18072               (use (match_dup 3))
18073               (clobber (match_dup 5))])
18074    (set (match_dup 0) (match_dup 4))]
18075   "")
18076
18077 (define_split
18078   [(set (match_operand:DI 0 "memory_operand" "")
18079         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18080          UNSPEC_FIST_FLOOR))
18081    (use (match_operand:HI 2 "memory_operand" ""))
18082    (use (match_operand:HI 3 "memory_operand" ""))
18083    (clobber (match_operand:DI 4 "memory_operand" ""))
18084    (clobber (match_scratch 5 ""))]
18085   "reload_completed"
18086   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18087               (use (match_dup 2))
18088               (use (match_dup 3))
18089               (clobber (match_dup 5))])]
18090   "")
18091
18092 (define_insn "fist<mode>2_floor"
18093   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18094         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18095          UNSPEC_FIST_FLOOR))
18096    (use (match_operand:HI 2 "memory_operand" "m"))
18097    (use (match_operand:HI 3 "memory_operand" "m"))]
18098   "TARGET_USE_FANCY_MATH_387
18099    && flag_unsafe_math_optimizations"
18100   "* return output_fix_trunc (insn, operands, 0);"
18101   [(set_attr "type" "fistp")
18102    (set_attr "i387_cw" "floor")
18103    (set_attr "mode" "<MODE>")])
18104
18105 (define_insn "fist<mode>2_floor_with_temp"
18106   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18107         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18108          UNSPEC_FIST_FLOOR))
18109    (use (match_operand:HI 2 "memory_operand" "m,m"))
18110    (use (match_operand:HI 3 "memory_operand" "m,m"))
18111    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18112   "TARGET_USE_FANCY_MATH_387
18113    && flag_unsafe_math_optimizations"
18114   "#"
18115   [(set_attr "type" "fistp")
18116    (set_attr "i387_cw" "floor")
18117    (set_attr "mode" "<MODE>")])
18118
18119 (define_split
18120   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18121         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18122          UNSPEC_FIST_FLOOR))
18123    (use (match_operand:HI 2 "memory_operand" ""))
18124    (use (match_operand:HI 3 "memory_operand" ""))
18125    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18126   "reload_completed"
18127   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18128                                   UNSPEC_FIST_FLOOR))
18129               (use (match_dup 2))
18130               (use (match_dup 3))])
18131    (set (match_dup 0) (match_dup 4))]
18132   "")
18133
18134 (define_split
18135   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18136         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18137          UNSPEC_FIST_FLOOR))
18138    (use (match_operand:HI 2 "memory_operand" ""))
18139    (use (match_operand:HI 3 "memory_operand" ""))
18140    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18141   "reload_completed"
18142   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18143                                   UNSPEC_FIST_FLOOR))
18144               (use (match_dup 2))
18145               (use (match_dup 3))])]
18146   "")
18147
18148 (define_expand "lfloorxf<mode>2"
18149   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18150                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18151                     UNSPEC_FIST_FLOOR))
18152               (clobber (reg:CC FLAGS_REG))])]
18153   "TARGET_USE_FANCY_MATH_387
18154    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18155    && flag_unsafe_math_optimizations"
18156   "")
18157
18158 (define_expand "lfloor<mode>di2"
18159   [(match_operand:DI 0 "nonimmediate_operand" "")
18160    (match_operand:MODEF 1 "register_operand" "")]
18161   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18162    && !flag_trapping_math
18163    && !optimize_size"
18164 {
18165   ix86_expand_lfloorceil (operand0, operand1, true);
18166   DONE;
18167 })
18168
18169 (define_expand "lfloor<mode>si2"
18170   [(match_operand:SI 0 "nonimmediate_operand" "")
18171    (match_operand:MODEF 1 "register_operand" "")]
18172   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173    && !flag_trapping_math
18174    && (!optimize_size || !TARGET_64BIT)"
18175 {
18176   ix86_expand_lfloorceil (operand0, operand1, true);
18177   DONE;
18178 })
18179
18180 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18181 (define_insn_and_split "frndintxf2_ceil"
18182   [(set (match_operand:XF 0 "register_operand" "")
18183         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18184          UNSPEC_FRNDINT_CEIL))
18185    (clobber (reg:CC FLAGS_REG))]
18186   "TARGET_USE_FANCY_MATH_387
18187    && flag_unsafe_math_optimizations
18188    && !(reload_completed || reload_in_progress)"
18189   "#"
18190   "&& 1"
18191   [(const_int 0)]
18192 {
18193   ix86_optimize_mode_switching[I387_CEIL] = 1;
18194
18195   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18196   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18197
18198   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18199                                        operands[2], operands[3]));
18200   DONE;
18201 }
18202   [(set_attr "type" "frndint")
18203    (set_attr "i387_cw" "ceil")
18204    (set_attr "mode" "XF")])
18205
18206 (define_insn "frndintxf2_ceil_i387"
18207   [(set (match_operand:XF 0 "register_operand" "=f")
18208         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18209          UNSPEC_FRNDINT_CEIL))
18210    (use (match_operand:HI 2 "memory_operand" "m"))
18211    (use (match_operand:HI 3 "memory_operand" "m"))]
18212   "TARGET_USE_FANCY_MATH_387
18213    && flag_unsafe_math_optimizations"
18214   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18215   [(set_attr "type" "frndint")
18216    (set_attr "i387_cw" "ceil")
18217    (set_attr "mode" "XF")])
18218
18219 (define_expand "ceilxf2"
18220   [(use (match_operand:XF 0 "register_operand" ""))
18221    (use (match_operand:XF 1 "register_operand" ""))]
18222   "TARGET_USE_FANCY_MATH_387
18223    && flag_unsafe_math_optimizations && !optimize_size"
18224 {
18225   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18226   DONE;
18227 })
18228
18229 (define_expand "ceil<mode>2"
18230   [(use (match_operand:MODEF 0 "register_operand" ""))
18231    (use (match_operand:MODEF 1 "register_operand" ""))]
18232   "(TARGET_USE_FANCY_MATH_387
18233     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18234         || TARGET_MIX_SSE_I387)
18235     && flag_unsafe_math_optimizations && !optimize_size)
18236    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18237        && !flag_trapping_math
18238        && (TARGET_ROUND || !optimize_size))"
18239 {
18240   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18241       && !flag_trapping_math
18242       && (TARGET_ROUND || !optimize_size))
18243     {
18244       if (TARGET_ROUND)
18245         emit_insn (gen_sse4_1_round<mode>2
18246                    (operands[0], operands[1], GEN_INT (0x02)));
18247       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18248         ix86_expand_floorceil (operand0, operand1, false);
18249       else
18250         ix86_expand_floorceildf_32 (operand0, operand1, false);
18251     }
18252   else
18253     {
18254       rtx op0 = gen_reg_rtx (XFmode);
18255       rtx op1 = gen_reg_rtx (XFmode);
18256
18257       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18258       emit_insn (gen_frndintxf2_ceil (op0, op1));
18259
18260       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18261     }
18262   DONE;
18263 })
18264
18265 (define_insn_and_split "*fist<mode>2_ceil_1"
18266   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18267         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18268          UNSPEC_FIST_CEIL))
18269    (clobber (reg:CC FLAGS_REG))]
18270   "TARGET_USE_FANCY_MATH_387
18271    && flag_unsafe_math_optimizations
18272    && !(reload_completed || reload_in_progress)"
18273   "#"
18274   "&& 1"
18275   [(const_int 0)]
18276 {
18277   ix86_optimize_mode_switching[I387_CEIL] = 1;
18278
18279   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18280   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18281   if (memory_operand (operands[0], VOIDmode))
18282     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18283                                      operands[2], operands[3]));
18284   else
18285     {
18286       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18287       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18288                                                  operands[2], operands[3],
18289                                                  operands[4]));
18290     }
18291   DONE;
18292 }
18293   [(set_attr "type" "fistp")
18294    (set_attr "i387_cw" "ceil")
18295    (set_attr "mode" "<MODE>")])
18296
18297 (define_insn "fistdi2_ceil"
18298   [(set (match_operand:DI 0 "memory_operand" "=m")
18299         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18300          UNSPEC_FIST_CEIL))
18301    (use (match_operand:HI 2 "memory_operand" "m"))
18302    (use (match_operand:HI 3 "memory_operand" "m"))
18303    (clobber (match_scratch:XF 4 "=&1f"))]
18304   "TARGET_USE_FANCY_MATH_387
18305    && flag_unsafe_math_optimizations"
18306   "* return output_fix_trunc (insn, operands, 0);"
18307   [(set_attr "type" "fistp")
18308    (set_attr "i387_cw" "ceil")
18309    (set_attr "mode" "DI")])
18310
18311 (define_insn "fistdi2_ceil_with_temp"
18312   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18313         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18314          UNSPEC_FIST_CEIL))
18315    (use (match_operand:HI 2 "memory_operand" "m,m"))
18316    (use (match_operand:HI 3 "memory_operand" "m,m"))
18317    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18318    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18319   "TARGET_USE_FANCY_MATH_387
18320    && flag_unsafe_math_optimizations"
18321   "#"
18322   [(set_attr "type" "fistp")
18323    (set_attr "i387_cw" "ceil")
18324    (set_attr "mode" "DI")])
18325
18326 (define_split
18327   [(set (match_operand:DI 0 "register_operand" "")
18328         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18329          UNSPEC_FIST_CEIL))
18330    (use (match_operand:HI 2 "memory_operand" ""))
18331    (use (match_operand:HI 3 "memory_operand" ""))
18332    (clobber (match_operand:DI 4 "memory_operand" ""))
18333    (clobber (match_scratch 5 ""))]
18334   "reload_completed"
18335   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18336               (use (match_dup 2))
18337               (use (match_dup 3))
18338               (clobber (match_dup 5))])
18339    (set (match_dup 0) (match_dup 4))]
18340   "")
18341
18342 (define_split
18343   [(set (match_operand:DI 0 "memory_operand" "")
18344         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18345          UNSPEC_FIST_CEIL))
18346    (use (match_operand:HI 2 "memory_operand" ""))
18347    (use (match_operand:HI 3 "memory_operand" ""))
18348    (clobber (match_operand:DI 4 "memory_operand" ""))
18349    (clobber (match_scratch 5 ""))]
18350   "reload_completed"
18351   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18352               (use (match_dup 2))
18353               (use (match_dup 3))
18354               (clobber (match_dup 5))])]
18355   "")
18356
18357 (define_insn "fist<mode>2_ceil"
18358   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18359         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18360          UNSPEC_FIST_CEIL))
18361    (use (match_operand:HI 2 "memory_operand" "m"))
18362    (use (match_operand:HI 3 "memory_operand" "m"))]
18363   "TARGET_USE_FANCY_MATH_387
18364    && flag_unsafe_math_optimizations"
18365   "* return output_fix_trunc (insn, operands, 0);"
18366   [(set_attr "type" "fistp")
18367    (set_attr "i387_cw" "ceil")
18368    (set_attr "mode" "<MODE>")])
18369
18370 (define_insn "fist<mode>2_ceil_with_temp"
18371   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18372         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18373          UNSPEC_FIST_CEIL))
18374    (use (match_operand:HI 2 "memory_operand" "m,m"))
18375    (use (match_operand:HI 3 "memory_operand" "m,m"))
18376    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18377   "TARGET_USE_FANCY_MATH_387
18378    && flag_unsafe_math_optimizations"
18379   "#"
18380   [(set_attr "type" "fistp")
18381    (set_attr "i387_cw" "ceil")
18382    (set_attr "mode" "<MODE>")])
18383
18384 (define_split
18385   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18386         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18387          UNSPEC_FIST_CEIL))
18388    (use (match_operand:HI 2 "memory_operand" ""))
18389    (use (match_operand:HI 3 "memory_operand" ""))
18390    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18391   "reload_completed"
18392   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18393                                   UNSPEC_FIST_CEIL))
18394               (use (match_dup 2))
18395               (use (match_dup 3))])
18396    (set (match_dup 0) (match_dup 4))]
18397   "")
18398
18399 (define_split
18400   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18401         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18402          UNSPEC_FIST_CEIL))
18403    (use (match_operand:HI 2 "memory_operand" ""))
18404    (use (match_operand:HI 3 "memory_operand" ""))
18405    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18406   "reload_completed"
18407   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18408                                   UNSPEC_FIST_CEIL))
18409               (use (match_dup 2))
18410               (use (match_dup 3))])]
18411   "")
18412
18413 (define_expand "lceilxf<mode>2"
18414   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18415                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18416                     UNSPEC_FIST_CEIL))
18417               (clobber (reg:CC FLAGS_REG))])]
18418   "TARGET_USE_FANCY_MATH_387
18419    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18420    && flag_unsafe_math_optimizations"
18421   "")
18422
18423 (define_expand "lceil<mode>di2"
18424   [(match_operand:DI 0 "nonimmediate_operand" "")
18425    (match_operand:MODEF 1 "register_operand" "")]
18426   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18427    && !flag_trapping_math"
18428 {
18429   ix86_expand_lfloorceil (operand0, operand1, false);
18430   DONE;
18431 })
18432
18433 (define_expand "lceil<mode>si2"
18434   [(match_operand:SI 0 "nonimmediate_operand" "")
18435    (match_operand:MODEF 1 "register_operand" "")]
18436   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18437    && !flag_trapping_math"
18438 {
18439   ix86_expand_lfloorceil (operand0, operand1, false);
18440   DONE;
18441 })
18442
18443 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18444 (define_insn_and_split "frndintxf2_trunc"
18445   [(set (match_operand:XF 0 "register_operand" "")
18446         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18447          UNSPEC_FRNDINT_TRUNC))
18448    (clobber (reg:CC FLAGS_REG))]
18449   "TARGET_USE_FANCY_MATH_387
18450    && flag_unsafe_math_optimizations
18451    && !(reload_completed || reload_in_progress)"
18452   "#"
18453   "&& 1"
18454   [(const_int 0)]
18455 {
18456   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18457
18458   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18459   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18460
18461   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18462                                         operands[2], operands[3]));
18463   DONE;
18464 }
18465   [(set_attr "type" "frndint")
18466    (set_attr "i387_cw" "trunc")
18467    (set_attr "mode" "XF")])
18468
18469 (define_insn "frndintxf2_trunc_i387"
18470   [(set (match_operand:XF 0 "register_operand" "=f")
18471         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18472          UNSPEC_FRNDINT_TRUNC))
18473    (use (match_operand:HI 2 "memory_operand" "m"))
18474    (use (match_operand:HI 3 "memory_operand" "m"))]
18475   "TARGET_USE_FANCY_MATH_387
18476    && flag_unsafe_math_optimizations"
18477   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18478   [(set_attr "type" "frndint")
18479    (set_attr "i387_cw" "trunc")
18480    (set_attr "mode" "XF")])
18481
18482 (define_expand "btruncxf2"
18483   [(use (match_operand:XF 0 "register_operand" ""))
18484    (use (match_operand:XF 1 "register_operand" ""))]
18485   "TARGET_USE_FANCY_MATH_387
18486    && flag_unsafe_math_optimizations && !optimize_size"
18487 {
18488   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18489   DONE;
18490 })
18491
18492 (define_expand "btrunc<mode>2"
18493   [(use (match_operand:MODEF 0 "register_operand" ""))
18494    (use (match_operand:MODEF 1 "register_operand" ""))]
18495   "(TARGET_USE_FANCY_MATH_387
18496     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18497         || TARGET_MIX_SSE_I387)
18498     && flag_unsafe_math_optimizations && !optimize_size)
18499    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18500        && !flag_trapping_math
18501        && (TARGET_ROUND || !optimize_size))"
18502 {
18503   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18504       && !flag_trapping_math
18505       && (TARGET_ROUND || !optimize_size))
18506     {
18507       if (TARGET_ROUND)
18508         emit_insn (gen_sse4_1_round<mode>2
18509                    (operands[0], operands[1], GEN_INT (0x03)));
18510       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18511         ix86_expand_trunc (operand0, operand1);
18512       else
18513         ix86_expand_truncdf_32 (operand0, operand1);
18514     }
18515   else
18516     {
18517       rtx op0 = gen_reg_rtx (XFmode);
18518       rtx op1 = gen_reg_rtx (XFmode);
18519
18520       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18521       emit_insn (gen_frndintxf2_trunc (op0, op1));
18522
18523       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18524     }
18525   DONE;
18526 })
18527
18528 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18529 (define_insn_and_split "frndintxf2_mask_pm"
18530   [(set (match_operand:XF 0 "register_operand" "")
18531         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18532          UNSPEC_FRNDINT_MASK_PM))
18533    (clobber (reg:CC FLAGS_REG))]
18534   "TARGET_USE_FANCY_MATH_387
18535    && flag_unsafe_math_optimizations
18536    && !(reload_completed || reload_in_progress)"
18537   "#"
18538   "&& 1"
18539   [(const_int 0)]
18540 {
18541   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18542
18543   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18544   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18545
18546   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18547                                           operands[2], operands[3]));
18548   DONE;
18549 }
18550   [(set_attr "type" "frndint")
18551    (set_attr "i387_cw" "mask_pm")
18552    (set_attr "mode" "XF")])
18553
18554 (define_insn "frndintxf2_mask_pm_i387"
18555   [(set (match_operand:XF 0 "register_operand" "=f")
18556         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18557          UNSPEC_FRNDINT_MASK_PM))
18558    (use (match_operand:HI 2 "memory_operand" "m"))
18559    (use (match_operand:HI 3 "memory_operand" "m"))]
18560   "TARGET_USE_FANCY_MATH_387
18561    && flag_unsafe_math_optimizations"
18562   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18563   [(set_attr "type" "frndint")
18564    (set_attr "i387_cw" "mask_pm")
18565    (set_attr "mode" "XF")])
18566
18567 (define_expand "nearbyintxf2"
18568   [(use (match_operand:XF 0 "register_operand" ""))
18569    (use (match_operand:XF 1 "register_operand" ""))]
18570   "TARGET_USE_FANCY_MATH_387
18571    && flag_unsafe_math_optimizations"
18572 {
18573   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18574
18575   DONE;
18576 })
18577
18578 (define_expand "nearbyint<mode>2"
18579   [(use (match_operand:MODEF 0 "register_operand" ""))
18580    (use (match_operand:MODEF 1 "register_operand" ""))]
18581   "TARGET_USE_FANCY_MATH_387
18582    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18583        || TARGET_MIX_SSE_I387)
18584    && flag_unsafe_math_optimizations"
18585 {
18586   rtx op0 = gen_reg_rtx (XFmode);
18587   rtx op1 = gen_reg_rtx (XFmode);
18588
18589   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18590   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18591
18592   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18593   DONE;
18594 })
18595
18596 (define_insn "fxam<mode>2_i387"
18597   [(set (match_operand:HI 0 "register_operand" "=a")
18598         (unspec:HI
18599           [(match_operand:X87MODEF 1 "register_operand" "f")]
18600           UNSPEC_FXAM))]
18601   "TARGET_USE_FANCY_MATH_387"
18602   "fxam\n\tfnstsw\t%0"
18603   [(set_attr "type" "multi")
18604    (set_attr "unit" "i387")
18605    (set_attr "mode" "<MODE>")])
18606
18607 (define_expand "isinf<mode>2"
18608   [(use (match_operand:SI 0 "register_operand" ""))
18609    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18610   "TARGET_USE_FANCY_MATH_387
18611    && TARGET_C99_FUNCTIONS
18612    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18613 {
18614   rtx mask = GEN_INT (0x45);
18615   rtx val = GEN_INT (0x05);
18616
18617   rtx cond;
18618
18619   rtx scratch = gen_reg_rtx (HImode);
18620   rtx res = gen_reg_rtx (QImode);
18621
18622   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18623   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18624   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18625   cond = gen_rtx_fmt_ee (EQ, QImode,
18626                          gen_rtx_REG (CCmode, FLAGS_REG),
18627                          const0_rtx);
18628   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18629   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18630   DONE;
18631 })
18632
18633 (define_expand "signbit<mode>2"
18634   [(use (match_operand:SI 0 "register_operand" ""))
18635    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18636   "TARGET_USE_FANCY_MATH_387
18637    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18638 {
18639   rtx mask = GEN_INT (0x0200);
18640
18641   rtx scratch = gen_reg_rtx (HImode);
18642
18643   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18644   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18645   DONE;
18646 })
18647 \f
18648 ;; Block operation instructions
18649
18650 (define_expand "movmemsi"
18651   [(use (match_operand:BLK 0 "memory_operand" ""))
18652    (use (match_operand:BLK 1 "memory_operand" ""))
18653    (use (match_operand:SI 2 "nonmemory_operand" ""))
18654    (use (match_operand:SI 3 "const_int_operand" ""))
18655    (use (match_operand:SI 4 "const_int_operand" ""))
18656    (use (match_operand:SI 5 "const_int_operand" ""))]
18657   ""
18658 {
18659  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18660                          operands[4], operands[5]))
18661    DONE;
18662  else
18663    FAIL;
18664 })
18665
18666 (define_expand "movmemdi"
18667   [(use (match_operand:BLK 0 "memory_operand" ""))
18668    (use (match_operand:BLK 1 "memory_operand" ""))
18669    (use (match_operand:DI 2 "nonmemory_operand" ""))
18670    (use (match_operand:DI 3 "const_int_operand" ""))
18671    (use (match_operand:SI 4 "const_int_operand" ""))
18672    (use (match_operand:SI 5 "const_int_operand" ""))]
18673   "TARGET_64BIT"
18674 {
18675  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18676                          operands[4], operands[5]))
18677    DONE;
18678  else
18679    FAIL;
18680 })
18681
18682 ;; Most CPUs don't like single string operations
18683 ;; Handle this case here to simplify previous expander.
18684
18685 (define_expand "strmov"
18686   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18687    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18688    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18689               (clobber (reg:CC FLAGS_REG))])
18690    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18691               (clobber (reg:CC FLAGS_REG))])]
18692   ""
18693 {
18694   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18695
18696   /* If .md ever supports :P for Pmode, these can be directly
18697      in the pattern above.  */
18698   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18699   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18700
18701   if (TARGET_SINGLE_STRINGOP || optimize_size)
18702     {
18703       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18704                                       operands[2], operands[3],
18705                                       operands[5], operands[6]));
18706       DONE;
18707     }
18708
18709   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18710 })
18711
18712 (define_expand "strmov_singleop"
18713   [(parallel [(set (match_operand 1 "memory_operand" "")
18714                    (match_operand 3 "memory_operand" ""))
18715               (set (match_operand 0 "register_operand" "")
18716                    (match_operand 4 "" ""))
18717               (set (match_operand 2 "register_operand" "")
18718                    (match_operand 5 "" ""))])]
18719   "TARGET_SINGLE_STRINGOP || optimize_size"
18720   "")
18721
18722 (define_insn "*strmovdi_rex_1"
18723   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18724         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18725    (set (match_operand:DI 0 "register_operand" "=D")
18726         (plus:DI (match_dup 2)
18727                  (const_int 8)))
18728    (set (match_operand:DI 1 "register_operand" "=S")
18729         (plus:DI (match_dup 3)
18730                  (const_int 8)))]
18731   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18732   "movsq"
18733   [(set_attr "type" "str")
18734    (set_attr "mode" "DI")
18735    (set_attr "memory" "both")])
18736
18737 (define_insn "*strmovsi_1"
18738   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18739         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18740    (set (match_operand:SI 0 "register_operand" "=D")
18741         (plus:SI (match_dup 2)
18742                  (const_int 4)))
18743    (set (match_operand:SI 1 "register_operand" "=S")
18744         (plus:SI (match_dup 3)
18745                  (const_int 4)))]
18746   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18747   "{movsl|movsd}"
18748   [(set_attr "type" "str")
18749    (set_attr "mode" "SI")
18750    (set_attr "memory" "both")])
18751
18752 (define_insn "*strmovsi_rex_1"
18753   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18754         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18755    (set (match_operand:DI 0 "register_operand" "=D")
18756         (plus:DI (match_dup 2)
18757                  (const_int 4)))
18758    (set (match_operand:DI 1 "register_operand" "=S")
18759         (plus:DI (match_dup 3)
18760                  (const_int 4)))]
18761   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18762   "{movsl|movsd}"
18763   [(set_attr "type" "str")
18764    (set_attr "mode" "SI")
18765    (set_attr "memory" "both")])
18766
18767 (define_insn "*strmovhi_1"
18768   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18769         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18770    (set (match_operand:SI 0 "register_operand" "=D")
18771         (plus:SI (match_dup 2)
18772                  (const_int 2)))
18773    (set (match_operand:SI 1 "register_operand" "=S")
18774         (plus:SI (match_dup 3)
18775                  (const_int 2)))]
18776   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18777   "movsw"
18778   [(set_attr "type" "str")
18779    (set_attr "memory" "both")
18780    (set_attr "mode" "HI")])
18781
18782 (define_insn "*strmovhi_rex_1"
18783   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18784         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18785    (set (match_operand:DI 0 "register_operand" "=D")
18786         (plus:DI (match_dup 2)
18787                  (const_int 2)))
18788    (set (match_operand:DI 1 "register_operand" "=S")
18789         (plus:DI (match_dup 3)
18790                  (const_int 2)))]
18791   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18792   "movsw"
18793   [(set_attr "type" "str")
18794    (set_attr "memory" "both")
18795    (set_attr "mode" "HI")])
18796
18797 (define_insn "*strmovqi_1"
18798   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18799         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18800    (set (match_operand:SI 0 "register_operand" "=D")
18801         (plus:SI (match_dup 2)
18802                  (const_int 1)))
18803    (set (match_operand:SI 1 "register_operand" "=S")
18804         (plus:SI (match_dup 3)
18805                  (const_int 1)))]
18806   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18807   "movsb"
18808   [(set_attr "type" "str")
18809    (set_attr "memory" "both")
18810    (set_attr "mode" "QI")])
18811
18812 (define_insn "*strmovqi_rex_1"
18813   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18814         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18815    (set (match_operand:DI 0 "register_operand" "=D")
18816         (plus:DI (match_dup 2)
18817                  (const_int 1)))
18818    (set (match_operand:DI 1 "register_operand" "=S")
18819         (plus:DI (match_dup 3)
18820                  (const_int 1)))]
18821   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18822   "movsb"
18823   [(set_attr "type" "str")
18824    (set_attr "memory" "both")
18825    (set_attr "mode" "QI")])
18826
18827 (define_expand "rep_mov"
18828   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18829               (set (match_operand 0 "register_operand" "")
18830                    (match_operand 5 "" ""))
18831               (set (match_operand 2 "register_operand" "")
18832                    (match_operand 6 "" ""))
18833               (set (match_operand 1 "memory_operand" "")
18834                    (match_operand 3 "memory_operand" ""))
18835               (use (match_dup 4))])]
18836   ""
18837   "")
18838
18839 (define_insn "*rep_movdi_rex64"
18840   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18841    (set (match_operand:DI 0 "register_operand" "=D")
18842         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18843                             (const_int 3))
18844                  (match_operand:DI 3 "register_operand" "0")))
18845    (set (match_operand:DI 1 "register_operand" "=S")
18846         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18847                  (match_operand:DI 4 "register_operand" "1")))
18848    (set (mem:BLK (match_dup 3))
18849         (mem:BLK (match_dup 4)))
18850    (use (match_dup 5))]
18851   "TARGET_64BIT"
18852   "rep movsq"
18853   [(set_attr "type" "str")
18854    (set_attr "prefix_rep" "1")
18855    (set_attr "memory" "both")
18856    (set_attr "mode" "DI")])
18857
18858 (define_insn "*rep_movsi"
18859   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18860    (set (match_operand:SI 0 "register_operand" "=D")
18861         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18862                             (const_int 2))
18863                  (match_operand:SI 3 "register_operand" "0")))
18864    (set (match_operand:SI 1 "register_operand" "=S")
18865         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18866                  (match_operand:SI 4 "register_operand" "1")))
18867    (set (mem:BLK (match_dup 3))
18868         (mem:BLK (match_dup 4)))
18869    (use (match_dup 5))]
18870   "!TARGET_64BIT"
18871   "rep movs{l|d}"
18872   [(set_attr "type" "str")
18873    (set_attr "prefix_rep" "1")
18874    (set_attr "memory" "both")
18875    (set_attr "mode" "SI")])
18876
18877 (define_insn "*rep_movsi_rex64"
18878   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18879    (set (match_operand:DI 0 "register_operand" "=D")
18880         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18881                             (const_int 2))
18882                  (match_operand:DI 3 "register_operand" "0")))
18883    (set (match_operand:DI 1 "register_operand" "=S")
18884         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18885                  (match_operand:DI 4 "register_operand" "1")))
18886    (set (mem:BLK (match_dup 3))
18887         (mem:BLK (match_dup 4)))
18888    (use (match_dup 5))]
18889   "TARGET_64BIT"
18890   "rep movs{l|d}"
18891   [(set_attr "type" "str")
18892    (set_attr "prefix_rep" "1")
18893    (set_attr "memory" "both")
18894    (set_attr "mode" "SI")])
18895
18896 (define_insn "*rep_movqi"
18897   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18898    (set (match_operand:SI 0 "register_operand" "=D")
18899         (plus:SI (match_operand:SI 3 "register_operand" "0")
18900                  (match_operand:SI 5 "register_operand" "2")))
18901    (set (match_operand:SI 1 "register_operand" "=S")
18902         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18903    (set (mem:BLK (match_dup 3))
18904         (mem:BLK (match_dup 4)))
18905    (use (match_dup 5))]
18906   "!TARGET_64BIT"
18907   "rep movsb"
18908   [(set_attr "type" "str")
18909    (set_attr "prefix_rep" "1")
18910    (set_attr "memory" "both")
18911    (set_attr "mode" "SI")])
18912
18913 (define_insn "*rep_movqi_rex64"
18914   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18915    (set (match_operand:DI 0 "register_operand" "=D")
18916         (plus:DI (match_operand:DI 3 "register_operand" "0")
18917                  (match_operand:DI 5 "register_operand" "2")))
18918    (set (match_operand:DI 1 "register_operand" "=S")
18919         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18920    (set (mem:BLK (match_dup 3))
18921         (mem:BLK (match_dup 4)))
18922    (use (match_dup 5))]
18923   "TARGET_64BIT"
18924   "rep movsb"
18925   [(set_attr "type" "str")
18926    (set_attr "prefix_rep" "1")
18927    (set_attr "memory" "both")
18928    (set_attr "mode" "SI")])
18929
18930 (define_expand "setmemsi"
18931    [(use (match_operand:BLK 0 "memory_operand" ""))
18932     (use (match_operand:SI 1 "nonmemory_operand" ""))
18933     (use (match_operand 2 "const_int_operand" ""))
18934     (use (match_operand 3 "const_int_operand" ""))
18935     (use (match_operand:SI 4 "const_int_operand" ""))
18936     (use (match_operand:SI 5 "const_int_operand" ""))]
18937   ""
18938 {
18939  if (ix86_expand_setmem (operands[0], operands[1],
18940                          operands[2], operands[3],
18941                          operands[4], operands[5]))
18942    DONE;
18943  else
18944    FAIL;
18945 })
18946
18947 (define_expand "setmemdi"
18948    [(use (match_operand:BLK 0 "memory_operand" ""))
18949     (use (match_operand:DI 1 "nonmemory_operand" ""))
18950     (use (match_operand 2 "const_int_operand" ""))
18951     (use (match_operand 3 "const_int_operand" ""))
18952     (use (match_operand 4 "const_int_operand" ""))
18953     (use (match_operand 5 "const_int_operand" ""))]
18954   "TARGET_64BIT"
18955 {
18956  if (ix86_expand_setmem (operands[0], operands[1],
18957                          operands[2], operands[3],
18958                          operands[4], operands[5]))
18959    DONE;
18960  else
18961    FAIL;
18962 })
18963
18964 ;; Most CPUs don't like single string operations
18965 ;; Handle this case here to simplify previous expander.
18966
18967 (define_expand "strset"
18968   [(set (match_operand 1 "memory_operand" "")
18969         (match_operand 2 "register_operand" ""))
18970    (parallel [(set (match_operand 0 "register_operand" "")
18971                    (match_dup 3))
18972               (clobber (reg:CC FLAGS_REG))])]
18973   ""
18974 {
18975   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18976     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18977
18978   /* If .md ever supports :P for Pmode, this can be directly
18979      in the pattern above.  */
18980   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18981                               GEN_INT (GET_MODE_SIZE (GET_MODE
18982                                                       (operands[2]))));
18983   if (TARGET_SINGLE_STRINGOP || optimize_size)
18984     {
18985       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18986                                       operands[3]));
18987       DONE;
18988     }
18989 })
18990
18991 (define_expand "strset_singleop"
18992   [(parallel [(set (match_operand 1 "memory_operand" "")
18993                    (match_operand 2 "register_operand" ""))
18994               (set (match_operand 0 "register_operand" "")
18995                    (match_operand 3 "" ""))])]
18996   "TARGET_SINGLE_STRINGOP || optimize_size"
18997   "")
18998
18999 (define_insn "*strsetdi_rex_1"
19000   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19001         (match_operand:DI 2 "register_operand" "a"))
19002    (set (match_operand:DI 0 "register_operand" "=D")
19003         (plus:DI (match_dup 1)
19004                  (const_int 8)))]
19005   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19006   "stosq"
19007   [(set_attr "type" "str")
19008    (set_attr "memory" "store")
19009    (set_attr "mode" "DI")])
19010
19011 (define_insn "*strsetsi_1"
19012   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19013         (match_operand:SI 2 "register_operand" "a"))
19014    (set (match_operand:SI 0 "register_operand" "=D")
19015         (plus:SI (match_dup 1)
19016                  (const_int 4)))]
19017   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19018   "{stosl|stosd}"
19019   [(set_attr "type" "str")
19020    (set_attr "memory" "store")
19021    (set_attr "mode" "SI")])
19022
19023 (define_insn "*strsetsi_rex_1"
19024   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19025         (match_operand:SI 2 "register_operand" "a"))
19026    (set (match_operand:DI 0 "register_operand" "=D")
19027         (plus:DI (match_dup 1)
19028                  (const_int 4)))]
19029   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19030   "{stosl|stosd}"
19031   [(set_attr "type" "str")
19032    (set_attr "memory" "store")
19033    (set_attr "mode" "SI")])
19034
19035 (define_insn "*strsethi_1"
19036   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19037         (match_operand:HI 2 "register_operand" "a"))
19038    (set (match_operand:SI 0 "register_operand" "=D")
19039         (plus:SI (match_dup 1)
19040                  (const_int 2)))]
19041   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19042   "stosw"
19043   [(set_attr "type" "str")
19044    (set_attr "memory" "store")
19045    (set_attr "mode" "HI")])
19046
19047 (define_insn "*strsethi_rex_1"
19048   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19049         (match_operand:HI 2 "register_operand" "a"))
19050    (set (match_operand:DI 0 "register_operand" "=D")
19051         (plus:DI (match_dup 1)
19052                  (const_int 2)))]
19053   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19054   "stosw"
19055   [(set_attr "type" "str")
19056    (set_attr "memory" "store")
19057    (set_attr "mode" "HI")])
19058
19059 (define_insn "*strsetqi_1"
19060   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19061         (match_operand:QI 2 "register_operand" "a"))
19062    (set (match_operand:SI 0 "register_operand" "=D")
19063         (plus:SI (match_dup 1)
19064                  (const_int 1)))]
19065   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19066   "stosb"
19067   [(set_attr "type" "str")
19068    (set_attr "memory" "store")
19069    (set_attr "mode" "QI")])
19070
19071 (define_insn "*strsetqi_rex_1"
19072   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19073         (match_operand:QI 2 "register_operand" "a"))
19074    (set (match_operand:DI 0 "register_operand" "=D")
19075         (plus:DI (match_dup 1)
19076                  (const_int 1)))]
19077   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19078   "stosb"
19079   [(set_attr "type" "str")
19080    (set_attr "memory" "store")
19081    (set_attr "mode" "QI")])
19082
19083 (define_expand "rep_stos"
19084   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19085               (set (match_operand 0 "register_operand" "")
19086                    (match_operand 4 "" ""))
19087               (set (match_operand 2 "memory_operand" "") (const_int 0))
19088               (use (match_operand 3 "register_operand" ""))
19089               (use (match_dup 1))])]
19090   ""
19091   "")
19092
19093 (define_insn "*rep_stosdi_rex64"
19094   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19095    (set (match_operand:DI 0 "register_operand" "=D")
19096         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19097                             (const_int 3))
19098                  (match_operand:DI 3 "register_operand" "0")))
19099    (set (mem:BLK (match_dup 3))
19100         (const_int 0))
19101    (use (match_operand:DI 2 "register_operand" "a"))
19102    (use (match_dup 4))]
19103   "TARGET_64BIT"
19104   "rep stosq"
19105   [(set_attr "type" "str")
19106    (set_attr "prefix_rep" "1")
19107    (set_attr "memory" "store")
19108    (set_attr "mode" "DI")])
19109
19110 (define_insn "*rep_stossi"
19111   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19112    (set (match_operand:SI 0 "register_operand" "=D")
19113         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19114                             (const_int 2))
19115                  (match_operand:SI 3 "register_operand" "0")))
19116    (set (mem:BLK (match_dup 3))
19117         (const_int 0))
19118    (use (match_operand:SI 2 "register_operand" "a"))
19119    (use (match_dup 4))]
19120   "!TARGET_64BIT"
19121   "rep stos{l|d}"
19122   [(set_attr "type" "str")
19123    (set_attr "prefix_rep" "1")
19124    (set_attr "memory" "store")
19125    (set_attr "mode" "SI")])
19126
19127 (define_insn "*rep_stossi_rex64"
19128   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19129    (set (match_operand:DI 0 "register_operand" "=D")
19130         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19131                             (const_int 2))
19132                  (match_operand:DI 3 "register_operand" "0")))
19133    (set (mem:BLK (match_dup 3))
19134         (const_int 0))
19135    (use (match_operand:SI 2 "register_operand" "a"))
19136    (use (match_dup 4))]
19137   "TARGET_64BIT"
19138   "rep stos{l|d}"
19139   [(set_attr "type" "str")
19140    (set_attr "prefix_rep" "1")
19141    (set_attr "memory" "store")
19142    (set_attr "mode" "SI")])
19143
19144 (define_insn "*rep_stosqi"
19145   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19146    (set (match_operand:SI 0 "register_operand" "=D")
19147         (plus:SI (match_operand:SI 3 "register_operand" "0")
19148                  (match_operand:SI 4 "register_operand" "1")))
19149    (set (mem:BLK (match_dup 3))
19150         (const_int 0))
19151    (use (match_operand:QI 2 "register_operand" "a"))
19152    (use (match_dup 4))]
19153   "!TARGET_64BIT"
19154   "rep stosb"
19155   [(set_attr "type" "str")
19156    (set_attr "prefix_rep" "1")
19157    (set_attr "memory" "store")
19158    (set_attr "mode" "QI")])
19159
19160 (define_insn "*rep_stosqi_rex64"
19161   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19162    (set (match_operand:DI 0 "register_operand" "=D")
19163         (plus:DI (match_operand:DI 3 "register_operand" "0")
19164                  (match_operand:DI 4 "register_operand" "1")))
19165    (set (mem:BLK (match_dup 3))
19166         (const_int 0))
19167    (use (match_operand:QI 2 "register_operand" "a"))
19168    (use (match_dup 4))]
19169   "TARGET_64BIT"
19170   "rep stosb"
19171   [(set_attr "type" "str")
19172    (set_attr "prefix_rep" "1")
19173    (set_attr "memory" "store")
19174    (set_attr "mode" "QI")])
19175
19176 (define_expand "cmpstrnsi"
19177   [(set (match_operand:SI 0 "register_operand" "")
19178         (compare:SI (match_operand:BLK 1 "general_operand" "")
19179                     (match_operand:BLK 2 "general_operand" "")))
19180    (use (match_operand 3 "general_operand" ""))
19181    (use (match_operand 4 "immediate_operand" ""))]
19182   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19183 {
19184   rtx addr1, addr2, out, outlow, count, countreg, align;
19185
19186   /* Can't use this if the user has appropriated esi or edi.  */
19187   if (global_regs[4] || global_regs[5])
19188     FAIL;
19189
19190   out = operands[0];
19191   if (!REG_P (out))
19192     out = gen_reg_rtx (SImode);
19193
19194   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19195   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19196   if (addr1 != XEXP (operands[1], 0))
19197     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19198   if (addr2 != XEXP (operands[2], 0))
19199     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19200
19201   count = operands[3];
19202   countreg = ix86_zero_extend_to_Pmode (count);
19203
19204   /* %%% Iff we are testing strict equality, we can use known alignment
19205      to good advantage.  This may be possible with combine, particularly
19206      once cc0 is dead.  */
19207   align = operands[4];
19208
19209   if (CONST_INT_P (count))
19210     {
19211       if (INTVAL (count) == 0)
19212         {
19213           emit_move_insn (operands[0], const0_rtx);
19214           DONE;
19215         }
19216       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19217                                      operands[1], operands[2]));
19218     }
19219   else
19220     {
19221       if (TARGET_64BIT)
19222         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19223       else
19224         emit_insn (gen_cmpsi_1 (countreg, countreg));
19225       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19226                                   operands[1], operands[2]));
19227     }
19228
19229   outlow = gen_lowpart (QImode, out);
19230   emit_insn (gen_cmpintqi (outlow));
19231   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19232
19233   if (operands[0] != out)
19234     emit_move_insn (operands[0], out);
19235
19236   DONE;
19237 })
19238
19239 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19240
19241 (define_expand "cmpintqi"
19242   [(set (match_dup 1)
19243         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19244    (set (match_dup 2)
19245         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19246    (parallel [(set (match_operand:QI 0 "register_operand" "")
19247                    (minus:QI (match_dup 1)
19248                              (match_dup 2)))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   ""
19251   "operands[1] = gen_reg_rtx (QImode);
19252    operands[2] = gen_reg_rtx (QImode);")
19253
19254 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19255 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19256
19257 (define_expand "cmpstrnqi_nz_1"
19258   [(parallel [(set (reg:CC FLAGS_REG)
19259                    (compare:CC (match_operand 4 "memory_operand" "")
19260                                (match_operand 5 "memory_operand" "")))
19261               (use (match_operand 2 "register_operand" ""))
19262               (use (match_operand:SI 3 "immediate_operand" ""))
19263               (clobber (match_operand 0 "register_operand" ""))
19264               (clobber (match_operand 1 "register_operand" ""))
19265               (clobber (match_dup 2))])]
19266   ""
19267   "")
19268
19269 (define_insn "*cmpstrnqi_nz_1"
19270   [(set (reg:CC FLAGS_REG)
19271         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19272                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19273    (use (match_operand:SI 6 "register_operand" "2"))
19274    (use (match_operand:SI 3 "immediate_operand" "i"))
19275    (clobber (match_operand:SI 0 "register_operand" "=S"))
19276    (clobber (match_operand:SI 1 "register_operand" "=D"))
19277    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19278   "!TARGET_64BIT"
19279   "repz cmpsb"
19280   [(set_attr "type" "str")
19281    (set_attr "mode" "QI")
19282    (set_attr "prefix_rep" "1")])
19283
19284 (define_insn "*cmpstrnqi_nz_rex_1"
19285   [(set (reg:CC FLAGS_REG)
19286         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19287                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19288    (use (match_operand:DI 6 "register_operand" "2"))
19289    (use (match_operand:SI 3 "immediate_operand" "i"))
19290    (clobber (match_operand:DI 0 "register_operand" "=S"))
19291    (clobber (match_operand:DI 1 "register_operand" "=D"))
19292    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19293   "TARGET_64BIT"
19294   "repz cmpsb"
19295   [(set_attr "type" "str")
19296    (set_attr "mode" "QI")
19297    (set_attr "prefix_rep" "1")])
19298
19299 ;; The same, but the count is not known to not be zero.
19300
19301 (define_expand "cmpstrnqi_1"
19302   [(parallel [(set (reg:CC FLAGS_REG)
19303                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19304                                      (const_int 0))
19305                   (compare:CC (match_operand 4 "memory_operand" "")
19306                               (match_operand 5 "memory_operand" ""))
19307                   (const_int 0)))
19308               (use (match_operand:SI 3 "immediate_operand" ""))
19309               (use (reg:CC FLAGS_REG))
19310               (clobber (match_operand 0 "register_operand" ""))
19311               (clobber (match_operand 1 "register_operand" ""))
19312               (clobber (match_dup 2))])]
19313   ""
19314   "")
19315
19316 (define_insn "*cmpstrnqi_1"
19317   [(set (reg:CC FLAGS_REG)
19318         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19319                              (const_int 0))
19320           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19321                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19322           (const_int 0)))
19323    (use (match_operand:SI 3 "immediate_operand" "i"))
19324    (use (reg:CC FLAGS_REG))
19325    (clobber (match_operand:SI 0 "register_operand" "=S"))
19326    (clobber (match_operand:SI 1 "register_operand" "=D"))
19327    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19328   "!TARGET_64BIT"
19329   "repz cmpsb"
19330   [(set_attr "type" "str")
19331    (set_attr "mode" "QI")
19332    (set_attr "prefix_rep" "1")])
19333
19334 (define_insn "*cmpstrnqi_rex_1"
19335   [(set (reg:CC FLAGS_REG)
19336         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19337                              (const_int 0))
19338           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19339                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19340           (const_int 0)))
19341    (use (match_operand:SI 3 "immediate_operand" "i"))
19342    (use (reg:CC FLAGS_REG))
19343    (clobber (match_operand:DI 0 "register_operand" "=S"))
19344    (clobber (match_operand:DI 1 "register_operand" "=D"))
19345    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19346   "TARGET_64BIT"
19347   "repz cmpsb"
19348   [(set_attr "type" "str")
19349    (set_attr "mode" "QI")
19350    (set_attr "prefix_rep" "1")])
19351
19352 (define_expand "strlensi"
19353   [(set (match_operand:SI 0 "register_operand" "")
19354         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19355                     (match_operand:QI 2 "immediate_operand" "")
19356                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19357   ""
19358 {
19359  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19360    DONE;
19361  else
19362    FAIL;
19363 })
19364
19365 (define_expand "strlendi"
19366   [(set (match_operand:DI 0 "register_operand" "")
19367         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19368                     (match_operand:QI 2 "immediate_operand" "")
19369                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19370   ""
19371 {
19372  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19373    DONE;
19374  else
19375    FAIL;
19376 })
19377
19378 (define_expand "strlenqi_1"
19379   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19380               (clobber (match_operand 1 "register_operand" ""))
19381               (clobber (reg:CC FLAGS_REG))])]
19382   ""
19383   "")
19384
19385 (define_insn "*strlenqi_1"
19386   [(set (match_operand:SI 0 "register_operand" "=&c")
19387         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19388                     (match_operand:QI 2 "register_operand" "a")
19389                     (match_operand:SI 3 "immediate_operand" "i")
19390                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19391    (clobber (match_operand:SI 1 "register_operand" "=D"))
19392    (clobber (reg:CC FLAGS_REG))]
19393   "!TARGET_64BIT"
19394   "repnz scasb"
19395   [(set_attr "type" "str")
19396    (set_attr "mode" "QI")
19397    (set_attr "prefix_rep" "1")])
19398
19399 (define_insn "*strlenqi_rex_1"
19400   [(set (match_operand:DI 0 "register_operand" "=&c")
19401         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19402                     (match_operand:QI 2 "register_operand" "a")
19403                     (match_operand:DI 3 "immediate_operand" "i")
19404                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19405    (clobber (match_operand:DI 1 "register_operand" "=D"))
19406    (clobber (reg:CC FLAGS_REG))]
19407   "TARGET_64BIT"
19408   "repnz scasb"
19409   [(set_attr "type" "str")
19410    (set_attr "mode" "QI")
19411    (set_attr "prefix_rep" "1")])
19412
19413 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19414 ;; handled in combine, but it is not currently up to the task.
19415 ;; When used for their truth value, the cmpstrn* expanders generate
19416 ;; code like this:
19417 ;;
19418 ;;   repz cmpsb
19419 ;;   seta       %al
19420 ;;   setb       %dl
19421 ;;   cmpb       %al, %dl
19422 ;;   jcc        label
19423 ;;
19424 ;; The intermediate three instructions are unnecessary.
19425
19426 ;; This one handles cmpstrn*_nz_1...
19427 (define_peephole2
19428   [(parallel[
19429      (set (reg:CC FLAGS_REG)
19430           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19431                       (mem:BLK (match_operand 5 "register_operand" ""))))
19432      (use (match_operand 6 "register_operand" ""))
19433      (use (match_operand:SI 3 "immediate_operand" ""))
19434      (clobber (match_operand 0 "register_operand" ""))
19435      (clobber (match_operand 1 "register_operand" ""))
19436      (clobber (match_operand 2 "register_operand" ""))])
19437    (set (match_operand:QI 7 "register_operand" "")
19438         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19439    (set (match_operand:QI 8 "register_operand" "")
19440         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19441    (set (reg FLAGS_REG)
19442         (compare (match_dup 7) (match_dup 8)))
19443   ]
19444   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19445   [(parallel[
19446      (set (reg:CC FLAGS_REG)
19447           (compare:CC (mem:BLK (match_dup 4))
19448                       (mem:BLK (match_dup 5))))
19449      (use (match_dup 6))
19450      (use (match_dup 3))
19451      (clobber (match_dup 0))
19452      (clobber (match_dup 1))
19453      (clobber (match_dup 2))])]
19454   "")
19455
19456 ;; ...and this one handles cmpstrn*_1.
19457 (define_peephole2
19458   [(parallel[
19459      (set (reg:CC FLAGS_REG)
19460           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19461                                (const_int 0))
19462             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19463                         (mem:BLK (match_operand 5 "register_operand" "")))
19464             (const_int 0)))
19465      (use (match_operand:SI 3 "immediate_operand" ""))
19466      (use (reg:CC FLAGS_REG))
19467      (clobber (match_operand 0 "register_operand" ""))
19468      (clobber (match_operand 1 "register_operand" ""))
19469      (clobber (match_operand 2 "register_operand" ""))])
19470    (set (match_operand:QI 7 "register_operand" "")
19471         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19472    (set (match_operand:QI 8 "register_operand" "")
19473         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19474    (set (reg FLAGS_REG)
19475         (compare (match_dup 7) (match_dup 8)))
19476   ]
19477   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19478   [(parallel[
19479      (set (reg:CC FLAGS_REG)
19480           (if_then_else:CC (ne (match_dup 6)
19481                                (const_int 0))
19482             (compare:CC (mem:BLK (match_dup 4))
19483                         (mem:BLK (match_dup 5)))
19484             (const_int 0)))
19485      (use (match_dup 3))
19486      (use (reg:CC FLAGS_REG))
19487      (clobber (match_dup 0))
19488      (clobber (match_dup 1))
19489      (clobber (match_dup 2))])]
19490   "")
19491
19492
19493 \f
19494 ;; Conditional move instructions.
19495
19496 (define_expand "movdicc"
19497   [(set (match_operand:DI 0 "register_operand" "")
19498         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19499                          (match_operand:DI 2 "general_operand" "")
19500                          (match_operand:DI 3 "general_operand" "")))]
19501   "TARGET_64BIT"
19502   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19503
19504 (define_insn "x86_movdicc_0_m1_rex64"
19505   [(set (match_operand:DI 0 "register_operand" "=r")
19506         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19507           (const_int -1)
19508           (const_int 0)))
19509    (clobber (reg:CC FLAGS_REG))]
19510   "TARGET_64BIT"
19511   "sbb{q}\t%0, %0"
19512   ; Since we don't have the proper number of operands for an alu insn,
19513   ; fill in all the blanks.
19514   [(set_attr "type" "alu")
19515    (set_attr "pent_pair" "pu")
19516    (set_attr "memory" "none")
19517    (set_attr "imm_disp" "false")
19518    (set_attr "mode" "DI")
19519    (set_attr "length_immediate" "0")])
19520
19521 (define_insn "*movdicc_c_rex64"
19522   [(set (match_operand:DI 0 "register_operand" "=r,r")
19523         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19524                                 [(reg FLAGS_REG) (const_int 0)])
19525                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19526                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19527   "TARGET_64BIT && TARGET_CMOVE
19528    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19529   "@
19530    cmov%O2%C1\t{%2, %0|%0, %2}
19531    cmov%O2%c1\t{%3, %0|%0, %3}"
19532   [(set_attr "type" "icmov")
19533    (set_attr "mode" "DI")])
19534
19535 (define_expand "movsicc"
19536   [(set (match_operand:SI 0 "register_operand" "")
19537         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19538                          (match_operand:SI 2 "general_operand" "")
19539                          (match_operand:SI 3 "general_operand" "")))]
19540   ""
19541   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19542
19543 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19544 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19545 ;; So just document what we're doing explicitly.
19546
19547 (define_insn "x86_movsicc_0_m1"
19548   [(set (match_operand:SI 0 "register_operand" "=r")
19549         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19550           (const_int -1)
19551           (const_int 0)))
19552    (clobber (reg:CC FLAGS_REG))]
19553   ""
19554   "sbb{l}\t%0, %0"
19555   ; Since we don't have the proper number of operands for an alu insn,
19556   ; fill in all the blanks.
19557   [(set_attr "type" "alu")
19558    (set_attr "pent_pair" "pu")
19559    (set_attr "memory" "none")
19560    (set_attr "imm_disp" "false")
19561    (set_attr "mode" "SI")
19562    (set_attr "length_immediate" "0")])
19563
19564 (define_insn "*movsicc_noc"
19565   [(set (match_operand:SI 0 "register_operand" "=r,r")
19566         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19567                                 [(reg FLAGS_REG) (const_int 0)])
19568                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19569                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19570   "TARGET_CMOVE
19571    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19572   "@
19573    cmov%O2%C1\t{%2, %0|%0, %2}
19574    cmov%O2%c1\t{%3, %0|%0, %3}"
19575   [(set_attr "type" "icmov")
19576    (set_attr "mode" "SI")])
19577
19578 (define_expand "movhicc"
19579   [(set (match_operand:HI 0 "register_operand" "")
19580         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19581                          (match_operand:HI 2 "general_operand" "")
19582                          (match_operand:HI 3 "general_operand" "")))]
19583   "TARGET_HIMODE_MATH"
19584   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19585
19586 (define_insn "*movhicc_noc"
19587   [(set (match_operand:HI 0 "register_operand" "=r,r")
19588         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19589                                 [(reg FLAGS_REG) (const_int 0)])
19590                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19591                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19592   "TARGET_CMOVE
19593    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19594   "@
19595    cmov%O2%C1\t{%2, %0|%0, %2}
19596    cmov%O2%c1\t{%3, %0|%0, %3}"
19597   [(set_attr "type" "icmov")
19598    (set_attr "mode" "HI")])
19599
19600 (define_expand "movqicc"
19601   [(set (match_operand:QI 0 "register_operand" "")
19602         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19603                          (match_operand:QI 2 "general_operand" "")
19604                          (match_operand:QI 3 "general_operand" "")))]
19605   "TARGET_QIMODE_MATH"
19606   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19607
19608 (define_insn_and_split "*movqicc_noc"
19609   [(set (match_operand:QI 0 "register_operand" "=r,r")
19610         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19611                                 [(match_operand 4 "flags_reg_operand" "")
19612                                  (const_int 0)])
19613                       (match_operand:QI 2 "register_operand" "r,0")
19614                       (match_operand:QI 3 "register_operand" "0,r")))]
19615   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19616   "#"
19617   "&& reload_completed"
19618   [(set (match_dup 0)
19619         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19620                       (match_dup 2)
19621                       (match_dup 3)))]
19622   "operands[0] = gen_lowpart (SImode, operands[0]);
19623    operands[2] = gen_lowpart (SImode, operands[2]);
19624    operands[3] = gen_lowpart (SImode, operands[3]);"
19625   [(set_attr "type" "icmov")
19626    (set_attr "mode" "SI")])
19627
19628 (define_expand "movsfcc"
19629   [(set (match_operand:SF 0 "register_operand" "")
19630         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19631                          (match_operand:SF 2 "register_operand" "")
19632                          (match_operand:SF 3 "register_operand" "")))]
19633   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19634   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19635
19636 (define_insn "*movsfcc_1_387"
19637   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19638         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19639                                 [(reg FLAGS_REG) (const_int 0)])
19640                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19641                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19642   "TARGET_80387 && TARGET_CMOVE
19643    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19644   "@
19645    fcmov%F1\t{%2, %0|%0, %2}
19646    fcmov%f1\t{%3, %0|%0, %3}
19647    cmov%O2%C1\t{%2, %0|%0, %2}
19648    cmov%O2%c1\t{%3, %0|%0, %3}"
19649   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19650    (set_attr "mode" "SF,SF,SI,SI")])
19651
19652 (define_expand "movdfcc"
19653   [(set (match_operand:DF 0 "register_operand" "")
19654         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19655                          (match_operand:DF 2 "register_operand" "")
19656                          (match_operand:DF 3 "register_operand" "")))]
19657   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19658   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19659
19660 (define_insn "*movdfcc_1"
19661   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19662         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19663                                 [(reg FLAGS_REG) (const_int 0)])
19664                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19665                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19666   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19667    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19668   "@
19669    fcmov%F1\t{%2, %0|%0, %2}
19670    fcmov%f1\t{%3, %0|%0, %3}
19671    #
19672    #"
19673   [(set_attr "type" "fcmov,fcmov,multi,multi")
19674    (set_attr "mode" "DF")])
19675
19676 (define_insn "*movdfcc_1_rex64"
19677   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19678         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19679                                 [(reg FLAGS_REG) (const_int 0)])
19680                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19681                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19682   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19683    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19684   "@
19685    fcmov%F1\t{%2, %0|%0, %2}
19686    fcmov%f1\t{%3, %0|%0, %3}
19687    cmov%O2%C1\t{%2, %0|%0, %2}
19688    cmov%O2%c1\t{%3, %0|%0, %3}"
19689   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19690    (set_attr "mode" "DF")])
19691
19692 (define_split
19693   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19694         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19695                                 [(match_operand 4 "flags_reg_operand" "")
19696                                  (const_int 0)])
19697                       (match_operand:DF 2 "nonimmediate_operand" "")
19698                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19699   "!TARGET_64BIT && reload_completed"
19700   [(set (match_dup 2)
19701         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19702                       (match_dup 5)
19703                       (match_dup 7)))
19704    (set (match_dup 3)
19705         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19706                       (match_dup 6)
19707                       (match_dup 8)))]
19708   "split_di (operands+2, 1, operands+5, operands+6);
19709    split_di (operands+3, 1, operands+7, operands+8);
19710    split_di (operands, 1, operands+2, operands+3);")
19711
19712 (define_expand "movxfcc"
19713   [(set (match_operand:XF 0 "register_operand" "")
19714         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19715                          (match_operand:XF 2 "register_operand" "")
19716                          (match_operand:XF 3 "register_operand" "")))]
19717   "TARGET_80387 && TARGET_CMOVE"
19718   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19719
19720 (define_insn "*movxfcc_1"
19721   [(set (match_operand:XF 0 "register_operand" "=f,f")
19722         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19723                                 [(reg FLAGS_REG) (const_int 0)])
19724                       (match_operand:XF 2 "register_operand" "f,0")
19725                       (match_operand:XF 3 "register_operand" "0,f")))]
19726   "TARGET_80387 && TARGET_CMOVE"
19727   "@
19728    fcmov%F1\t{%2, %0|%0, %2}
19729    fcmov%f1\t{%3, %0|%0, %3}"
19730   [(set_attr "type" "fcmov")
19731    (set_attr "mode" "XF")])
19732
19733 ;; SSE5 conditional move
19734 (define_insn "*sse5_pcmov_<mode>"
19735   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,x")
19736         (if_then_else:MODEF 
19737           (match_operand:MODEF 1 "nonimmediate_operand" "xm,x,0,0")
19738           (match_operand:MODEF 2 "nonimmediate_operand" "0,0,x,xm")
19739           (match_operand:MODEF 3 "vector_move_operand" "x,xm,xm,x")))]
19740   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19741   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19742   [(set_attr "type" "sse4arg")])
19743
19744 ;; These versions of the min/max patterns are intentionally ignorant of
19745 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19746 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19747 ;; are undefined in this condition, we're certain this is correct.
19748
19749 (define_insn "sminsf3"
19750   [(set (match_operand:SF 0 "register_operand" "=x")
19751         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19752                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19753   "TARGET_SSE_MATH"
19754   "minss\t{%2, %0|%0, %2}"
19755   [(set_attr "type" "sseadd")
19756    (set_attr "mode" "SF")])
19757
19758 (define_insn "smaxsf3"
19759   [(set (match_operand:SF 0 "register_operand" "=x")
19760         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19761                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19762   "TARGET_SSE_MATH"
19763   "maxss\t{%2, %0|%0, %2}"
19764   [(set_attr "type" "sseadd")
19765    (set_attr "mode" "SF")])
19766
19767 (define_insn "smindf3"
19768   [(set (match_operand:DF 0 "register_operand" "=x")
19769         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19770                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19771   "TARGET_SSE2 && TARGET_SSE_MATH"
19772   "minsd\t{%2, %0|%0, %2}"
19773   [(set_attr "type" "sseadd")
19774    (set_attr "mode" "DF")])
19775
19776 (define_insn "smaxdf3"
19777   [(set (match_operand:DF 0 "register_operand" "=x")
19778         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19779                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19780   "TARGET_SSE2 && TARGET_SSE_MATH"
19781   "maxsd\t{%2, %0|%0, %2}"
19782   [(set_attr "type" "sseadd")
19783    (set_attr "mode" "DF")])
19784
19785 ;; These versions of the min/max patterns implement exactly the operations
19786 ;;   min = (op1 < op2 ? op1 : op2)
19787 ;;   max = (!(op1 < op2) ? op1 : op2)
19788 ;; Their operands are not commutative, and thus they may be used in the
19789 ;; presence of -0.0 and NaN.
19790
19791 (define_insn "*ieee_sminsf3"
19792   [(set (match_operand:SF 0 "register_operand" "=x")
19793         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19794                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19795                    UNSPEC_IEEE_MIN))]
19796   "TARGET_SSE_MATH"
19797   "minss\t{%2, %0|%0, %2}"
19798   [(set_attr "type" "sseadd")
19799    (set_attr "mode" "SF")])
19800
19801 (define_insn "*ieee_smaxsf3"
19802   [(set (match_operand:SF 0 "register_operand" "=x")
19803         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19804                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19805                    UNSPEC_IEEE_MAX))]
19806   "TARGET_SSE_MATH"
19807   "maxss\t{%2, %0|%0, %2}"
19808   [(set_attr "type" "sseadd")
19809    (set_attr "mode" "SF")])
19810
19811 (define_insn "*ieee_smindf3"
19812   [(set (match_operand:DF 0 "register_operand" "=x")
19813         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19814                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19815                    UNSPEC_IEEE_MIN))]
19816   "TARGET_SSE2 && TARGET_SSE_MATH"
19817   "minsd\t{%2, %0|%0, %2}"
19818   [(set_attr "type" "sseadd")
19819    (set_attr "mode" "DF")])
19820
19821 (define_insn "*ieee_smaxdf3"
19822   [(set (match_operand:DF 0 "register_operand" "=x")
19823         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19824                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19825                    UNSPEC_IEEE_MAX))]
19826   "TARGET_SSE2 && TARGET_SSE_MATH"
19827   "maxsd\t{%2, %0|%0, %2}"
19828   [(set_attr "type" "sseadd")
19829    (set_attr "mode" "DF")])
19830
19831 ;; Make two stack loads independent:
19832 ;;   fld aa              fld aa
19833 ;;   fld %st(0)     ->   fld bb
19834 ;;   fmul bb             fmul %st(1), %st
19835 ;;
19836 ;; Actually we only match the last two instructions for simplicity.
19837 (define_peephole2
19838   [(set (match_operand 0 "fp_register_operand" "")
19839         (match_operand 1 "fp_register_operand" ""))
19840    (set (match_dup 0)
19841         (match_operator 2 "binary_fp_operator"
19842            [(match_dup 0)
19843             (match_operand 3 "memory_operand" "")]))]
19844   "REGNO (operands[0]) != REGNO (operands[1])"
19845   [(set (match_dup 0) (match_dup 3))
19846    (set (match_dup 0) (match_dup 4))]
19847
19848   ;; The % modifier is not operational anymore in peephole2's, so we have to
19849   ;; swap the operands manually in the case of addition and multiplication.
19850   "if (COMMUTATIVE_ARITH_P (operands[2]))
19851      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19852                                  operands[0], operands[1]);
19853    else
19854      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19855                                  operands[1], operands[0]);")
19856
19857 ;; Conditional addition patterns
19858 (define_expand "addqicc"
19859   [(match_operand:QI 0 "register_operand" "")
19860    (match_operand 1 "comparison_operator" "")
19861    (match_operand:QI 2 "register_operand" "")
19862    (match_operand:QI 3 "const_int_operand" "")]
19863   ""
19864   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19865
19866 (define_expand "addhicc"
19867   [(match_operand:HI 0 "register_operand" "")
19868    (match_operand 1 "comparison_operator" "")
19869    (match_operand:HI 2 "register_operand" "")
19870    (match_operand:HI 3 "const_int_operand" "")]
19871   ""
19872   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19873
19874 (define_expand "addsicc"
19875   [(match_operand:SI 0 "register_operand" "")
19876    (match_operand 1 "comparison_operator" "")
19877    (match_operand:SI 2 "register_operand" "")
19878    (match_operand:SI 3 "const_int_operand" "")]
19879   ""
19880   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19881
19882 (define_expand "adddicc"
19883   [(match_operand:DI 0 "register_operand" "")
19884    (match_operand 1 "comparison_operator" "")
19885    (match_operand:DI 2 "register_operand" "")
19886    (match_operand:DI 3 "const_int_operand" "")]
19887   "TARGET_64BIT"
19888   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19889
19890 \f
19891 ;; Misc patterns (?)
19892
19893 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19894 ;; Otherwise there will be nothing to keep
19895 ;;
19896 ;; [(set (reg ebp) (reg esp))]
19897 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19898 ;;  (clobber (eflags)]
19899 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19900 ;;
19901 ;; in proper program order.
19902 (define_insn "pro_epilogue_adjust_stack_1"
19903   [(set (match_operand:SI 0 "register_operand" "=r,r")
19904         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19905                  (match_operand:SI 2 "immediate_operand" "i,i")))
19906    (clobber (reg:CC FLAGS_REG))
19907    (clobber (mem:BLK (scratch)))]
19908   "!TARGET_64BIT"
19909 {
19910   switch (get_attr_type (insn))
19911     {
19912     case TYPE_IMOV:
19913       return "mov{l}\t{%1, %0|%0, %1}";
19914
19915     case TYPE_ALU:
19916       if (CONST_INT_P (operands[2])
19917           && (INTVAL (operands[2]) == 128
19918               || (INTVAL (operands[2]) < 0
19919                   && INTVAL (operands[2]) != -128)))
19920         {
19921           operands[2] = GEN_INT (-INTVAL (operands[2]));
19922           return "sub{l}\t{%2, %0|%0, %2}";
19923         }
19924       return "add{l}\t{%2, %0|%0, %2}";
19925
19926     case TYPE_LEA:
19927       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19928       return "lea{l}\t{%a2, %0|%0, %a2}";
19929
19930     default:
19931       gcc_unreachable ();
19932     }
19933 }
19934   [(set (attr "type")
19935         (cond [(eq_attr "alternative" "0")
19936                  (const_string "alu")
19937                (match_operand:SI 2 "const0_operand" "")
19938                  (const_string "imov")
19939               ]
19940               (const_string "lea")))
19941    (set_attr "mode" "SI")])
19942
19943 (define_insn "pro_epilogue_adjust_stack_rex64"
19944   [(set (match_operand:DI 0 "register_operand" "=r,r")
19945         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19946                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19947    (clobber (reg:CC FLAGS_REG))
19948    (clobber (mem:BLK (scratch)))]
19949   "TARGET_64BIT"
19950 {
19951   switch (get_attr_type (insn))
19952     {
19953     case TYPE_IMOV:
19954       return "mov{q}\t{%1, %0|%0, %1}";
19955
19956     case TYPE_ALU:
19957       if (CONST_INT_P (operands[2])
19958           /* Avoid overflows.  */
19959           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19960           && (INTVAL (operands[2]) == 128
19961               || (INTVAL (operands[2]) < 0
19962                   && INTVAL (operands[2]) != -128)))
19963         {
19964           operands[2] = GEN_INT (-INTVAL (operands[2]));
19965           return "sub{q}\t{%2, %0|%0, %2}";
19966         }
19967       return "add{q}\t{%2, %0|%0, %2}";
19968
19969     case TYPE_LEA:
19970       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19971       return "lea{q}\t{%a2, %0|%0, %a2}";
19972
19973     default:
19974       gcc_unreachable ();
19975     }
19976 }
19977   [(set (attr "type")
19978         (cond [(eq_attr "alternative" "0")
19979                  (const_string "alu")
19980                (match_operand:DI 2 "const0_operand" "")
19981                  (const_string "imov")
19982               ]
19983               (const_string "lea")))
19984    (set_attr "mode" "DI")])
19985
19986 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19987   [(set (match_operand:DI 0 "register_operand" "=r,r")
19988         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19989                  (match_operand:DI 3 "immediate_operand" "i,i")))
19990    (use (match_operand:DI 2 "register_operand" "r,r"))
19991    (clobber (reg:CC FLAGS_REG))
19992    (clobber (mem:BLK (scratch)))]
19993   "TARGET_64BIT"
19994 {
19995   switch (get_attr_type (insn))
19996     {
19997     case TYPE_ALU:
19998       return "add{q}\t{%2, %0|%0, %2}";
19999
20000     case TYPE_LEA:
20001       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20002       return "lea{q}\t{%a2, %0|%0, %a2}";
20003
20004     default:
20005       gcc_unreachable ();
20006     }
20007 }
20008   [(set_attr "type" "alu,lea")
20009    (set_attr "mode" "DI")])
20010
20011 (define_insn "allocate_stack_worker_32"
20012   [(set (match_operand:SI 0 "register_operand" "+a")
20013         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20014    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20015    (clobber (reg:CC FLAGS_REG))]
20016   "!TARGET_64BIT && TARGET_STACK_PROBE"
20017   "call\t__alloca"
20018   [(set_attr "type" "multi")
20019    (set_attr "length" "5")])
20020
20021 (define_insn "allocate_stack_worker_64"
20022   [(set (match_operand:DI 0 "register_operand" "=a")
20023         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20024    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20025    (clobber (reg:DI R10_REG))
20026    (clobber (reg:DI R11_REG))
20027    (clobber (reg:CC FLAGS_REG))]
20028   "TARGET_64BIT && TARGET_STACK_PROBE"
20029   "call\t___chkstk"
20030   [(set_attr "type" "multi")
20031    (set_attr "length" "5")])
20032
20033 (define_expand "allocate_stack"
20034   [(match_operand 0 "register_operand" "")
20035    (match_operand 1 "general_operand" "")]
20036   "TARGET_STACK_PROBE"
20037 {
20038   rtx x;
20039
20040 #ifndef CHECK_STACK_LIMIT
20041 #define CHECK_STACK_LIMIT 0
20042 #endif
20043
20044   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20045       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20046     {
20047       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20048                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20049       if (x != stack_pointer_rtx)
20050         emit_move_insn (stack_pointer_rtx, x);
20051     }
20052   else
20053     {
20054       x = copy_to_mode_reg (Pmode, operands[1]);
20055       if (TARGET_64BIT)
20056         x = gen_allocate_stack_worker_64 (x);
20057       else
20058         x = gen_allocate_stack_worker_32 (x);
20059       emit_insn (x);
20060     }
20061
20062   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20063   DONE;
20064 })
20065
20066 (define_expand "builtin_setjmp_receiver"
20067   [(label_ref (match_operand 0 "" ""))]
20068   "!TARGET_64BIT && flag_pic"
20069 {
20070   if (TARGET_MACHO)
20071     {
20072       rtx xops[3];
20073       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20074       rtx label_rtx = gen_label_rtx ();
20075       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20076       xops[0] = xops[1] = picreg;
20077       xops[2] = gen_rtx_CONST (SImode,
20078                   gen_rtx_MINUS (SImode,
20079                     gen_rtx_LABEL_REF (SImode, label_rtx),
20080                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
20081       ix86_expand_binary_operator (MINUS, SImode, xops);
20082     }
20083   else
20084     emit_insn (gen_set_got (pic_offset_table_rtx));
20085   DONE;
20086 })
20087 \f
20088 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20089
20090 (define_split
20091   [(set (match_operand 0 "register_operand" "")
20092         (match_operator 3 "promotable_binary_operator"
20093            [(match_operand 1 "register_operand" "")
20094             (match_operand 2 "aligned_operand" "")]))
20095    (clobber (reg:CC FLAGS_REG))]
20096   "! TARGET_PARTIAL_REG_STALL && reload_completed
20097    && ((GET_MODE (operands[0]) == HImode
20098         && ((!optimize_size && !TARGET_FAST_PREFIX)
20099             /* ??? next two lines just !satisfies_constraint_K (...) */
20100             || !CONST_INT_P (operands[2])
20101             || satisfies_constraint_K (operands[2])))
20102        || (GET_MODE (operands[0]) == QImode
20103            && (TARGET_PROMOTE_QImode || optimize_size)))"
20104   [(parallel [(set (match_dup 0)
20105                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20106               (clobber (reg:CC FLAGS_REG))])]
20107   "operands[0] = gen_lowpart (SImode, operands[0]);
20108    operands[1] = gen_lowpart (SImode, operands[1]);
20109    if (GET_CODE (operands[3]) != ASHIFT)
20110      operands[2] = gen_lowpart (SImode, operands[2]);
20111    PUT_MODE (operands[3], SImode);")
20112
20113 ; Promote the QImode tests, as i386 has encoding of the AND
20114 ; instruction with 32-bit sign-extended immediate and thus the
20115 ; instruction size is unchanged, except in the %eax case for
20116 ; which it is increased by one byte, hence the ! optimize_size.
20117 (define_split
20118   [(set (match_operand 0 "flags_reg_operand" "")
20119         (match_operator 2 "compare_operator"
20120           [(and (match_operand 3 "aligned_operand" "")
20121                 (match_operand 4 "const_int_operand" ""))
20122            (const_int 0)]))
20123    (set (match_operand 1 "register_operand" "")
20124         (and (match_dup 3) (match_dup 4)))]
20125   "! TARGET_PARTIAL_REG_STALL && reload_completed
20126    && ! optimize_size
20127    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20128        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20129    /* Ensure that the operand will remain sign-extended immediate.  */
20130    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20131   [(parallel [(set (match_dup 0)
20132                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20133                                     (const_int 0)]))
20134               (set (match_dup 1)
20135                    (and:SI (match_dup 3) (match_dup 4)))])]
20136 {
20137   operands[4]
20138     = gen_int_mode (INTVAL (operands[4])
20139                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20140   operands[1] = gen_lowpart (SImode, operands[1]);
20141   operands[3] = gen_lowpart (SImode, operands[3]);
20142 })
20143
20144 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20145 ; the TEST instruction with 32-bit sign-extended immediate and thus
20146 ; the instruction size would at least double, which is not what we
20147 ; want even with ! optimize_size.
20148 (define_split
20149   [(set (match_operand 0 "flags_reg_operand" "")
20150         (match_operator 1 "compare_operator"
20151           [(and (match_operand:HI 2 "aligned_operand" "")
20152                 (match_operand:HI 3 "const_int_operand" ""))
20153            (const_int 0)]))]
20154   "! TARGET_PARTIAL_REG_STALL && reload_completed
20155    && ! TARGET_FAST_PREFIX
20156    && ! optimize_size
20157    /* Ensure that the operand will remain sign-extended immediate.  */
20158    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20159   [(set (match_dup 0)
20160         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20161                          (const_int 0)]))]
20162 {
20163   operands[3]
20164     = gen_int_mode (INTVAL (operands[3])
20165                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20166   operands[2] = gen_lowpart (SImode, operands[2]);
20167 })
20168
20169 (define_split
20170   [(set (match_operand 0 "register_operand" "")
20171         (neg (match_operand 1 "register_operand" "")))
20172    (clobber (reg:CC FLAGS_REG))]
20173   "! TARGET_PARTIAL_REG_STALL && reload_completed
20174    && (GET_MODE (operands[0]) == HImode
20175        || (GET_MODE (operands[0]) == QImode
20176            && (TARGET_PROMOTE_QImode || optimize_size)))"
20177   [(parallel [(set (match_dup 0)
20178                    (neg:SI (match_dup 1)))
20179               (clobber (reg:CC FLAGS_REG))])]
20180   "operands[0] = gen_lowpart (SImode, operands[0]);
20181    operands[1] = gen_lowpart (SImode, operands[1]);")
20182
20183 (define_split
20184   [(set (match_operand 0 "register_operand" "")
20185         (not (match_operand 1 "register_operand" "")))]
20186   "! TARGET_PARTIAL_REG_STALL && reload_completed
20187    && (GET_MODE (operands[0]) == HImode
20188        || (GET_MODE (operands[0]) == QImode
20189            && (TARGET_PROMOTE_QImode || optimize_size)))"
20190   [(set (match_dup 0)
20191         (not:SI (match_dup 1)))]
20192   "operands[0] = gen_lowpart (SImode, operands[0]);
20193    operands[1] = gen_lowpart (SImode, operands[1]);")
20194
20195 (define_split
20196   [(set (match_operand 0 "register_operand" "")
20197         (if_then_else (match_operator 1 "comparison_operator"
20198                                 [(reg FLAGS_REG) (const_int 0)])
20199                       (match_operand 2 "register_operand" "")
20200                       (match_operand 3 "register_operand" "")))]
20201   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20202    && (GET_MODE (operands[0]) == HImode
20203        || (GET_MODE (operands[0]) == QImode
20204            && (TARGET_PROMOTE_QImode || optimize_size)))"
20205   [(set (match_dup 0)
20206         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20207   "operands[0] = gen_lowpart (SImode, operands[0]);
20208    operands[2] = gen_lowpart (SImode, operands[2]);
20209    operands[3] = gen_lowpart (SImode, operands[3]);")
20210
20211 \f
20212 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20213 ;; transform a complex memory operation into two memory to register operations.
20214
20215 ;; Don't push memory operands
20216 (define_peephole2
20217   [(set (match_operand:SI 0 "push_operand" "")
20218         (match_operand:SI 1 "memory_operand" ""))
20219    (match_scratch:SI 2 "r")]
20220   "!optimize_size && !TARGET_PUSH_MEMORY
20221    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20222   [(set (match_dup 2) (match_dup 1))
20223    (set (match_dup 0) (match_dup 2))]
20224   "")
20225
20226 (define_peephole2
20227   [(set (match_operand:DI 0 "push_operand" "")
20228         (match_operand:DI 1 "memory_operand" ""))
20229    (match_scratch:DI 2 "r")]
20230   "!optimize_size && !TARGET_PUSH_MEMORY
20231    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20232   [(set (match_dup 2) (match_dup 1))
20233    (set (match_dup 0) (match_dup 2))]
20234   "")
20235
20236 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20237 ;; SImode pushes.
20238 (define_peephole2
20239   [(set (match_operand:SF 0 "push_operand" "")
20240         (match_operand:SF 1 "memory_operand" ""))
20241    (match_scratch:SF 2 "r")]
20242   "!optimize_size && !TARGET_PUSH_MEMORY
20243    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20244   [(set (match_dup 2) (match_dup 1))
20245    (set (match_dup 0) (match_dup 2))]
20246   "")
20247
20248 (define_peephole2
20249   [(set (match_operand:HI 0 "push_operand" "")
20250         (match_operand:HI 1 "memory_operand" ""))
20251    (match_scratch:HI 2 "r")]
20252   "!optimize_size && !TARGET_PUSH_MEMORY
20253    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20254   [(set (match_dup 2) (match_dup 1))
20255    (set (match_dup 0) (match_dup 2))]
20256   "")
20257
20258 (define_peephole2
20259   [(set (match_operand:QI 0 "push_operand" "")
20260         (match_operand:QI 1 "memory_operand" ""))
20261    (match_scratch:QI 2 "q")]
20262   "!optimize_size && !TARGET_PUSH_MEMORY
20263    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20264   [(set (match_dup 2) (match_dup 1))
20265    (set (match_dup 0) (match_dup 2))]
20266   "")
20267
20268 ;; Don't move an immediate directly to memory when the instruction
20269 ;; gets too big.
20270 (define_peephole2
20271   [(match_scratch:SI 1 "r")
20272    (set (match_operand:SI 0 "memory_operand" "")
20273         (const_int 0))]
20274   "! optimize_size
20275    && ! TARGET_USE_MOV0
20276    && TARGET_SPLIT_LONG_MOVES
20277    && get_attr_length (insn) >= ix86_cost->large_insn
20278    && peep2_regno_dead_p (0, FLAGS_REG)"
20279   [(parallel [(set (match_dup 1) (const_int 0))
20280               (clobber (reg:CC FLAGS_REG))])
20281    (set (match_dup 0) (match_dup 1))]
20282   "")
20283
20284 (define_peephole2
20285   [(match_scratch:HI 1 "r")
20286    (set (match_operand:HI 0 "memory_operand" "")
20287         (const_int 0))]
20288   "! optimize_size
20289    && ! TARGET_USE_MOV0
20290    && TARGET_SPLIT_LONG_MOVES
20291    && get_attr_length (insn) >= ix86_cost->large_insn
20292    && peep2_regno_dead_p (0, FLAGS_REG)"
20293   [(parallel [(set (match_dup 2) (const_int 0))
20294               (clobber (reg:CC FLAGS_REG))])
20295    (set (match_dup 0) (match_dup 1))]
20296   "operands[2] = gen_lowpart (SImode, operands[1]);")
20297
20298 (define_peephole2
20299   [(match_scratch:QI 1 "q")
20300    (set (match_operand:QI 0 "memory_operand" "")
20301         (const_int 0))]
20302   "! optimize_size
20303    && ! TARGET_USE_MOV0
20304    && TARGET_SPLIT_LONG_MOVES
20305    && get_attr_length (insn) >= ix86_cost->large_insn
20306    && peep2_regno_dead_p (0, FLAGS_REG)"
20307   [(parallel [(set (match_dup 2) (const_int 0))
20308               (clobber (reg:CC FLAGS_REG))])
20309    (set (match_dup 0) (match_dup 1))]
20310   "operands[2] = gen_lowpart (SImode, operands[1]);")
20311
20312 (define_peephole2
20313   [(match_scratch:SI 2 "r")
20314    (set (match_operand:SI 0 "memory_operand" "")
20315         (match_operand:SI 1 "immediate_operand" ""))]
20316   "! optimize_size
20317    && TARGET_SPLIT_LONG_MOVES
20318    && get_attr_length (insn) >= ix86_cost->large_insn"
20319   [(set (match_dup 2) (match_dup 1))
20320    (set (match_dup 0) (match_dup 2))]
20321   "")
20322
20323 (define_peephole2
20324   [(match_scratch:HI 2 "r")
20325    (set (match_operand:HI 0 "memory_operand" "")
20326         (match_operand:HI 1 "immediate_operand" ""))]
20327   "! optimize_size
20328    && TARGET_SPLIT_LONG_MOVES
20329    && get_attr_length (insn) >= ix86_cost->large_insn"
20330   [(set (match_dup 2) (match_dup 1))
20331    (set (match_dup 0) (match_dup 2))]
20332   "")
20333
20334 (define_peephole2
20335   [(match_scratch:QI 2 "q")
20336    (set (match_operand:QI 0 "memory_operand" "")
20337         (match_operand:QI 1 "immediate_operand" ""))]
20338   "! optimize_size
20339    && TARGET_SPLIT_LONG_MOVES
20340    && get_attr_length (insn) >= ix86_cost->large_insn"
20341   [(set (match_dup 2) (match_dup 1))
20342    (set (match_dup 0) (match_dup 2))]
20343   "")
20344
20345 ;; Don't compare memory with zero, load and use a test instead.
20346 (define_peephole2
20347   [(set (match_operand 0 "flags_reg_operand" "")
20348         (match_operator 1 "compare_operator"
20349           [(match_operand:SI 2 "memory_operand" "")
20350            (const_int 0)]))
20351    (match_scratch:SI 3 "r")]
20352   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20353   [(set (match_dup 3) (match_dup 2))
20354    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20355   "")
20356
20357 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20358 ;; Don't split NOTs with a displacement operand, because resulting XOR
20359 ;; will not be pairable anyway.
20360 ;;
20361 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20362 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20363 ;; so this split helps here as well.
20364 ;;
20365 ;; Note: Can't do this as a regular split because we can't get proper
20366 ;; lifetime information then.
20367
20368 (define_peephole2
20369   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20370         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20371   "!optimize_size
20372    && ((TARGET_NOT_UNPAIRABLE
20373         && (!MEM_P (operands[0])
20374             || !memory_displacement_operand (operands[0], SImode)))
20375        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20376    && peep2_regno_dead_p (0, FLAGS_REG)"
20377   [(parallel [(set (match_dup 0)
20378                    (xor:SI (match_dup 1) (const_int -1)))
20379               (clobber (reg:CC FLAGS_REG))])]
20380   "")
20381
20382 (define_peephole2
20383   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20384         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20385   "!optimize_size
20386    && ((TARGET_NOT_UNPAIRABLE
20387         && (!MEM_P (operands[0])
20388             || !memory_displacement_operand (operands[0], HImode)))
20389        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20390    && peep2_regno_dead_p (0, FLAGS_REG)"
20391   [(parallel [(set (match_dup 0)
20392                    (xor:HI (match_dup 1) (const_int -1)))
20393               (clobber (reg:CC FLAGS_REG))])]
20394   "")
20395
20396 (define_peephole2
20397   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20398         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20399   "!optimize_size
20400    && ((TARGET_NOT_UNPAIRABLE
20401         && (!MEM_P (operands[0])
20402             || !memory_displacement_operand (operands[0], QImode)))
20403        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20404    && peep2_regno_dead_p (0, FLAGS_REG)"
20405   [(parallel [(set (match_dup 0)
20406                    (xor:QI (match_dup 1) (const_int -1)))
20407               (clobber (reg:CC FLAGS_REG))])]
20408   "")
20409
20410 ;; Non pairable "test imm, reg" instructions can be translated to
20411 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20412 ;; byte opcode instead of two, have a short form for byte operands),
20413 ;; so do it for other CPUs as well.  Given that the value was dead,
20414 ;; this should not create any new dependencies.  Pass on the sub-word
20415 ;; versions if we're concerned about partial register stalls.
20416
20417 (define_peephole2
20418   [(set (match_operand 0 "flags_reg_operand" "")
20419         (match_operator 1 "compare_operator"
20420           [(and:SI (match_operand:SI 2 "register_operand" "")
20421                    (match_operand:SI 3 "immediate_operand" ""))
20422            (const_int 0)]))]
20423   "ix86_match_ccmode (insn, CCNOmode)
20424    && (true_regnum (operands[2]) != 0
20425        || satisfies_constraint_K (operands[3]))
20426    && peep2_reg_dead_p (1, operands[2])"
20427   [(parallel
20428      [(set (match_dup 0)
20429            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20430                             (const_int 0)]))
20431       (set (match_dup 2)
20432            (and:SI (match_dup 2) (match_dup 3)))])]
20433   "")
20434
20435 ;; We don't need to handle HImode case, because it will be promoted to SImode
20436 ;; on ! TARGET_PARTIAL_REG_STALL
20437
20438 (define_peephole2
20439   [(set (match_operand 0 "flags_reg_operand" "")
20440         (match_operator 1 "compare_operator"
20441           [(and:QI (match_operand:QI 2 "register_operand" "")
20442                    (match_operand:QI 3 "immediate_operand" ""))
20443            (const_int 0)]))]
20444   "! TARGET_PARTIAL_REG_STALL
20445    && ix86_match_ccmode (insn, CCNOmode)
20446    && true_regnum (operands[2]) != 0
20447    && peep2_reg_dead_p (1, operands[2])"
20448   [(parallel
20449      [(set (match_dup 0)
20450            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20451                             (const_int 0)]))
20452       (set (match_dup 2)
20453            (and:QI (match_dup 2) (match_dup 3)))])]
20454   "")
20455
20456 (define_peephole2
20457   [(set (match_operand 0 "flags_reg_operand" "")
20458         (match_operator 1 "compare_operator"
20459           [(and:SI
20460              (zero_extract:SI
20461                (match_operand 2 "ext_register_operand" "")
20462                (const_int 8)
20463                (const_int 8))
20464              (match_operand 3 "const_int_operand" ""))
20465            (const_int 0)]))]
20466   "! TARGET_PARTIAL_REG_STALL
20467    && ix86_match_ccmode (insn, CCNOmode)
20468    && true_regnum (operands[2]) != 0
20469    && peep2_reg_dead_p (1, operands[2])"
20470   [(parallel [(set (match_dup 0)
20471                    (match_op_dup 1
20472                      [(and:SI
20473                         (zero_extract:SI
20474                           (match_dup 2)
20475                           (const_int 8)
20476                           (const_int 8))
20477                         (match_dup 3))
20478                       (const_int 0)]))
20479               (set (zero_extract:SI (match_dup 2)
20480                                     (const_int 8)
20481                                     (const_int 8))
20482                    (and:SI
20483                      (zero_extract:SI
20484                        (match_dup 2)
20485                        (const_int 8)
20486                        (const_int 8))
20487                      (match_dup 3)))])]
20488   "")
20489
20490 ;; Don't do logical operations with memory inputs.
20491 (define_peephole2
20492   [(match_scratch:SI 2 "r")
20493    (parallel [(set (match_operand:SI 0 "register_operand" "")
20494                    (match_operator:SI 3 "arith_or_logical_operator"
20495                      [(match_dup 0)
20496                       (match_operand:SI 1 "memory_operand" "")]))
20497               (clobber (reg:CC FLAGS_REG))])]
20498   "! optimize_size && ! TARGET_READ_MODIFY"
20499   [(set (match_dup 2) (match_dup 1))
20500    (parallel [(set (match_dup 0)
20501                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20502               (clobber (reg:CC FLAGS_REG))])]
20503   "")
20504
20505 (define_peephole2
20506   [(match_scratch:SI 2 "r")
20507    (parallel [(set (match_operand:SI 0 "register_operand" "")
20508                    (match_operator:SI 3 "arith_or_logical_operator"
20509                      [(match_operand:SI 1 "memory_operand" "")
20510                       (match_dup 0)]))
20511               (clobber (reg:CC FLAGS_REG))])]
20512   "! optimize_size && ! TARGET_READ_MODIFY"
20513   [(set (match_dup 2) (match_dup 1))
20514    (parallel [(set (match_dup 0)
20515                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20516               (clobber (reg:CC FLAGS_REG))])]
20517   "")
20518
20519 ; Don't do logical operations with memory outputs
20520 ;
20521 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20522 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20523 ; the same decoder scheduling characteristics as the original.
20524
20525 (define_peephole2
20526   [(match_scratch:SI 2 "r")
20527    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20528                    (match_operator:SI 3 "arith_or_logical_operator"
20529                      [(match_dup 0)
20530                       (match_operand:SI 1 "nonmemory_operand" "")]))
20531               (clobber (reg:CC FLAGS_REG))])]
20532   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20533   [(set (match_dup 2) (match_dup 0))
20534    (parallel [(set (match_dup 2)
20535                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20536               (clobber (reg:CC FLAGS_REG))])
20537    (set (match_dup 0) (match_dup 2))]
20538   "")
20539
20540 (define_peephole2
20541   [(match_scratch:SI 2 "r")
20542    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20543                    (match_operator:SI 3 "arith_or_logical_operator"
20544                      [(match_operand:SI 1 "nonmemory_operand" "")
20545                       (match_dup 0)]))
20546               (clobber (reg:CC FLAGS_REG))])]
20547   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20548   [(set (match_dup 2) (match_dup 0))
20549    (parallel [(set (match_dup 2)
20550                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20551               (clobber (reg:CC FLAGS_REG))])
20552    (set (match_dup 0) (match_dup 2))]
20553   "")
20554
20555 ;; Attempt to always use XOR for zeroing registers.
20556 (define_peephole2
20557   [(set (match_operand 0 "register_operand" "")
20558         (match_operand 1 "const0_operand" ""))]
20559   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20560    && (! TARGET_USE_MOV0 || optimize_size)
20561    && GENERAL_REG_P (operands[0])
20562    && peep2_regno_dead_p (0, FLAGS_REG)"
20563   [(parallel [(set (match_dup 0) (const_int 0))
20564               (clobber (reg:CC FLAGS_REG))])]
20565 {
20566   operands[0] = gen_lowpart (word_mode, operands[0]);
20567 })
20568
20569 (define_peephole2
20570   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20571         (const_int 0))]
20572   "(GET_MODE (operands[0]) == QImode
20573     || GET_MODE (operands[0]) == HImode)
20574    && (! TARGET_USE_MOV0 || optimize_size)
20575    && peep2_regno_dead_p (0, FLAGS_REG)"
20576   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20577               (clobber (reg:CC FLAGS_REG))])])
20578
20579 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20580 (define_peephole2
20581   [(set (match_operand 0 "register_operand" "")
20582         (const_int -1))]
20583   "(GET_MODE (operands[0]) == HImode
20584     || GET_MODE (operands[0]) == SImode
20585     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20586    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20587    && peep2_regno_dead_p (0, FLAGS_REG)"
20588   [(parallel [(set (match_dup 0) (const_int -1))
20589               (clobber (reg:CC FLAGS_REG))])]
20590   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20591                               operands[0]);")
20592
20593 ;; Attempt to convert simple leas to adds. These can be created by
20594 ;; move expanders.
20595 (define_peephole2
20596   [(set (match_operand:SI 0 "register_operand" "")
20597         (plus:SI (match_dup 0)
20598                  (match_operand:SI 1 "nonmemory_operand" "")))]
20599   "peep2_regno_dead_p (0, FLAGS_REG)"
20600   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20601               (clobber (reg:CC FLAGS_REG))])]
20602   "")
20603
20604 (define_peephole2
20605   [(set (match_operand:SI 0 "register_operand" "")
20606         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20607                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20608   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20609   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20610               (clobber (reg:CC FLAGS_REG))])]
20611   "operands[2] = gen_lowpart (SImode, operands[2]);")
20612
20613 (define_peephole2
20614   [(set (match_operand:DI 0 "register_operand" "")
20615         (plus:DI (match_dup 0)
20616                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20617   "peep2_regno_dead_p (0, FLAGS_REG)"
20618   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20619               (clobber (reg:CC FLAGS_REG))])]
20620   "")
20621
20622 (define_peephole2
20623   [(set (match_operand:SI 0 "register_operand" "")
20624         (mult:SI (match_dup 0)
20625                  (match_operand:SI 1 "const_int_operand" "")))]
20626   "exact_log2 (INTVAL (operands[1])) >= 0
20627    && peep2_regno_dead_p (0, FLAGS_REG)"
20628   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20629               (clobber (reg:CC FLAGS_REG))])]
20630   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20631
20632 (define_peephole2
20633   [(set (match_operand:DI 0 "register_operand" "")
20634         (mult:DI (match_dup 0)
20635                  (match_operand:DI 1 "const_int_operand" "")))]
20636   "exact_log2 (INTVAL (operands[1])) >= 0
20637    && peep2_regno_dead_p (0, FLAGS_REG)"
20638   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20639               (clobber (reg:CC FLAGS_REG))])]
20640   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20641
20642 (define_peephole2
20643   [(set (match_operand:SI 0 "register_operand" "")
20644         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20645                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20646   "exact_log2 (INTVAL (operands[2])) >= 0
20647    && REGNO (operands[0]) == REGNO (operands[1])
20648    && peep2_regno_dead_p (0, FLAGS_REG)"
20649   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20650               (clobber (reg:CC FLAGS_REG))])]
20651   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20652
20653 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20654 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20655 ;; many CPUs it is also faster, since special hardware to avoid esp
20656 ;; dependencies is present.
20657
20658 ;; While some of these conversions may be done using splitters, we use peepholes
20659 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20660
20661 ;; Convert prologue esp subtractions to push.
20662 ;; We need register to push.  In order to keep verify_flow_info happy we have
20663 ;; two choices
20664 ;; - use scratch and clobber it in order to avoid dependencies
20665 ;; - use already live register
20666 ;; We can't use the second way right now, since there is no reliable way how to
20667 ;; verify that given register is live.  First choice will also most likely in
20668 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20669 ;; call clobbered registers are dead.  We may want to use base pointer as an
20670 ;; alternative when no register is available later.
20671
20672 (define_peephole2
20673   [(match_scratch:SI 0 "r")
20674    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20675               (clobber (reg:CC FLAGS_REG))
20676               (clobber (mem:BLK (scratch)))])]
20677   "optimize_size || !TARGET_SUB_ESP_4"
20678   [(clobber (match_dup 0))
20679    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20680               (clobber (mem:BLK (scratch)))])])
20681
20682 (define_peephole2
20683   [(match_scratch:SI 0 "r")
20684    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20685               (clobber (reg:CC FLAGS_REG))
20686               (clobber (mem:BLK (scratch)))])]
20687   "optimize_size || !TARGET_SUB_ESP_8"
20688   [(clobber (match_dup 0))
20689    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20690    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20691               (clobber (mem:BLK (scratch)))])])
20692
20693 ;; Convert esp subtractions to push.
20694 (define_peephole2
20695   [(match_scratch:SI 0 "r")
20696    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20697               (clobber (reg:CC FLAGS_REG))])]
20698   "optimize_size || !TARGET_SUB_ESP_4"
20699   [(clobber (match_dup 0))
20700    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20701
20702 (define_peephole2
20703   [(match_scratch:SI 0 "r")
20704    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20705               (clobber (reg:CC FLAGS_REG))])]
20706   "optimize_size || !TARGET_SUB_ESP_8"
20707   [(clobber (match_dup 0))
20708    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20709    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20710
20711 ;; Convert epilogue deallocator to pop.
20712 (define_peephole2
20713   [(match_scratch:SI 0 "r")
20714    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20715               (clobber (reg:CC FLAGS_REG))
20716               (clobber (mem:BLK (scratch)))])]
20717   "optimize_size || !TARGET_ADD_ESP_4"
20718   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20719               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20720               (clobber (mem:BLK (scratch)))])]
20721   "")
20722
20723 ;; Two pops case is tricky, since pop causes dependency on destination register.
20724 ;; We use two registers if available.
20725 (define_peephole2
20726   [(match_scratch:SI 0 "r")
20727    (match_scratch:SI 1 "r")
20728    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20729               (clobber (reg:CC FLAGS_REG))
20730               (clobber (mem:BLK (scratch)))])]
20731   "optimize_size || !TARGET_ADD_ESP_8"
20732   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20733               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20734               (clobber (mem:BLK (scratch)))])
20735    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20736               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20737   "")
20738
20739 (define_peephole2
20740   [(match_scratch:SI 0 "r")
20741    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20742               (clobber (reg:CC FLAGS_REG))
20743               (clobber (mem:BLK (scratch)))])]
20744   "optimize_size"
20745   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20746               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20747               (clobber (mem:BLK (scratch)))])
20748    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20749               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20750   "")
20751
20752 ;; Convert esp additions to pop.
20753 (define_peephole2
20754   [(match_scratch:SI 0 "r")
20755    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20756               (clobber (reg:CC FLAGS_REG))])]
20757   ""
20758   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20759               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20760   "")
20761
20762 ;; Two pops case is tricky, since pop causes dependency on destination register.
20763 ;; We use two registers if available.
20764 (define_peephole2
20765   [(match_scratch:SI 0 "r")
20766    (match_scratch:SI 1 "r")
20767    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20768               (clobber (reg:CC FLAGS_REG))])]
20769   ""
20770   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20771               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20772    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20773               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20774   "")
20775
20776 (define_peephole2
20777   [(match_scratch:SI 0 "r")
20778    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20779               (clobber (reg:CC FLAGS_REG))])]
20780   "optimize_size"
20781   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20782               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20783    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20784               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20785   "")
20786 \f
20787 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20788 ;; required and register dies.  Similarly for 128 to plus -128.
20789 (define_peephole2
20790   [(set (match_operand 0 "flags_reg_operand" "")
20791         (match_operator 1 "compare_operator"
20792           [(match_operand 2 "register_operand" "")
20793            (match_operand 3 "const_int_operand" "")]))]
20794   "(INTVAL (operands[3]) == -1
20795     || INTVAL (operands[3]) == 1
20796     || INTVAL (operands[3]) == 128)
20797    && ix86_match_ccmode (insn, CCGCmode)
20798    && peep2_reg_dead_p (1, operands[2])"
20799   [(parallel [(set (match_dup 0)
20800                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20801               (clobber (match_dup 2))])]
20802   "")
20803 \f
20804 (define_peephole2
20805   [(match_scratch:DI 0 "r")
20806    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20807               (clobber (reg:CC FLAGS_REG))
20808               (clobber (mem:BLK (scratch)))])]
20809   "optimize_size || !TARGET_SUB_ESP_4"
20810   [(clobber (match_dup 0))
20811    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20812               (clobber (mem:BLK (scratch)))])])
20813
20814 (define_peephole2
20815   [(match_scratch:DI 0 "r")
20816    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20817               (clobber (reg:CC FLAGS_REG))
20818               (clobber (mem:BLK (scratch)))])]
20819   "optimize_size || !TARGET_SUB_ESP_8"
20820   [(clobber (match_dup 0))
20821    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20822    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20823               (clobber (mem:BLK (scratch)))])])
20824
20825 ;; Convert esp subtractions to push.
20826 (define_peephole2
20827   [(match_scratch:DI 0 "r")
20828    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20829               (clobber (reg:CC FLAGS_REG))])]
20830   "optimize_size || !TARGET_SUB_ESP_4"
20831   [(clobber (match_dup 0))
20832    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20833
20834 (define_peephole2
20835   [(match_scratch:DI 0 "r")
20836    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20837               (clobber (reg:CC FLAGS_REG))])]
20838   "optimize_size || !TARGET_SUB_ESP_8"
20839   [(clobber (match_dup 0))
20840    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20841    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20842
20843 ;; Convert epilogue deallocator to pop.
20844 (define_peephole2
20845   [(match_scratch:DI 0 "r")
20846    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20847               (clobber (reg:CC FLAGS_REG))
20848               (clobber (mem:BLK (scratch)))])]
20849   "optimize_size || !TARGET_ADD_ESP_4"
20850   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20851               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20852               (clobber (mem:BLK (scratch)))])]
20853   "")
20854
20855 ;; Two pops case is tricky, since pop causes dependency on destination register.
20856 ;; We use two registers if available.
20857 (define_peephole2
20858   [(match_scratch:DI 0 "r")
20859    (match_scratch:DI 1 "r")
20860    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20861               (clobber (reg:CC FLAGS_REG))
20862               (clobber (mem:BLK (scratch)))])]
20863   "optimize_size || !TARGET_ADD_ESP_8"
20864   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20865               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20866               (clobber (mem:BLK (scratch)))])
20867    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20868               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20869   "")
20870
20871 (define_peephole2
20872   [(match_scratch:DI 0 "r")
20873    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20874               (clobber (reg:CC FLAGS_REG))
20875               (clobber (mem:BLK (scratch)))])]
20876   "optimize_size"
20877   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20878               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20879               (clobber (mem:BLK (scratch)))])
20880    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20881               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20882   "")
20883
20884 ;; Convert esp additions to pop.
20885 (define_peephole2
20886   [(match_scratch:DI 0 "r")
20887    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20888               (clobber (reg:CC FLAGS_REG))])]
20889   ""
20890   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20891               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20892   "")
20893
20894 ;; Two pops case is tricky, since pop causes dependency on destination register.
20895 ;; We use two registers if available.
20896 (define_peephole2
20897   [(match_scratch:DI 0 "r")
20898    (match_scratch:DI 1 "r")
20899    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20900               (clobber (reg:CC FLAGS_REG))])]
20901   ""
20902   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20903               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20904    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20905               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20906   "")
20907
20908 (define_peephole2
20909   [(match_scratch:DI 0 "r")
20910    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20911               (clobber (reg:CC FLAGS_REG))])]
20912   "optimize_size"
20913   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20914               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20915    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20916               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20917   "")
20918 \f
20919 ;; Convert imul by three, five and nine into lea
20920 (define_peephole2
20921   [(parallel
20922     [(set (match_operand:SI 0 "register_operand" "")
20923           (mult:SI (match_operand:SI 1 "register_operand" "")
20924                    (match_operand:SI 2 "const_int_operand" "")))
20925      (clobber (reg:CC FLAGS_REG))])]
20926   "INTVAL (operands[2]) == 3
20927    || INTVAL (operands[2]) == 5
20928    || INTVAL (operands[2]) == 9"
20929   [(set (match_dup 0)
20930         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20931                  (match_dup 1)))]
20932   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20933
20934 (define_peephole2
20935   [(parallel
20936     [(set (match_operand:SI 0 "register_operand" "")
20937           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20938                    (match_operand:SI 2 "const_int_operand" "")))
20939      (clobber (reg:CC FLAGS_REG))])]
20940   "!optimize_size
20941    && (INTVAL (operands[2]) == 3
20942        || INTVAL (operands[2]) == 5
20943        || INTVAL (operands[2]) == 9)"
20944   [(set (match_dup 0) (match_dup 1))
20945    (set (match_dup 0)
20946         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20947                  (match_dup 0)))]
20948   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20949
20950 (define_peephole2
20951   [(parallel
20952     [(set (match_operand:DI 0 "register_operand" "")
20953           (mult:DI (match_operand:DI 1 "register_operand" "")
20954                    (match_operand:DI 2 "const_int_operand" "")))
20955      (clobber (reg:CC FLAGS_REG))])]
20956   "TARGET_64BIT
20957    && (INTVAL (operands[2]) == 3
20958        || INTVAL (operands[2]) == 5
20959        || INTVAL (operands[2]) == 9)"
20960   [(set (match_dup 0)
20961         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20962                  (match_dup 1)))]
20963   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20964
20965 (define_peephole2
20966   [(parallel
20967     [(set (match_operand:DI 0 "register_operand" "")
20968           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20969                    (match_operand:DI 2 "const_int_operand" "")))
20970      (clobber (reg:CC FLAGS_REG))])]
20971   "TARGET_64BIT
20972    && !optimize_size
20973    && (INTVAL (operands[2]) == 3
20974        || INTVAL (operands[2]) == 5
20975        || INTVAL (operands[2]) == 9)"
20976   [(set (match_dup 0) (match_dup 1))
20977    (set (match_dup 0)
20978         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20979                  (match_dup 0)))]
20980   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20981
20982 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20983 ;; imul $32bit_imm, reg, reg is direct decoded.
20984 (define_peephole2
20985   [(match_scratch:DI 3 "r")
20986    (parallel [(set (match_operand:DI 0 "register_operand" "")
20987                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20988                             (match_operand:DI 2 "immediate_operand" "")))
20989               (clobber (reg:CC FLAGS_REG))])]
20990   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20991    && !satisfies_constraint_K (operands[2])"
20992   [(set (match_dup 3) (match_dup 1))
20993    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20994               (clobber (reg:CC FLAGS_REG))])]
20995 "")
20996
20997 (define_peephole2
20998   [(match_scratch:SI 3 "r")
20999    (parallel [(set (match_operand:SI 0 "register_operand" "")
21000                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21001                             (match_operand:SI 2 "immediate_operand" "")))
21002               (clobber (reg:CC FLAGS_REG))])]
21003   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21004    && !satisfies_constraint_K (operands[2])"
21005   [(set (match_dup 3) (match_dup 1))
21006    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21007               (clobber (reg:CC FLAGS_REG))])]
21008 "")
21009
21010 (define_peephole2
21011   [(match_scratch:SI 3 "r")
21012    (parallel [(set (match_operand:DI 0 "register_operand" "")
21013                    (zero_extend:DI
21014                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21015                               (match_operand:SI 2 "immediate_operand" ""))))
21016               (clobber (reg:CC FLAGS_REG))])]
21017   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21018    && !satisfies_constraint_K (operands[2])"
21019   [(set (match_dup 3) (match_dup 1))
21020    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21021               (clobber (reg:CC FLAGS_REG))])]
21022 "")
21023
21024 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21025 ;; Convert it into imul reg, reg
21026 ;; It would be better to force assembler to encode instruction using long
21027 ;; immediate, but there is apparently no way to do so.
21028 (define_peephole2
21029   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21030                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21031                             (match_operand:DI 2 "const_int_operand" "")))
21032               (clobber (reg:CC FLAGS_REG))])
21033    (match_scratch:DI 3 "r")]
21034   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21035    && satisfies_constraint_K (operands[2])"
21036   [(set (match_dup 3) (match_dup 2))
21037    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21038               (clobber (reg:CC FLAGS_REG))])]
21039 {
21040   if (!rtx_equal_p (operands[0], operands[1]))
21041     emit_move_insn (operands[0], operands[1]);
21042 })
21043
21044 (define_peephole2
21045   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21046                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21047                             (match_operand:SI 2 "const_int_operand" "")))
21048               (clobber (reg:CC FLAGS_REG))])
21049    (match_scratch:SI 3 "r")]
21050   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21051    && satisfies_constraint_K (operands[2])"
21052   [(set (match_dup 3) (match_dup 2))
21053    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21054               (clobber (reg:CC FLAGS_REG))])]
21055 {
21056   if (!rtx_equal_p (operands[0], operands[1]))
21057     emit_move_insn (operands[0], operands[1]);
21058 })
21059
21060 (define_peephole2
21061   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21062                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21063                             (match_operand:HI 2 "immediate_operand" "")))
21064               (clobber (reg:CC FLAGS_REG))])
21065    (match_scratch:HI 3 "r")]
21066   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
21067   [(set (match_dup 3) (match_dup 2))
21068    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21069               (clobber (reg:CC FLAGS_REG))])]
21070 {
21071   if (!rtx_equal_p (operands[0], operands[1]))
21072     emit_move_insn (operands[0], operands[1]);
21073 })
21074
21075 ;; After splitting up read-modify operations, array accesses with memory
21076 ;; operands might end up in form:
21077 ;;  sall    $2, %eax
21078 ;;  movl    4(%esp), %edx
21079 ;;  addl    %edx, %eax
21080 ;; instead of pre-splitting:
21081 ;;  sall    $2, %eax
21082 ;;  addl    4(%esp), %eax
21083 ;; Turn it into:
21084 ;;  movl    4(%esp), %edx
21085 ;;  leal    (%edx,%eax,4), %eax
21086
21087 (define_peephole2
21088   [(parallel [(set (match_operand 0 "register_operand" "")
21089                    (ashift (match_operand 1 "register_operand" "")
21090                            (match_operand 2 "const_int_operand" "")))
21091                (clobber (reg:CC FLAGS_REG))])
21092    (set (match_operand 3 "register_operand")
21093         (match_operand 4 "x86_64_general_operand" ""))
21094    (parallel [(set (match_operand 5 "register_operand" "")
21095                    (plus (match_operand 6 "register_operand" "")
21096                          (match_operand 7 "register_operand" "")))
21097                    (clobber (reg:CC FLAGS_REG))])]
21098   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21099    /* Validate MODE for lea.  */
21100    && ((!TARGET_PARTIAL_REG_STALL
21101         && (GET_MODE (operands[0]) == QImode
21102             || GET_MODE (operands[0]) == HImode))
21103        || GET_MODE (operands[0]) == SImode
21104        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21105    /* We reorder load and the shift.  */
21106    && !rtx_equal_p (operands[1], operands[3])
21107    && !reg_overlap_mentioned_p (operands[0], operands[4])
21108    /* Last PLUS must consist of operand 0 and 3.  */
21109    && !rtx_equal_p (operands[0], operands[3])
21110    && (rtx_equal_p (operands[3], operands[6])
21111        || rtx_equal_p (operands[3], operands[7]))
21112    && (rtx_equal_p (operands[0], operands[6])
21113        || rtx_equal_p (operands[0], operands[7]))
21114    /* The intermediate operand 0 must die or be same as output.  */
21115    && (rtx_equal_p (operands[0], operands[5])
21116        || peep2_reg_dead_p (3, operands[0]))"
21117   [(set (match_dup 3) (match_dup 4))
21118    (set (match_dup 0) (match_dup 1))]
21119 {
21120   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21121   int scale = 1 << INTVAL (operands[2]);
21122   rtx index = gen_lowpart (Pmode, operands[1]);
21123   rtx base = gen_lowpart (Pmode, operands[3]);
21124   rtx dest = gen_lowpart (mode, operands[5]);
21125
21126   operands[1] = gen_rtx_PLUS (Pmode, base,
21127                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21128   if (mode != Pmode)
21129     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21130   operands[0] = dest;
21131 })
21132 \f
21133 ;; Call-value patterns last so that the wildcard operand does not
21134 ;; disrupt insn-recog's switch tables.
21135
21136 (define_insn "*call_value_pop_0"
21137   [(set (match_operand 0 "" "")
21138         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21139               (match_operand:SI 2 "" "")))
21140    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21141                             (match_operand:SI 3 "immediate_operand" "")))]
21142   "!TARGET_64BIT"
21143 {
21144   if (SIBLING_CALL_P (insn))
21145     return "jmp\t%P1";
21146   else
21147     return "call\t%P1";
21148 }
21149   [(set_attr "type" "callv")])
21150
21151 (define_insn "*call_value_pop_1"
21152   [(set (match_operand 0 "" "")
21153         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21154               (match_operand:SI 2 "" "")))
21155    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21156                             (match_operand:SI 3 "immediate_operand" "i")))]
21157   "!TARGET_64BIT"
21158 {
21159   if (constant_call_address_operand (operands[1], Pmode))
21160     {
21161       if (SIBLING_CALL_P (insn))
21162         return "jmp\t%P1";
21163       else
21164         return "call\t%P1";
21165     }
21166   if (SIBLING_CALL_P (insn))
21167     return "jmp\t%A1";
21168   else
21169     return "call\t%A1";
21170 }
21171   [(set_attr "type" "callv")])
21172
21173 (define_insn "*call_value_0"
21174   [(set (match_operand 0 "" "")
21175         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21176               (match_operand:SI 2 "" "")))]
21177   "!TARGET_64BIT"
21178 {
21179   if (SIBLING_CALL_P (insn))
21180     return "jmp\t%P1";
21181   else
21182     return "call\t%P1";
21183 }
21184   [(set_attr "type" "callv")])
21185
21186 (define_insn "*call_value_0_rex64"
21187   [(set (match_operand 0 "" "")
21188         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21189               (match_operand:DI 2 "const_int_operand" "")))]
21190   "TARGET_64BIT"
21191 {
21192   if (SIBLING_CALL_P (insn))
21193     return "jmp\t%P1";
21194   else
21195     return "call\t%P1";
21196 }
21197   [(set_attr "type" "callv")])
21198
21199 (define_insn "*call_value_1"
21200   [(set (match_operand 0 "" "")
21201         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21202               (match_operand:SI 2 "" "")))]
21203   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21204 {
21205   if (constant_call_address_operand (operands[1], Pmode))
21206     return "call\t%P1";
21207   return "call\t%A1";
21208 }
21209   [(set_attr "type" "callv")])
21210
21211 (define_insn "*sibcall_value_1"
21212   [(set (match_operand 0 "" "")
21213         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21214               (match_operand:SI 2 "" "")))]
21215   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21216 {
21217   if (constant_call_address_operand (operands[1], Pmode))
21218     return "jmp\t%P1";
21219   return "jmp\t%A1";
21220 }
21221   [(set_attr "type" "callv")])
21222
21223 (define_insn "*call_value_1_rex64"
21224   [(set (match_operand 0 "" "")
21225         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21226               (match_operand:DI 2 "" "")))]
21227   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21228    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21229 {
21230   if (constant_call_address_operand (operands[1], Pmode))
21231     return "call\t%P1";
21232   return "call\t%A1";
21233 }
21234   [(set_attr "type" "callv")])
21235
21236 (define_insn "*call_value_1_rex64_large"
21237   [(set (match_operand 0 "" "")
21238         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21239               (match_operand:DI 2 "" "")))]
21240   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21241   "call\t%A1"
21242   [(set_attr "type" "callv")])
21243
21244 (define_insn "*sibcall_value_1_rex64"
21245   [(set (match_operand 0 "" "")
21246         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21247               (match_operand:DI 2 "" "")))]
21248   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21249   "jmp\t%P1"
21250   [(set_attr "type" "callv")])
21251
21252 (define_insn "*sibcall_value_1_rex64_v"
21253   [(set (match_operand 0 "" "")
21254         (call (mem:QI (reg:DI R11_REG))
21255               (match_operand:DI 1 "" "")))]
21256   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21257   "jmp\t*%%r11"
21258   [(set_attr "type" "callv")])
21259 \f
21260 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21261 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21262 ;; caught for use by garbage collectors and the like.  Using an insn that
21263 ;; maps to SIGILL makes it more likely the program will rightfully die.
21264 ;; Keeping with tradition, "6" is in honor of #UD.
21265 (define_insn "trap"
21266   [(trap_if (const_int 1) (const_int 6))]
21267   ""
21268   { return ASM_SHORT "0x0b0f"; }
21269   [(set_attr "length" "2")])
21270
21271 (define_expand "sse_prologue_save"
21272   [(parallel [(set (match_operand:BLK 0 "" "")
21273                    (unspec:BLK [(reg:DI 21)
21274                                 (reg:DI 22)
21275                                 (reg:DI 23)
21276                                 (reg:DI 24)
21277                                 (reg:DI 25)
21278                                 (reg:DI 26)
21279                                 (reg:DI 27)
21280                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21281               (use (match_operand:DI 1 "register_operand" ""))
21282               (use (match_operand:DI 2 "immediate_operand" ""))
21283               (use (label_ref:DI (match_operand 3 "" "")))])]
21284   "TARGET_64BIT"
21285   "")
21286
21287 (define_insn "*sse_prologue_save_insn"
21288   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21289                           (match_operand:DI 4 "const_int_operand" "n")))
21290         (unspec:BLK [(reg:DI 21)
21291                      (reg:DI 22)
21292                      (reg:DI 23)
21293                      (reg:DI 24)
21294                      (reg:DI 25)
21295                      (reg:DI 26)
21296                      (reg:DI 27)
21297                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21298    (use (match_operand:DI 1 "register_operand" "r"))
21299    (use (match_operand:DI 2 "const_int_operand" "i"))
21300    (use (label_ref:DI (match_operand 3 "" "X")))]
21301   "TARGET_64BIT
21302    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21303    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21304   "*
21305 {
21306   int i;
21307   operands[0] = gen_rtx_MEM (Pmode,
21308                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21309   output_asm_insn (\"jmp\\t%A1\", operands);
21310   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21311     {
21312       operands[4] = adjust_address (operands[0], DImode, i*16);
21313       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21314       PUT_MODE (operands[4], TImode);
21315       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21316         output_asm_insn (\"rex\", operands);
21317       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21318     }
21319   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21320                              CODE_LABEL_NUMBER (operands[3]));
21321   return \"\";
21322 }
21323   "
21324   [(set_attr "type" "other")
21325    (set_attr "length_immediate" "0")
21326    (set_attr "length_address" "0")
21327    (set_attr "length" "135")
21328    (set_attr "memory" "store")
21329    (set_attr "modrm" "0")
21330    (set_attr "mode" "DI")])
21331
21332 (define_expand "prefetch"
21333   [(prefetch (match_operand 0 "address_operand" "")
21334              (match_operand:SI 1 "const_int_operand" "")
21335              (match_operand:SI 2 "const_int_operand" ""))]
21336   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21337 {
21338   int rw = INTVAL (operands[1]);
21339   int locality = INTVAL (operands[2]);
21340
21341   gcc_assert (rw == 0 || rw == 1);
21342   gcc_assert (locality >= 0 && locality <= 3);
21343   gcc_assert (GET_MODE (operands[0]) == Pmode
21344               || GET_MODE (operands[0]) == VOIDmode);
21345
21346   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21347      supported by SSE counterpart or the SSE prefetch is not available
21348      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21349      of locality.  */
21350   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21351     operands[2] = GEN_INT (3);
21352   else
21353     operands[1] = const0_rtx;
21354 })
21355
21356 (define_insn "*prefetch_sse"
21357   [(prefetch (match_operand:SI 0 "address_operand" "p")
21358              (const_int 0)
21359              (match_operand:SI 1 "const_int_operand" ""))]
21360   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21361 {
21362   static const char * const patterns[4] = {
21363    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21364   };
21365
21366   int locality = INTVAL (operands[1]);
21367   gcc_assert (locality >= 0 && locality <= 3);
21368
21369   return patterns[locality];
21370 }
21371   [(set_attr "type" "sse")
21372    (set_attr "memory" "none")])
21373
21374 (define_insn "*prefetch_sse_rex"
21375   [(prefetch (match_operand:DI 0 "address_operand" "p")
21376              (const_int 0)
21377              (match_operand:SI 1 "const_int_operand" ""))]
21378   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21379 {
21380   static const char * const patterns[4] = {
21381    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21382   };
21383
21384   int locality = INTVAL (operands[1]);
21385   gcc_assert (locality >= 0 && locality <= 3);
21386
21387   return patterns[locality];
21388 }
21389   [(set_attr "type" "sse")
21390    (set_attr "memory" "none")])
21391
21392 (define_insn "*prefetch_3dnow"
21393   [(prefetch (match_operand:SI 0 "address_operand" "p")
21394              (match_operand:SI 1 "const_int_operand" "n")
21395              (const_int 3))]
21396   "TARGET_3DNOW && !TARGET_64BIT"
21397 {
21398   if (INTVAL (operands[1]) == 0)
21399     return "prefetch\t%a0";
21400   else
21401     return "prefetchw\t%a0";
21402 }
21403   [(set_attr "type" "mmx")
21404    (set_attr "memory" "none")])
21405
21406 (define_insn "*prefetch_3dnow_rex"
21407   [(prefetch (match_operand:DI 0 "address_operand" "p")
21408              (match_operand:SI 1 "const_int_operand" "n")
21409              (const_int 3))]
21410   "TARGET_3DNOW && TARGET_64BIT"
21411 {
21412   if (INTVAL (operands[1]) == 0)
21413     return "prefetch\t%a0";
21414   else
21415     return "prefetchw\t%a0";
21416 }
21417   [(set_attr "type" "mmx")
21418    (set_attr "memory" "none")])
21419
21420 (define_expand "stack_protect_set"
21421   [(match_operand 0 "memory_operand" "")
21422    (match_operand 1 "memory_operand" "")]
21423   ""
21424 {
21425 #ifdef TARGET_THREAD_SSP_OFFSET
21426   if (TARGET_64BIT)
21427     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21428                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21429   else
21430     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21431                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21432 #else
21433   if (TARGET_64BIT)
21434     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21435   else
21436     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21437 #endif
21438   DONE;
21439 })
21440
21441 (define_insn "stack_protect_set_si"
21442   [(set (match_operand:SI 0 "memory_operand" "=m")
21443         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21444    (set (match_scratch:SI 2 "=&r") (const_int 0))
21445    (clobber (reg:CC FLAGS_REG))]
21446   ""
21447   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21448   [(set_attr "type" "multi")])
21449
21450 (define_insn "stack_protect_set_di"
21451   [(set (match_operand:DI 0 "memory_operand" "=m")
21452         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21453    (set (match_scratch:DI 2 "=&r") (const_int 0))
21454    (clobber (reg:CC FLAGS_REG))]
21455   "TARGET_64BIT"
21456   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21457   [(set_attr "type" "multi")])
21458
21459 (define_insn "stack_tls_protect_set_si"
21460   [(set (match_operand:SI 0 "memory_operand" "=m")
21461         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21462    (set (match_scratch:SI 2 "=&r") (const_int 0))
21463    (clobber (reg:CC FLAGS_REG))]
21464   ""
21465   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21466   [(set_attr "type" "multi")])
21467
21468 (define_insn "stack_tls_protect_set_di"
21469   [(set (match_operand:DI 0 "memory_operand" "=m")
21470         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21471    (set (match_scratch:DI 2 "=&r") (const_int 0))
21472    (clobber (reg:CC FLAGS_REG))]
21473   "TARGET_64BIT"
21474   {
21475      /* The kernel uses a different segment register for performance reasons; a
21476         system call would not have to trash the userspace segment register,
21477         which would be expensive */
21478      if (ix86_cmodel != CM_KERNEL)
21479         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21480      else
21481         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21482   }
21483   [(set_attr "type" "multi")])
21484
21485 (define_expand "stack_protect_test"
21486   [(match_operand 0 "memory_operand" "")
21487    (match_operand 1 "memory_operand" "")
21488    (match_operand 2 "" "")]
21489   ""
21490 {
21491   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21492   ix86_compare_op0 = operands[0];
21493   ix86_compare_op1 = operands[1];
21494   ix86_compare_emitted = flags;
21495
21496 #ifdef TARGET_THREAD_SSP_OFFSET
21497   if (TARGET_64BIT)
21498     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21499                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21500   else
21501     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21502                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21503 #else
21504   if (TARGET_64BIT)
21505     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21506   else
21507     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21508 #endif
21509   emit_jump_insn (gen_beq (operands[2]));
21510   DONE;
21511 })
21512
21513 (define_insn "stack_protect_test_si"
21514   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21515         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21516                      (match_operand:SI 2 "memory_operand" "m")]
21517                     UNSPEC_SP_TEST))
21518    (clobber (match_scratch:SI 3 "=&r"))]
21519   ""
21520   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21521   [(set_attr "type" "multi")])
21522
21523 (define_insn "stack_protect_test_di"
21524   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21525         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21526                      (match_operand:DI 2 "memory_operand" "m")]
21527                     UNSPEC_SP_TEST))
21528    (clobber (match_scratch:DI 3 "=&r"))]
21529   "TARGET_64BIT"
21530   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21531   [(set_attr "type" "multi")])
21532
21533 (define_insn "stack_tls_protect_test_si"
21534   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21535         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21536                      (match_operand:SI 2 "const_int_operand" "i")]
21537                     UNSPEC_SP_TLS_TEST))
21538    (clobber (match_scratch:SI 3 "=r"))]
21539   ""
21540   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21541   [(set_attr "type" "multi")])
21542
21543 (define_insn "stack_tls_protect_test_di"
21544   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21545         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21546                      (match_operand:DI 2 "const_int_operand" "i")]
21547                     UNSPEC_SP_TLS_TEST))
21548    (clobber (match_scratch:DI 3 "=r"))]
21549   "TARGET_64BIT"
21550   {
21551      /* The kernel uses a different segment register for performance reasons; a
21552         system call would not have to trash the userspace segment register,
21553         which would be expensive */
21554      if (ix86_cmodel != CM_KERNEL)
21555         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21556      else
21557         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21558   }
21559   [(set_attr "type" "multi")])
21560
21561 (define_mode_iterator CRC32MODE [QI HI SI])
21562 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21563 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21564
21565 (define_insn "sse4_2_crc32<mode>"
21566   [(set (match_operand:SI 0 "register_operand" "=r")
21567         (unspec:SI
21568           [(match_operand:SI 1 "register_operand" "0")
21569            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21570           UNSPEC_CRC32))]
21571   "TARGET_SSE4_2"
21572   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21573   [(set_attr "type" "sselog1")
21574    (set_attr "prefix_rep" "1")
21575    (set_attr "prefix_extra" "1")
21576    (set_attr "mode" "SI")])
21577
21578 (define_insn "sse4_2_crc32di"
21579   [(set (match_operand:DI 0 "register_operand" "=r")
21580         (unspec:DI
21581           [(match_operand:DI 1 "register_operand" "0")
21582            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21583           UNSPEC_CRC32))]
21584   "TARGET_SSE4_2 && TARGET_64BIT"
21585   "crc32q\t{%2, %0|%0, %2}"
21586   [(set_attr "type" "sselog1")
21587    (set_attr "prefix_rep" "1")
21588    (set_attr "prefix_extra" "1")
21589    (set_attr "mode" "DI")])
21590
21591 (include "mmx.md")
21592 (include "sse.md")
21593 (include "sync.md")