OSDN Git Service

04d38f6497be6960e454fccca4b38740d6070ecf
[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, 2008
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 variants
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   [(AX_REG                       0)
223    (DX_REG                       1)
224    (CX_REG                       2)
225    (SI_REG                       4)
226    (DI_REG                       5)
227    (BP_REG                       6)
228    (SP_REG                       7)
229    (FLAGS_REG                   17)
230    (FPSR_REG                    18)
231    (FPCR_REG                    19)
232    (R10_REG                     39)
233    (R11_REG                     40)
234   ])
235
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
237 ;; from i386.c.
238
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first.  This allows for better optimization.  For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
243
244 \f
245 ;; Processor type.  This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248                     nocona,core2,generic32,generic64,amdfam10"
249   (const (symbol_ref "ix86_tune")))
250
251 ;; A basic instruction type.  Refinements due to arguments to be
252 ;; provided in other attributes.
253 (define_attr "type"
254   "other,multi,
255    alu,alu1,negnot,imov,imovx,lea,
256    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257    icmp,test,ibr,setcc,icmov,
258    push,pop,call,callv,leave,
259    str,bitmanip,
260    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263    ssemuladd,sse4arg,
264    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265   (const_string "other"))
266
267 ;; Main data type used by the insn
268 (define_attr "mode"
269   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270   (const_string "unknown"))
271
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275            (const_string "i387")
276          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279            (const_string "sse")
280          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281            (const_string "mmx")
282          (eq_attr "type" "other")
283            (const_string "unknown")]
284          (const_string "integer")))
285
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
289                           bitmanip")
290            (const_int 0)
291          (eq_attr "unit" "i387,sse,mmx")
292            (const_int 0)
293          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294                           imul,icmp,push,pop")
295            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296          (eq_attr "type" "imov,test")
297            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298          (eq_attr "type" "call")
299            (if_then_else (match_operand 0 "constant_call_address_operand" "")
300              (const_int 4)
301              (const_int 0))
302          (eq_attr "type" "callv")
303            (if_then_else (match_operand 1 "constant_call_address_operand" "")
304              (const_int 4)
305              (const_int 0))
306          ;; We don't know the size before shorten_branches.  Expect
307          ;; the instruction to fit for better scheduling.
308          (eq_attr "type" "ibr")
309            (const_int 1)
310          ]
311          (symbol_ref "/* Update immediate_length and other attributes! */
312                       gcc_unreachable (),1")))
313
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316   (cond [(eq_attr "type" "str,other,multi,fxch")
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (symbol_ref "ix86_attr_length_address_default (insn)")))
326
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329   (if_then_else (ior (eq_attr "mode" "HI")
330                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
331     (const_int 1)
332     (const_int 0)))
333
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
337     (const_int 1)
338     (const_int 0)))
339
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
342   (if_then_else
343     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344          (eq_attr "unit" "sse,mmx"))
345     (const_int 1)
346     (const_int 0)))
347
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350   (cond [(and (eq_attr "mode" "DI")
351               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352            (const_int 1)
353          (and (eq_attr "mode" "QI")
354               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
355                   (const_int 0)))
356            (const_int 1)
357          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
358              (const_int 0))
359            (const_int 1)
360         ]
361         (const_int 0)))
362
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
365
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368   (cond [(eq_attr "type" "str,leave")
369            (const_int 0)
370          (eq_attr "unit" "i387")
371            (const_int 0)
372          (and (eq_attr "type" "incdec")
373               (ior (match_operand:SI 1 "register_operand" "")
374                    (match_operand:HI 1 "register_operand" "")))
375            (const_int 0)
376          (and (eq_attr "type" "push")
377               (not (match_operand 1 "memory_operand" "")))
378            (const_int 0)
379          (and (eq_attr "type" "pop")
380               (not (match_operand 0 "memory_operand" "")))
381            (const_int 0)
382          (and (eq_attr "type" "imov")
383               (ior (and (match_operand 0 "register_operand" "")
384                         (match_operand 1 "immediate_operand" ""))
385                    (ior (and (match_operand 0 "ax_reg_operand" "")
386                              (match_operand 1 "memory_displacement_only_operand" ""))
387                         (and (match_operand 0 "memory_displacement_only_operand" "")
388                              (match_operand 1 "ax_reg_operand" "")))))
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (const_int 1)))
398
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
402 ;; other insns.
403 (define_attr "length" ""
404   (cond [(eq_attr "type" "other,multi,fistp,frndint")
405            (const_int 16)
406          (eq_attr "type" "fcmp")
407            (const_int 4)
408          (eq_attr "unit" "i387")
409            (plus (const_int 2)
410                  (plus (attr "prefix_data16")
411                        (attr "length_address")))]
412          (plus (plus (attr "modrm")
413                      (plus (attr "prefix_0f")
414                            (plus (attr "prefix_rex")
415                                  (plus (attr "prefix_extra")
416                                        (const_int 1)))))
417                (plus (attr "prefix_rep")
418                      (plus (attr "prefix_data16")
419                            (plus (attr "length_immediate")
420                                  (attr "length_address")))))))
421
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
425
426 (define_attr "memory" "none,load,store,both,unknown"
427   (cond [(eq_attr "type" "other,multi,str")
428            (const_string "unknown")
429          (eq_attr "type" "lea,fcmov,fpspc")
430            (const_string "none")
431          (eq_attr "type" "fistp,leave")
432            (const_string "both")
433          (eq_attr "type" "frndint")
434            (const_string "load")
435          (eq_attr "type" "push")
436            (if_then_else (match_operand 1 "memory_operand" "")
437              (const_string "both")
438              (const_string "store"))
439          (eq_attr "type" "pop")
440            (if_then_else (match_operand 0 "memory_operand" "")
441              (const_string "both")
442              (const_string "load"))
443          (eq_attr "type" "setcc")
444            (if_then_else (match_operand 0 "memory_operand" "")
445              (const_string "store")
446              (const_string "none"))
447          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448            (if_then_else (ior (match_operand 0 "memory_operand" "")
449                               (match_operand 1 "memory_operand" ""))
450              (const_string "load")
451              (const_string "none"))
452          (eq_attr "type" "ibr")
453            (if_then_else (match_operand 0 "memory_operand" "")
454              (const_string "load")
455              (const_string "none"))
456          (eq_attr "type" "call")
457            (if_then_else (match_operand 0 "constant_call_address_operand" "")
458              (const_string "none")
459              (const_string "load"))
460          (eq_attr "type" "callv")
461            (if_then_else (match_operand 1 "constant_call_address_operand" "")
462              (const_string "none")
463              (const_string "load"))
464          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465               (match_operand 1 "memory_operand" ""))
466            (const_string "both")
467          (and (match_operand 0 "memory_operand" "")
468               (match_operand 1 "memory_operand" ""))
469            (const_string "both")
470          (match_operand 0 "memory_operand" "")
471            (const_string "store")
472          (match_operand 1 "memory_operand" "")
473            (const_string "load")
474          (and (eq_attr "type"
475                  "!alu1,negnot,ishift1,
476                    imov,imovx,icmp,test,bitmanip,
477                    fmov,fcmp,fsgn,
478                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480               (match_operand 2 "memory_operand" ""))
481            (const_string "load")
482          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483               (match_operand 3 "memory_operand" ""))
484            (const_string "load")
485         ]
486         (const_string "none")))
487
488 ;; Indicates if an instruction has both an immediate and a displacement.
489
490 (define_attr "imm_disp" "false,true,unknown"
491   (cond [(eq_attr "type" "other,multi")
492            (const_string "unknown")
493          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494               (and (match_operand 0 "memory_displacement_operand" "")
495                    (match_operand 1 "immediate_operand" "")))
496            (const_string "true")
497          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498               (and (match_operand 0 "memory_displacement_operand" "")
499                    (match_operand 2 "immediate_operand" "")))
500            (const_string "true")
501         ]
502         (const_string "false")))
503
504 ;; Indicates if an FP operation has an integer source.
505
506 (define_attr "fp_int_src" "false,true"
507   (const_string "false"))
508
509 ;; Defines rounding mode of an FP operation.
510
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512   (const_string "any"))
513
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516   [(set_attr "length" "128")
517    (set_attr "type" "multi")])
518
519 (define_code_iterator plusminus [plus minus])
520
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
523
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
526
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
529
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
532
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
535
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
538
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541         [(QI "general_operand")
542          (HI "general_operand")
543          (SI "general_operand")
544          (DI "x86_64_general_operand")])
545
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
548
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
551
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
554
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
557
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
560
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
563
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
567 \f
568 ;; Scheduling descriptions
569
570 (include "pentium.md")
571 (include "ppro.md")
572 (include "k6.md")
573 (include "athlon.md")
574 (include "geode.md")
575
576 \f
577 ;; Operand and operator predicates and constraints
578
579 (include "predicates.md")
580 (include "constraints.md")
581
582 \f
583 ;; Compare instructions.
584
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
588
589 (define_expand "cmpti"
590   [(set (reg:CC FLAGS_REG)
591         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592                     (match_operand:TI 1 "x86_64_general_operand" "")))]
593   "TARGET_64BIT"
594 {
595   if (MEM_P (operands[0]) && MEM_P (operands[1]))
596     operands[0] = force_reg (TImode, operands[0]);
597   ix86_compare_op0 = operands[0];
598   ix86_compare_op1 = operands[1];
599   DONE;
600 })
601
602 (define_expand "cmpdi"
603   [(set (reg:CC FLAGS_REG)
604         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605                     (match_operand:DI 1 "x86_64_general_operand" "")))]
606   ""
607 {
608   if (MEM_P (operands[0]) && MEM_P (operands[1]))
609     operands[0] = force_reg (DImode, operands[0]);
610   ix86_compare_op0 = operands[0];
611   ix86_compare_op1 = operands[1];
612   DONE;
613 })
614
615 (define_expand "cmpsi"
616   [(set (reg:CC FLAGS_REG)
617         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618                     (match_operand:SI 1 "general_operand" "")))]
619   ""
620 {
621   if (MEM_P (operands[0]) && MEM_P (operands[1]))
622     operands[0] = force_reg (SImode, operands[0]);
623   ix86_compare_op0 = operands[0];
624   ix86_compare_op1 = operands[1];
625   DONE;
626 })
627
628 (define_expand "cmphi"
629   [(set (reg:CC FLAGS_REG)
630         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631                     (match_operand:HI 1 "general_operand" "")))]
632   ""
633 {
634   if (MEM_P (operands[0]) && MEM_P (operands[1]))
635     operands[0] = force_reg (HImode, operands[0]);
636   ix86_compare_op0 = operands[0];
637   ix86_compare_op1 = operands[1];
638   DONE;
639 })
640
641 (define_expand "cmpqi"
642   [(set (reg:CC FLAGS_REG)
643         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644                     (match_operand:QI 1 "general_operand" "")))]
645   "TARGET_QIMODE_MATH"
646 {
647   if (MEM_P (operands[0]) && MEM_P (operands[1]))
648     operands[0] = force_reg (QImode, operands[0]);
649   ix86_compare_op0 = operands[0];
650   ix86_compare_op1 = operands[1];
651   DONE;
652 })
653
654 (define_insn "cmpdi_ccno_1_rex64"
655   [(set (reg FLAGS_REG)
656         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657                  (match_operand:DI 1 "const0_operand" "n,n")))]
658   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
659   "@
660    test{q}\t%0, %0
661    cmp{q}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "test,icmp")
663    (set_attr "length_immediate" "0,1")
664    (set_attr "mode" "DI")])
665
666 (define_insn "*cmpdi_minus_1_rex64"
667   [(set (reg FLAGS_REG)
668         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
670                  (const_int 0)))]
671   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672   "cmp{q}\t{%1, %0|%0, %1}"
673   [(set_attr "type" "icmp")
674    (set_attr "mode" "DI")])
675
676 (define_expand "cmpdi_1_rex64"
677   [(set (reg:CC FLAGS_REG)
678         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679                     (match_operand:DI 1 "general_operand" "")))]
680   "TARGET_64BIT"
681   "")
682
683 (define_insn "cmpdi_1_insn_rex64"
684   [(set (reg FLAGS_REG)
685         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688   "cmp{q}\t{%1, %0|%0, %1}"
689   [(set_attr "type" "icmp")
690    (set_attr "mode" "DI")])
691
692
693 (define_insn "*cmpsi_ccno_1"
694   [(set (reg FLAGS_REG)
695         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696                  (match_operand:SI 1 "const0_operand" "n,n")))]
697   "ix86_match_ccmode (insn, CCNOmode)"
698   "@
699    test{l}\t%0, %0
700    cmp{l}\t{%1, %0|%0, %1}"
701   [(set_attr "type" "test,icmp")
702    (set_attr "length_immediate" "0,1")
703    (set_attr "mode" "SI")])
704
705 (define_insn "*cmpsi_minus_1"
706   [(set (reg FLAGS_REG)
707         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708                            (match_operand:SI 1 "general_operand" "ri,mr"))
709                  (const_int 0)))]
710   "ix86_match_ccmode (insn, CCGOCmode)"
711   "cmp{l}\t{%1, %0|%0, %1}"
712   [(set_attr "type" "icmp")
713    (set_attr "mode" "SI")])
714
715 (define_expand "cmpsi_1"
716   [(set (reg:CC FLAGS_REG)
717         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718                     (match_operand:SI 1 "general_operand" "")))]
719   ""
720   "")
721
722 (define_insn "*cmpsi_1_insn"
723   [(set (reg FLAGS_REG)
724         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725                  (match_operand:SI 1 "general_operand" "ri,mr")))]
726   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727     && ix86_match_ccmode (insn, CCmode)"
728   "cmp{l}\t{%1, %0|%0, %1}"
729   [(set_attr "type" "icmp")
730    (set_attr "mode" "SI")])
731
732 (define_insn "*cmphi_ccno_1"
733   [(set (reg FLAGS_REG)
734         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735                  (match_operand:HI 1 "const0_operand" "n,n")))]
736   "ix86_match_ccmode (insn, CCNOmode)"
737   "@
738    test{w}\t%0, %0
739    cmp{w}\t{%1, %0|%0, %1}"
740   [(set_attr "type" "test,icmp")
741    (set_attr "length_immediate" "0,1")
742    (set_attr "mode" "HI")])
743
744 (define_insn "*cmphi_minus_1"
745   [(set (reg FLAGS_REG)
746         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747                            (match_operand:HI 1 "general_operand" "ri,mr"))
748                  (const_int 0)))]
749   "ix86_match_ccmode (insn, CCGOCmode)"
750   "cmp{w}\t{%1, %0|%0, %1}"
751   [(set_attr "type" "icmp")
752    (set_attr "mode" "HI")])
753
754 (define_insn "*cmphi_1"
755   [(set (reg FLAGS_REG)
756         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757                  (match_operand:HI 1 "general_operand" "ri,mr")))]
758   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759    && ix86_match_ccmode (insn, CCmode)"
760   "cmp{w}\t{%1, %0|%0, %1}"
761   [(set_attr "type" "icmp")
762    (set_attr "mode" "HI")])
763
764 (define_insn "*cmpqi_ccno_1"
765   [(set (reg FLAGS_REG)
766         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767                  (match_operand:QI 1 "const0_operand" "n,n")))]
768   "ix86_match_ccmode (insn, CCNOmode)"
769   "@
770    test{b}\t%0, %0
771    cmp{b}\t{$0, %0|%0, 0}"
772   [(set_attr "type" "test,icmp")
773    (set_attr "length_immediate" "0,1")
774    (set_attr "mode" "QI")])
775
776 (define_insn "*cmpqi_1"
777   [(set (reg FLAGS_REG)
778         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779                  (match_operand:QI 1 "general_operand" "qi,mq")))]
780   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781     && ix86_match_ccmode (insn, CCmode)"
782   "cmp{b}\t{%1, %0|%0, %1}"
783   [(set_attr "type" "icmp")
784    (set_attr "mode" "QI")])
785
786 (define_insn "*cmpqi_minus_1"
787   [(set (reg FLAGS_REG)
788         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789                            (match_operand:QI 1 "general_operand" "qi,mq"))
790                  (const_int 0)))]
791   "ix86_match_ccmode (insn, CCGOCmode)"
792   "cmp{b}\t{%1, %0|%0, %1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
795
796 (define_insn "*cmpqi_ext_1"
797   [(set (reg FLAGS_REG)
798         (compare
799           (match_operand:QI 0 "general_operand" "Qm")
800           (subreg:QI
801             (zero_extract:SI
802               (match_operand 1 "ext_register_operand" "Q")
803               (const_int 8)
804               (const_int 8)) 0)))]
805   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806   "cmp{b}\t{%h1, %0|%0, %h1}"
807   [(set_attr "type" "icmp")
808    (set_attr "mode" "QI")])
809
810 (define_insn "*cmpqi_ext_1_rex64"
811   [(set (reg FLAGS_REG)
812         (compare
813           (match_operand:QI 0 "register_operand" "Q")
814           (subreg:QI
815             (zero_extract:SI
816               (match_operand 1 "ext_register_operand" "Q")
817               (const_int 8)
818               (const_int 8)) 0)))]
819   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820   "cmp{b}\t{%h1, %0|%0, %h1}"
821   [(set_attr "type" "icmp")
822    (set_attr "mode" "QI")])
823
824 (define_insn "*cmpqi_ext_2"
825   [(set (reg FLAGS_REG)
826         (compare
827           (subreg:QI
828             (zero_extract:SI
829               (match_operand 0 "ext_register_operand" "Q")
830               (const_int 8)
831               (const_int 8)) 0)
832           (match_operand:QI 1 "const0_operand" "n")))]
833   "ix86_match_ccmode (insn, CCNOmode)"
834   "test{b}\t%h0, %h0"
835   [(set_attr "type" "test")
836    (set_attr "length_immediate" "0")
837    (set_attr "mode" "QI")])
838
839 (define_expand "cmpqi_ext_3"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC
842           (subreg:QI
843             (zero_extract:SI
844               (match_operand 0 "ext_register_operand" "")
845               (const_int 8)
846               (const_int 8)) 0)
847           (match_operand:QI 1 "general_operand" "")))]
848   ""
849   "")
850
851 (define_insn "cmpqi_ext_3_insn"
852   [(set (reg FLAGS_REG)
853         (compare
854           (subreg:QI
855             (zero_extract:SI
856               (match_operand 0 "ext_register_operand" "Q")
857               (const_int 8)
858               (const_int 8)) 0)
859           (match_operand:QI 1 "general_operand" "Qmn")))]
860   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861   "cmp{b}\t{%1, %h0|%h0, %1}"
862   [(set_attr "type" "icmp")
863    (set_attr "mode" "QI")])
864
865 (define_insn "cmpqi_ext_3_insn_rex64"
866   [(set (reg FLAGS_REG)
867         (compare
868           (subreg:QI
869             (zero_extract:SI
870               (match_operand 0 "ext_register_operand" "Q")
871               (const_int 8)
872               (const_int 8)) 0)
873           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875   "cmp{b}\t{%1, %h0|%h0, %1}"
876   [(set_attr "type" "icmp")
877    (set_attr "mode" "QI")])
878
879 (define_insn "*cmpqi_ext_4"
880   [(set (reg FLAGS_REG)
881         (compare
882           (subreg:QI
883             (zero_extract:SI
884               (match_operand 0 "ext_register_operand" "Q")
885               (const_int 8)
886               (const_int 8)) 0)
887           (subreg:QI
888             (zero_extract:SI
889               (match_operand 1 "ext_register_operand" "Q")
890               (const_int 8)
891               (const_int 8)) 0)))]
892   "ix86_match_ccmode (insn, CCmode)"
893   "cmp{b}\t{%h1, %h0|%h0, %h1}"
894   [(set_attr "type" "icmp")
895    (set_attr "mode" "QI")])
896
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares.  Which is what
900 ;; the old patterns did, but with many more of them.
901
902 (define_expand "cmpxf"
903   [(set (reg:CC FLAGS_REG)
904         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905                     (match_operand:XF 1 "nonmemory_operand" "")))]
906   "TARGET_80387"
907 {
908   ix86_compare_op0 = operands[0];
909   ix86_compare_op1 = operands[1];
910   DONE;
911 })
912
913 (define_expand "cmp<mode>"
914   [(set (reg:CC FLAGS_REG)
915         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
918 {
919   ix86_compare_op0 = operands[0];
920   ix86_compare_op1 = operands[1];
921   DONE;
922 })
923
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
926 ;;
927 ;; CCFPmode     compare with exceptions
928 ;; CCFPUmode    compare with no exceptions
929
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
932
933 (define_insn "*cmpfp_0"
934   [(set (match_operand:HI 0 "register_operand" "=a")
935         (unspec:HI
936           [(compare:CCFP
937              (match_operand 1 "register_operand" "f")
938              (match_operand 2 "const0_operand" "X"))]
939         UNSPEC_FNSTSW))]
940   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942   "* return output_fp_compare (insn, operands, 0, 0);"
943   [(set_attr "type" "multi")
944    (set_attr "unit" "i387")
945    (set (attr "mode")
946      (cond [(match_operand:SF 1 "" "")
947               (const_string "SF")
948             (match_operand:DF 1 "" "")
949               (const_string "DF")
950            ]
951            (const_string "XF")))])
952
953 (define_insn_and_split "*cmpfp_0_cc"
954   [(set (reg:CCFP FLAGS_REG)
955         (compare:CCFP
956           (match_operand 1 "register_operand" "f")
957           (match_operand 2 "const0_operand" "X")))
958    (clobber (match_operand:HI 0 "register_operand" "=a"))]
959   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960    && TARGET_SAHF && !TARGET_CMOVE
961    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
962   "#"
963   "&& reload_completed"
964   [(set (match_dup 0)
965         (unspec:HI
966           [(compare:CCFP (match_dup 1)(match_dup 2))]
967         UNSPEC_FNSTSW))
968    (set (reg:CC FLAGS_REG)
969         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
970   ""
971   [(set_attr "type" "multi")
972    (set_attr "unit" "i387")
973    (set (attr "mode")
974      (cond [(match_operand:SF 1 "" "")
975               (const_string "SF")
976             (match_operand:DF 1 "" "")
977               (const_string "DF")
978            ]
979            (const_string "XF")))])
980
981 (define_insn "*cmpfp_xf"
982   [(set (match_operand:HI 0 "register_operand" "=a")
983         (unspec:HI
984           [(compare:CCFP
985              (match_operand:XF 1 "register_operand" "f")
986              (match_operand:XF 2 "register_operand" "f"))]
987           UNSPEC_FNSTSW))]
988   "TARGET_80387"
989   "* return output_fp_compare (insn, operands, 0, 0);"
990   [(set_attr "type" "multi")
991    (set_attr "unit" "i387")
992    (set_attr "mode" "XF")])
993
994 (define_insn_and_split "*cmpfp_xf_cc"
995   [(set (reg:CCFP FLAGS_REG)
996         (compare:CCFP
997           (match_operand:XF 1 "register_operand" "f")
998           (match_operand:XF 2 "register_operand" "f")))
999    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1000   "TARGET_80387
1001    && TARGET_SAHF && !TARGET_CMOVE"
1002   "#"
1003   "&& reload_completed"
1004   [(set (match_dup 0)
1005         (unspec:HI
1006           [(compare:CCFP (match_dup 1)(match_dup 2))]
1007         UNSPEC_FNSTSW))
1008    (set (reg:CC FLAGS_REG)
1009         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1010   ""
1011   [(set_attr "type" "multi")
1012    (set_attr "unit" "i387")
1013    (set_attr "mode" "XF")])
1014
1015 (define_insn "*cmpfp_<mode>"
1016   [(set (match_operand:HI 0 "register_operand" "=a")
1017         (unspec:HI
1018           [(compare:CCFP
1019              (match_operand:MODEF 1 "register_operand" "f")
1020              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1021           UNSPEC_FNSTSW))]
1022   "TARGET_80387"
1023   "* return output_fp_compare (insn, operands, 0, 0);"
1024   [(set_attr "type" "multi")
1025    (set_attr "unit" "i387")
1026    (set_attr "mode" "<MODE>")])
1027
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029   [(set (reg:CCFP FLAGS_REG)
1030         (compare:CCFP
1031           (match_operand:MODEF 1 "register_operand" "f")
1032           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1034   "TARGET_80387
1035    && TARGET_SAHF && !TARGET_CMOVE"
1036   "#"
1037   "&& reload_completed"
1038   [(set (match_dup 0)
1039         (unspec:HI
1040           [(compare:CCFP (match_dup 1)(match_dup 2))]
1041         UNSPEC_FNSTSW))
1042    (set (reg:CC FLAGS_REG)
1043         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1044   ""
1045   [(set_attr "type" "multi")
1046    (set_attr "unit" "i387")
1047    (set_attr "mode" "<MODE>")])
1048
1049 (define_insn "*cmpfp_u"
1050   [(set (match_operand:HI 0 "register_operand" "=a")
1051         (unspec:HI
1052           [(compare:CCFPU
1053              (match_operand 1 "register_operand" "f")
1054              (match_operand 2 "register_operand" "f"))]
1055           UNSPEC_FNSTSW))]
1056   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058   "* return output_fp_compare (insn, operands, 0, 1);"
1059   [(set_attr "type" "multi")
1060    (set_attr "unit" "i387")
1061    (set (attr "mode")
1062      (cond [(match_operand:SF 1 "" "")
1063               (const_string "SF")
1064             (match_operand:DF 1 "" "")
1065               (const_string "DF")
1066            ]
1067            (const_string "XF")))])
1068
1069 (define_insn_and_split "*cmpfp_u_cc"
1070   [(set (reg:CCFPU FLAGS_REG)
1071         (compare:CCFPU
1072           (match_operand 1 "register_operand" "f")
1073           (match_operand 2 "register_operand" "f")))
1074    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076    && TARGET_SAHF && !TARGET_CMOVE
1077    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078   "#"
1079   "&& reload_completed"
1080   [(set (match_dup 0)
1081         (unspec:HI
1082           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1083         UNSPEC_FNSTSW))
1084    (set (reg:CC FLAGS_REG)
1085         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1086   ""
1087   [(set_attr "type" "multi")
1088    (set_attr "unit" "i387")
1089    (set (attr "mode")
1090      (cond [(match_operand:SF 1 "" "")
1091               (const_string "SF")
1092             (match_operand:DF 1 "" "")
1093               (const_string "DF")
1094            ]
1095            (const_string "XF")))])
1096
1097 (define_insn "*cmpfp_<mode>"
1098   [(set (match_operand:HI 0 "register_operand" "=a")
1099         (unspec:HI
1100           [(compare:CCFP
1101              (match_operand 1 "register_operand" "f")
1102              (match_operator 3 "float_operator"
1103                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1104           UNSPEC_FNSTSW))]
1105   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106    && TARGET_USE_<MODE>MODE_FIOP
1107    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108   "* return output_fp_compare (insn, operands, 0, 0);"
1109   [(set_attr "type" "multi")
1110    (set_attr "unit" "i387")
1111    (set_attr "fp_int_src" "true")
1112    (set_attr "mode" "<MODE>")])
1113
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115   [(set (reg:CCFP FLAGS_REG)
1116         (compare:CCFP
1117           (match_operand 1 "register_operand" "f")
1118           (match_operator 3 "float_operator"
1119             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122    && TARGET_SAHF && !TARGET_CMOVE
1123    && TARGET_USE_<MODE>MODE_FIOP
1124    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1125   "#"
1126   "&& reload_completed"
1127   [(set (match_dup 0)
1128         (unspec:HI
1129           [(compare:CCFP
1130              (match_dup 1)
1131              (match_op_dup 3 [(match_dup 2)]))]
1132         UNSPEC_FNSTSW))
1133    (set (reg:CC FLAGS_REG)
1134         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1135   ""
1136   [(set_attr "type" "multi")
1137    (set_attr "unit" "i387")
1138    (set_attr "fp_int_src" "true")
1139    (set_attr "mode" "<MODE>")])
1140
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1143
1144 (define_insn "x86_fnstsw_1"
1145   [(set (match_operand:HI 0 "register_operand" "=a")
1146         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1147   "TARGET_80387"
1148   "fnstsw\t%0"
1149   [(set_attr "length" "2")
1150    (set_attr "mode" "SI")
1151    (set_attr "unit" "i387")])
1152
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1155
1156 (define_insn "x86_sahf_1"
1157   [(set (reg:CC FLAGS_REG)
1158         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1159                    UNSPEC_SAHF))]
1160   "TARGET_SAHF"
1161 {
1162 #ifdef HAVE_AS_IX86_SAHF
1163   return "sahf";
1164 #else
1165   return ".byte\t0x9e";
1166 #endif
1167 }
1168   [(set_attr "length" "1")
1169    (set_attr "athlon_decode" "vector")
1170    (set_attr "amdfam10_decode" "direct")
1171    (set_attr "mode" "SI")])
1172
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176   [(set (reg:CCFP FLAGS_REG)
1177         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179   "TARGET_MIX_SSE_I387
1180    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182   "* return output_fp_compare (insn, operands, 1, 0);"
1183   [(set_attr "type" "fcmp,ssecomi")
1184    (set (attr "mode")
1185      (if_then_else (match_operand:SF 1 "" "")
1186         (const_string "SF")
1187         (const_string "DF")))
1188    (set_attr "athlon_decode" "vector")
1189    (set_attr "amdfam10_decode" "direct")])
1190
1191 (define_insn "*cmpfp_i_sse"
1192   [(set (reg:CCFP FLAGS_REG)
1193         (compare:CCFP (match_operand 0 "register_operand" "x")
1194                       (match_operand 1 "nonimmediate_operand" "xm")))]
1195   "TARGET_SSE_MATH
1196    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198   "* return output_fp_compare (insn, operands, 1, 0);"
1199   [(set_attr "type" "ssecomi")
1200    (set (attr "mode")
1201      (if_then_else (match_operand:SF 1 "" "")
1202         (const_string "SF")
1203         (const_string "DF")))
1204    (set_attr "athlon_decode" "vector")
1205    (set_attr "amdfam10_decode" "direct")])
1206
1207 (define_insn "*cmpfp_i_i387"
1208   [(set (reg:CCFP FLAGS_REG)
1209         (compare:CCFP (match_operand 0 "register_operand" "f")
1210                       (match_operand 1 "register_operand" "f")))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1212    && TARGET_CMOVE
1213    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215   "* return output_fp_compare (insn, operands, 1, 0);"
1216   [(set_attr "type" "fcmp")
1217    (set (attr "mode")
1218      (cond [(match_operand:SF 1 "" "")
1219               (const_string "SF")
1220             (match_operand:DF 1 "" "")
1221               (const_string "DF")
1222            ]
1223            (const_string "XF")))
1224    (set_attr "athlon_decode" "vector")
1225    (set_attr "amdfam10_decode" "direct")])
1226
1227 (define_insn "*cmpfp_iu_mixed"
1228   [(set (reg:CCFPU FLAGS_REG)
1229         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231   "TARGET_MIX_SSE_I387
1232    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234   "* return output_fp_compare (insn, operands, 1, 1);"
1235   [(set_attr "type" "fcmp,ssecomi")
1236    (set (attr "mode")
1237      (if_then_else (match_operand:SF 1 "" "")
1238         (const_string "SF")
1239         (const_string "DF")))
1240    (set_attr "athlon_decode" "vector")
1241    (set_attr "amdfam10_decode" "direct")])
1242
1243 (define_insn "*cmpfp_iu_sse"
1244   [(set (reg:CCFPU FLAGS_REG)
1245         (compare:CCFPU (match_operand 0 "register_operand" "x")
1246                        (match_operand 1 "nonimmediate_operand" "xm")))]
1247   "TARGET_SSE_MATH
1248    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250   "* return output_fp_compare (insn, operands, 1, 1);"
1251   [(set_attr "type" "ssecomi")
1252    (set (attr "mode")
1253      (if_then_else (match_operand:SF 1 "" "")
1254         (const_string "SF")
1255         (const_string "DF")))
1256    (set_attr "athlon_decode" "vector")
1257    (set_attr "amdfam10_decode" "direct")])
1258
1259 (define_insn "*cmpfp_iu_387"
1260   [(set (reg:CCFPU FLAGS_REG)
1261         (compare:CCFPU (match_operand 0 "register_operand" "f")
1262                        (match_operand 1 "register_operand" "f")))]
1263   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1264    && TARGET_CMOVE
1265    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267   "* return output_fp_compare (insn, operands, 1, 1);"
1268   [(set_attr "type" "fcmp")
1269    (set (attr "mode")
1270      (cond [(match_operand:SF 1 "" "")
1271               (const_string "SF")
1272             (match_operand:DF 1 "" "")
1273               (const_string "DF")
1274            ]
1275            (const_string "XF")))
1276    (set_attr "athlon_decode" "vector")
1277    (set_attr "amdfam10_decode" "direct")])
1278 \f
1279 ;; Move instructions.
1280
1281 ;; General case of fullword move.
1282
1283 (define_expand "movsi"
1284   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285         (match_operand:SI 1 "general_operand" ""))]
1286   ""
1287   "ix86_expand_move (SImode, operands); DONE;")
1288
1289 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1290 ;; general_operand.
1291 ;;
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1297
1298 (define_insn "*pushsi2"
1299   [(set (match_operand:SI 0 "push_operand" "=<")
1300         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1301   "!TARGET_64BIT"
1302   "push{l}\t%1"
1303   [(set_attr "type" "push")
1304    (set_attr "mode" "SI")])
1305
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308   [(set (match_operand:SI 0 "push_operand" "=X")
1309         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1310   "TARGET_64BIT"
1311   "push{q}\t%q1"
1312   [(set_attr "type" "push")
1313    (set_attr "mode" "SI")])
1314
1315 (define_insn "*pushsi2_prologue"
1316   [(set (match_operand:SI 0 "push_operand" "=<")
1317         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318    (clobber (mem:BLK (scratch)))]
1319   "!TARGET_64BIT"
1320   "push{l}\t%1"
1321   [(set_attr "type" "push")
1322    (set_attr "mode" "SI")])
1323
1324 (define_insn "*popsi1_epilogue"
1325   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326         (mem:SI (reg:SI SP_REG)))
1327    (set (reg:SI SP_REG)
1328         (plus:SI (reg:SI SP_REG) (const_int 4)))
1329    (clobber (mem:BLK (scratch)))]
1330   "!TARGET_64BIT"
1331   "pop{l}\t%0"
1332   [(set_attr "type" "pop")
1333    (set_attr "mode" "SI")])
1334
1335 (define_insn "popsi1"
1336   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337         (mem:SI (reg:SI SP_REG)))
1338    (set (reg:SI SP_REG)
1339         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1340   "!TARGET_64BIT"
1341   "pop{l}\t%0"
1342   [(set_attr "type" "pop")
1343    (set_attr "mode" "SI")])
1344
1345 (define_insn "*movsi_xor"
1346   [(set (match_operand:SI 0 "register_operand" "=r")
1347         (match_operand:SI 1 "const0_operand" "i"))
1348    (clobber (reg:CC FLAGS_REG))]
1349   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1350   "xor{l}\t%0, %0"
1351   [(set_attr "type" "alu1")
1352    (set_attr "mode" "SI")
1353    (set_attr "length_immediate" "0")])
1354
1355 (define_insn "*movsi_or"
1356   [(set (match_operand:SI 0 "register_operand" "=r")
1357         (match_operand:SI 1 "immediate_operand" "i"))
1358    (clobber (reg:CC FLAGS_REG))]
1359   "reload_completed
1360    && operands[1] == constm1_rtx
1361    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1362 {
1363   operands[1] = constm1_rtx;
1364   return "or{l}\t{%1, %0|%0, %1}";
1365 }
1366   [(set_attr "type" "alu1")
1367    (set_attr "mode" "SI")
1368    (set_attr "length_immediate" "1")])
1369
1370 (define_insn "*movsi_1"
1371   [(set (match_operand:SI 0 "nonimmediate_operand"
1372                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373         (match_operand:SI 1 "general_operand"
1374                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1375   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1376 {
1377   switch (get_attr_type (insn))
1378     {
1379     case TYPE_SSELOG1:
1380       if (get_attr_mode (insn) == MODE_TI)
1381         return "pxor\t%0, %0";
1382       return "xorps\t%0, %0";
1383
1384     case TYPE_SSEMOV:
1385       switch (get_attr_mode (insn))
1386         {
1387         case MODE_TI:
1388           return "movdqa\t{%1, %0|%0, %1}";
1389         case MODE_V4SF:
1390           return "movaps\t{%1, %0|%0, %1}";
1391         case MODE_SI:
1392           return "movd\t{%1, %0|%0, %1}";
1393         case MODE_SF:
1394           return "movss\t{%1, %0|%0, %1}";
1395         default:
1396           gcc_unreachable ();
1397         }
1398
1399     case TYPE_MMXADD:
1400       return "pxor\t%0, %0";
1401
1402     case TYPE_MMXMOV:
1403       if (get_attr_mode (insn) == MODE_DI)
1404         return "movq\t{%1, %0|%0, %1}";
1405       return "movd\t{%1, %0|%0, %1}";
1406
1407     case TYPE_LEA:
1408       return "lea{l}\t{%1, %0|%0, %1}";
1409
1410     default:
1411       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412       return "mov{l}\t{%1, %0|%0, %1}";
1413     }
1414 }
1415   [(set (attr "type")
1416      (cond [(eq_attr "alternative" "2")
1417               (const_string "mmxadd")
1418             (eq_attr "alternative" "3,4,5")
1419               (const_string "mmxmov")
1420             (eq_attr "alternative" "6")
1421               (const_string "sselog1")
1422             (eq_attr "alternative" "7,8,9,10,11")
1423               (const_string "ssemov")
1424             (match_operand:DI 1 "pic_32bit_operand" "")
1425               (const_string "lea")
1426            ]
1427            (const_string "imov")))
1428    (set (attr "mode")
1429      (cond [(eq_attr "alternative" "2,3")
1430               (const_string "DI")
1431             (eq_attr "alternative" "6,7")
1432               (if_then_else
1433                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434                 (const_string "V4SF")
1435                 (const_string "TI"))
1436             (and (eq_attr "alternative" "8,9,10,11")
1437                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1438               (const_string "SF")
1439            ]
1440            (const_string "SI")))])
1441
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1449   "@
1450    movabs{l}\t{%1, %P0|%P0, %1}
1451    mov{l}\t{%1, %a0|%a0, %1}"
1452   [(set_attr "type" "imov")
1453    (set_attr "modrm" "0,*")
1454    (set_attr "length_address" "8,0")
1455    (set_attr "length_immediate" "0,*")
1456    (set_attr "memory" "store")
1457    (set_attr "mode" "SI")])
1458
1459 (define_insn "*movabssi_2_rex64"
1460   [(set (match_operand:SI 0 "register_operand" "=a,r")
1461         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1463   "@
1464    movabs{l}\t{%P1, %0|%0, %P1}
1465    mov{l}\t{%a1, %0|%0, %a1}"
1466   [(set_attr "type" "imov")
1467    (set_attr "modrm" "0,*")
1468    (set_attr "length_address" "8,0")
1469    (set_attr "length_immediate" "0")
1470    (set_attr "memory" "load")
1471    (set_attr "mode" "SI")])
1472
1473 (define_insn "*swapsi"
1474   [(set (match_operand:SI 0 "register_operand" "+r")
1475         (match_operand:SI 1 "register_operand" "+r"))
1476    (set (match_dup 1)
1477         (match_dup 0))]
1478   ""
1479   "xchg{l}\t%1, %0"
1480   [(set_attr "type" "imov")
1481    (set_attr "mode" "SI")
1482    (set_attr "pent_pair" "np")
1483    (set_attr "athlon_decode" "vector")
1484    (set_attr "amdfam10_decode" "double")])
1485
1486 (define_expand "movhi"
1487   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488         (match_operand:HI 1 "general_operand" ""))]
1489   ""
1490   "ix86_expand_move (HImode, operands); DONE;")
1491
1492 (define_insn "*pushhi2"
1493   [(set (match_operand:HI 0 "push_operand" "=X")
1494         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1495   "!TARGET_64BIT"
1496   "push{l}\t%k1"
1497   [(set_attr "type" "push")
1498    (set_attr "mode" "SI")])
1499
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502   [(set (match_operand:HI 0 "push_operand" "=X")
1503         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1504   "TARGET_64BIT"
1505   "push{q}\t%q1"
1506   [(set_attr "type" "push")
1507    (set_attr "mode" "DI")])
1508
1509 (define_insn "*movhi_1"
1510   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 {
1514   switch (get_attr_type (insn))
1515     {
1516     case TYPE_IMOVX:
1517       /* movzwl is faster than movw on p2 due to partial word stalls,
1518          though not as fast as an aligned movl.  */
1519       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1520     default:
1521       if (get_attr_mode (insn) == MODE_SI)
1522         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1523       else
1524         return "mov{w}\t{%1, %0|%0, %1}";
1525     }
1526 }
1527   [(set (attr "type")
1528      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529               (const_string "imov")
1530             (and (eq_attr "alternative" "0")
1531                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532                           (const_int 0))
1533                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1534                           (const_int 0))))
1535               (const_string "imov")
1536             (and (eq_attr "alternative" "1,2")
1537                  (match_operand:HI 1 "aligned_operand" ""))
1538               (const_string "imov")
1539             (and (ne (symbol_ref "TARGET_MOVX")
1540                      (const_int 0))
1541                  (eq_attr "alternative" "0,2"))
1542               (const_string "imovx")
1543            ]
1544            (const_string "imov")))
1545     (set (attr "mode")
1546       (cond [(eq_attr "type" "imovx")
1547                (const_string "SI")
1548              (and (eq_attr "alternative" "1,2")
1549                   (match_operand:HI 1 "aligned_operand" ""))
1550                (const_string "SI")
1551              (and (eq_attr "alternative" "0")
1552                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                            (const_int 0))
1554                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1555                            (const_int 0))))
1556                (const_string "SI")
1557             ]
1558             (const_string "HI")))])
1559
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1567   "@
1568    movabs{w}\t{%1, %P0|%P0, %1}
1569    mov{w}\t{%1, %a0|%a0, %1}"
1570   [(set_attr "type" "imov")
1571    (set_attr "modrm" "0,*")
1572    (set_attr "length_address" "8,0")
1573    (set_attr "length_immediate" "0,*")
1574    (set_attr "memory" "store")
1575    (set_attr "mode" "HI")])
1576
1577 (define_insn "*movabshi_2_rex64"
1578   [(set (match_operand:HI 0 "register_operand" "=a,r")
1579         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1581   "@
1582    movabs{w}\t{%P1, %0|%0, %P1}
1583    mov{w}\t{%a1, %0|%0, %a1}"
1584   [(set_attr "type" "imov")
1585    (set_attr "modrm" "0,*")
1586    (set_attr "length_address" "8,0")
1587    (set_attr "length_immediate" "0")
1588    (set_attr "memory" "load")
1589    (set_attr "mode" "HI")])
1590
1591 (define_insn "*swaphi_1"
1592   [(set (match_operand:HI 0 "register_operand" "+r")
1593         (match_operand:HI 1 "register_operand" "+r"))
1594    (set (match_dup 1)
1595         (match_dup 0))]
1596   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597   "xchg{l}\t%k1, %k0"
1598   [(set_attr "type" "imov")
1599    (set_attr "mode" "SI")
1600    (set_attr "pent_pair" "np")
1601    (set_attr "athlon_decode" "vector")
1602    (set_attr "amdfam10_decode" "double")])
1603
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606   [(set (match_operand:HI 0 "register_operand" "+r")
1607         (match_operand:HI 1 "register_operand" "+r"))
1608    (set (match_dup 1)
1609         (match_dup 0))]
1610   "TARGET_PARTIAL_REG_STALL"
1611   "xchg{w}\t%1, %0"
1612   [(set_attr "type" "imov")
1613    (set_attr "mode" "HI")
1614    (set_attr "pent_pair" "np")
1615    (set_attr "athlon_decode" "vector")])
1616
1617 (define_expand "movstricthi"
1618   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619         (match_operand:HI 1 "general_operand" ""))]
1620   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 {
1622   /* Don't generate memory->memory moves, go through a register */
1623   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624     operands[1] = force_reg (HImode, operands[1]);
1625 })
1626
1627 (define_insn "*movstricthi_1"
1628   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629         (match_operand:HI 1 "general_operand" "rn,m"))]
1630   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632   "mov{w}\t{%1, %0|%0, %1}"
1633   [(set_attr "type" "imov")
1634    (set_attr "mode" "HI")])
1635
1636 (define_insn "*movstricthi_xor"
1637   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638         (match_operand:HI 1 "const0_operand" "i"))
1639    (clobber (reg:CC FLAGS_REG))]
1640   "reload_completed
1641    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1642   "xor{w}\t%0, %0"
1643   [(set_attr "type" "alu1")
1644    (set_attr "mode" "HI")
1645    (set_attr "length_immediate" "0")])
1646
1647 (define_expand "movqi"
1648   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649         (match_operand:QI 1 "general_operand" ""))]
1650   ""
1651   "ix86_expand_move (QImode, operands); DONE;")
1652
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte".  But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1656
1657 (define_insn "*pushqi2"
1658   [(set (match_operand:QI 0 "push_operand" "=X")
1659         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1660   "!TARGET_64BIT"
1661   "push{l}\t%k1"
1662   [(set_attr "type" "push")
1663    (set_attr "mode" "SI")])
1664
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667   [(set (match_operand:QI 0 "push_operand" "=X")
1668         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1669   "TARGET_64BIT"
1670   "push{q}\t%q1"
1671   [(set_attr "type" "push")
1672    (set_attr "mode" "DI")])
1673
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1679 ;; instruction).
1680 ;;
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there.  Then we use movzx.
1684 (define_insn "*movqi_1"
1685   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1687   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1688 {
1689   switch (get_attr_type (insn))
1690     {
1691     case TYPE_IMOVX:
1692       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1694     default:
1695       if (get_attr_mode (insn) == MODE_SI)
1696         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1697       else
1698         return "mov{b}\t{%1, %0|%0, %1}";
1699     }
1700 }
1701   [(set (attr "type")
1702      (cond [(and (eq_attr "alternative" "5")
1703                  (not (match_operand:QI 1 "aligned_operand" "")))
1704               (const_string "imovx")
1705             (ne (symbol_ref "optimize_size") (const_int 0))
1706               (const_string "imov")
1707             (and (eq_attr "alternative" "3")
1708                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709                           (const_int 0))
1710                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1711                           (const_int 0))))
1712               (const_string "imov")
1713             (eq_attr "alternative" "3,5")
1714               (const_string "imovx")
1715             (and (ne (symbol_ref "TARGET_MOVX")
1716                      (const_int 0))
1717                  (eq_attr "alternative" "2"))
1718               (const_string "imovx")
1719            ]
1720            (const_string "imov")))
1721    (set (attr "mode")
1722       (cond [(eq_attr "alternative" "3,4,5")
1723                (const_string "SI")
1724              (eq_attr "alternative" "6")
1725                (const_string "QI")
1726              (eq_attr "type" "imovx")
1727                (const_string "SI")
1728              (and (eq_attr "type" "imov")
1729                   (and (eq_attr "alternative" "0,1")
1730                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1731                                 (const_int 0))
1732                             (and (eq (symbol_ref "optimize_size")
1733                                      (const_int 0))
1734                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1735                                      (const_int 0))))))
1736                (const_string "SI")
1737              ;; Avoid partial register stalls when not using QImode arithmetic
1738              (and (eq_attr "type" "imov")
1739                   (and (eq_attr "alternative" "0,1")
1740                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741                                 (const_int 0))
1742                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1743                                 (const_int 0)))))
1744                (const_string "SI")
1745            ]
1746            (const_string "QI")))])
1747
1748 (define_expand "reload_outqi"
1749   [(parallel [(match_operand:QI 0 "" "=m")
1750               (match_operand:QI 1 "register_operand" "r")
1751               (match_operand:QI 2 "register_operand" "=&q")])]
1752   ""
1753 {
1754   rtx op0, op1, op2;
1755   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1756
1757   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758   if (! q_regs_operand (op1, QImode))
1759     {
1760       emit_insn (gen_movqi (op2, op1));
1761       op1 = op2;
1762     }
1763   emit_insn (gen_movqi (op0, op1));
1764   DONE;
1765 })
1766
1767 (define_insn "*swapqi_1"
1768   [(set (match_operand:QI 0 "register_operand" "+r")
1769         (match_operand:QI 1 "register_operand" "+r"))
1770    (set (match_dup 1)
1771         (match_dup 0))]
1772   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1773   "xchg{l}\t%k1, %k0"
1774   [(set_attr "type" "imov")
1775    (set_attr "mode" "SI")
1776    (set_attr "pent_pair" "np")
1777    (set_attr "athlon_decode" "vector")
1778    (set_attr "amdfam10_decode" "vector")])
1779
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782   [(set (match_operand:QI 0 "register_operand" "+q")
1783         (match_operand:QI 1 "register_operand" "+q"))
1784    (set (match_dup 1)
1785         (match_dup 0))]
1786   "TARGET_PARTIAL_REG_STALL"
1787   "xchg{b}\t%1, %0"
1788   [(set_attr "type" "imov")
1789    (set_attr "mode" "QI")
1790    (set_attr "pent_pair" "np")
1791    (set_attr "athlon_decode" "vector")])
1792
1793 (define_expand "movstrictqi"
1794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795         (match_operand:QI 1 "general_operand" ""))]
1796   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1797 {
1798   /* Don't generate memory->memory moves, go through a register.  */
1799   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800     operands[1] = force_reg (QImode, operands[1]);
1801 })
1802
1803 (define_insn "*movstrictqi_1"
1804   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805         (match_operand:QI 1 "general_operand" "*qn,m"))]
1806   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808   "mov{b}\t{%1, %0|%0, %1}"
1809   [(set_attr "type" "imov")
1810    (set_attr "mode" "QI")])
1811
1812 (define_insn "*movstrictqi_xor"
1813   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814         (match_operand:QI 1 "const0_operand" "i"))
1815    (clobber (reg:CC FLAGS_REG))]
1816   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1817   "xor{b}\t%0, %0"
1818   [(set_attr "type" "alu1")
1819    (set_attr "mode" "QI")
1820    (set_attr "length_immediate" "0")])
1821
1822 (define_insn "*movsi_extv_1"
1823   [(set (match_operand:SI 0 "register_operand" "=R")
1824         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1825                          (const_int 8)
1826                          (const_int 8)))]
1827   ""
1828   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829   [(set_attr "type" "imovx")
1830    (set_attr "mode" "SI")])
1831
1832 (define_insn "*movhi_extv_1"
1833   [(set (match_operand:HI 0 "register_operand" "=R")
1834         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1835                          (const_int 8)
1836                          (const_int 8)))]
1837   ""
1838   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839   [(set_attr "type" "imovx")
1840    (set_attr "mode" "SI")])
1841
1842 (define_insn "*movqi_extv_1"
1843   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1845                          (const_int 8)
1846                          (const_int 8)))]
1847   "!TARGET_64BIT"
1848 {
1849   switch (get_attr_type (insn))
1850     {
1851     case TYPE_IMOVX:
1852       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853     default:
1854       return "mov{b}\t{%h1, %0|%0, %h1}";
1855     }
1856 }
1857   [(set (attr "type")
1858      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860                              (ne (symbol_ref "TARGET_MOVX")
1861                                  (const_int 0))))
1862         (const_string "imovx")
1863         (const_string "imov")))
1864    (set (attr "mode")
1865      (if_then_else (eq_attr "type" "imovx")
1866         (const_string "SI")
1867         (const_string "QI")))])
1868
1869 (define_insn "*movqi_extv_1_rex64"
1870   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1872                          (const_int 8)
1873                          (const_int 8)))]
1874   "TARGET_64BIT"
1875 {
1876   switch (get_attr_type (insn))
1877     {
1878     case TYPE_IMOVX:
1879       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1880     default:
1881       return "mov{b}\t{%h1, %0|%0, %h1}";
1882     }
1883 }
1884   [(set (attr "type")
1885      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887                              (ne (symbol_ref "TARGET_MOVX")
1888                                  (const_int 0))))
1889         (const_string "imovx")
1890         (const_string "imov")))
1891    (set (attr "mode")
1892      (if_then_else (eq_attr "type" "imovx")
1893         (const_string "SI")
1894         (const_string "QI")))])
1895
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1903   "@
1904    movabs{b}\t{%1, %P0|%P0, %1}
1905    mov{b}\t{%1, %a0|%a0, %1}"
1906   [(set_attr "type" "imov")
1907    (set_attr "modrm" "0,*")
1908    (set_attr "length_address" "8,0")
1909    (set_attr "length_immediate" "0,*")
1910    (set_attr "memory" "store")
1911    (set_attr "mode" "QI")])
1912
1913 (define_insn "*movabsqi_2_rex64"
1914   [(set (match_operand:QI 0 "register_operand" "=a,r")
1915         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1917   "@
1918    movabs{b}\t{%P1, %0|%0, %P1}
1919    mov{b}\t{%a1, %0|%0, %a1}"
1920   [(set_attr "type" "imov")
1921    (set_attr "modrm" "0,*")
1922    (set_attr "length_address" "8,0")
1923    (set_attr "length_immediate" "0")
1924    (set_attr "memory" "load")
1925    (set_attr "mode" "QI")])
1926
1927 (define_insn "*movdi_extzv_1"
1928   [(set (match_operand:DI 0 "register_operand" "=R")
1929         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1930                          (const_int 8)
1931                          (const_int 8)))]
1932   "TARGET_64BIT"
1933   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934   [(set_attr "type" "imovx")
1935    (set_attr "mode" "DI")])
1936
1937 (define_insn "*movsi_extzv_1"
1938   [(set (match_operand:SI 0 "register_operand" "=R")
1939         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1940                          (const_int 8)
1941                          (const_int 8)))]
1942   ""
1943   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944   [(set_attr "type" "imovx")
1945    (set_attr "mode" "SI")])
1946
1947 (define_insn "*movqi_extzv_2"
1948   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1950                                     (const_int 8)
1951                                     (const_int 8)) 0))]
1952   "!TARGET_64BIT"
1953 {
1954   switch (get_attr_type (insn))
1955     {
1956     case TYPE_IMOVX:
1957       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958     default:
1959       return "mov{b}\t{%h1, %0|%0, %h1}";
1960     }
1961 }
1962   [(set (attr "type")
1963      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965                              (ne (symbol_ref "TARGET_MOVX")
1966                                  (const_int 0))))
1967         (const_string "imovx")
1968         (const_string "imov")))
1969    (set (attr "mode")
1970      (if_then_else (eq_attr "type" "imovx")
1971         (const_string "SI")
1972         (const_string "QI")))])
1973
1974 (define_insn "*movqi_extzv_2_rex64"
1975   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1977                                     (const_int 8)
1978                                     (const_int 8)) 0))]
1979   "TARGET_64BIT"
1980 {
1981   switch (get_attr_type (insn))
1982     {
1983     case TYPE_IMOVX:
1984       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1985     default:
1986       return "mov{b}\t{%h1, %0|%0, %h1}";
1987     }
1988 }
1989   [(set (attr "type")
1990      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991                         (ne (symbol_ref "TARGET_MOVX")
1992                             (const_int 0)))
1993         (const_string "imovx")
1994         (const_string "imov")))
1995    (set (attr "mode")
1996      (if_then_else (eq_attr "type" "imovx")
1997         (const_string "SI")
1998         (const_string "QI")))])
1999
2000 (define_insn "movsi_insv_1"
2001   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2002                          (const_int 8)
2003                          (const_int 8))
2004         (match_operand:SI 1 "general_operand" "Qmn"))]
2005   "!TARGET_64BIT"
2006   "mov{b}\t{%b1, %h0|%h0, %b1}"
2007   [(set_attr "type" "imov")
2008    (set_attr "mode" "QI")])
2009
2010 (define_insn "*movsi_insv_1_rex64"
2011   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2012                          (const_int 8)
2013                          (const_int 8))
2014         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2015   "TARGET_64BIT"
2016   "mov{b}\t{%b1, %h0|%h0, %b1}"
2017   [(set_attr "type" "imov")
2018    (set_attr "mode" "QI")])
2019
2020 (define_insn "movdi_insv_1_rex64"
2021   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2022                          (const_int 8)
2023                          (const_int 8))
2024         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2025   "TARGET_64BIT"
2026   "mov{b}\t{%b1, %h0|%h0, %b1}"
2027   [(set_attr "type" "imov")
2028    (set_attr "mode" "QI")])
2029
2030 (define_insn "*movqi_insv_2"
2031   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2032                          (const_int 8)
2033                          (const_int 8))
2034         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2035                      (const_int 8)))]
2036   ""
2037   "mov{b}\t{%h1, %h0|%h0, %h1}"
2038   [(set_attr "type" "imov")
2039    (set_attr "mode" "QI")])
2040
2041 (define_expand "movdi"
2042   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043         (match_operand:DI 1 "general_operand" ""))]
2044   ""
2045   "ix86_expand_move (DImode, operands); DONE;")
2046
2047 (define_insn "*pushdi"
2048   [(set (match_operand:DI 0 "push_operand" "=<")
2049         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2050   "!TARGET_64BIT"
2051   "#")
2052
2053 (define_insn "*pushdi2_rex64"
2054   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2056   "TARGET_64BIT"
2057   "@
2058    push{q}\t%1
2059    #"
2060   [(set_attr "type" "push,multi")
2061    (set_attr "mode" "DI")])
2062
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it.  In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2067 (define_peephole2
2068   [(match_scratch:DI 2 "r")
2069    (set (match_operand:DI 0 "push_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072    && !x86_64_immediate_operand (operands[1], DImode)"
2073   [(set (match_dup 2) (match_dup 1))
2074    (set (match_dup 0) (match_dup 2))]
2075   "")
2076
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 (define_peephole2
2081   [(set (match_operand:DI 0 "push_operand" "")
2082         (match_operand:DI 1 "immediate_operand" ""))]
2083   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085   [(set (match_dup 0) (match_dup 1))
2086    (set (match_dup 2) (match_dup 3))]
2087   "split_di (operands + 1, 1, operands + 2, operands + 3);
2088    operands[1] = gen_lowpart (DImode, operands[2]);
2089    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2090                                                     GEN_INT (4)));
2091   ")
2092
2093 (define_split
2094   [(set (match_operand:DI 0 "push_operand" "")
2095         (match_operand:DI 1 "immediate_operand" ""))]
2096   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097                     ? epilogue_completed : reload_completed)
2098    && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode)"
2100   [(set (match_dup 0) (match_dup 1))
2101    (set (match_dup 2) (match_dup 3))]
2102   "split_di (operands + 1, 1, operands + 2, operands + 3);
2103    operands[1] = gen_lowpart (DImode, operands[2]);
2104    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2105                                                     GEN_INT (4)));
2106   ")
2107
2108 (define_insn "*pushdi2_prologue_rex64"
2109   [(set (match_operand:DI 0 "push_operand" "=<")
2110         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111    (clobber (mem:BLK (scratch)))]
2112   "TARGET_64BIT"
2113   "push{q}\t%1"
2114   [(set_attr "type" "push")
2115    (set_attr "mode" "DI")])
2116
2117 (define_insn "*popdi1_epilogue_rex64"
2118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119         (mem:DI (reg:DI SP_REG)))
2120    (set (reg:DI SP_REG)
2121         (plus:DI (reg:DI SP_REG) (const_int 8)))
2122    (clobber (mem:BLK (scratch)))]
2123   "TARGET_64BIT"
2124   "pop{q}\t%0"
2125   [(set_attr "type" "pop")
2126    (set_attr "mode" "DI")])
2127
2128 (define_insn "popdi1"
2129   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130         (mem:DI (reg:DI SP_REG)))
2131    (set (reg:DI SP_REG)
2132         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2133   "TARGET_64BIT"
2134   "pop{q}\t%0"
2135   [(set_attr "type" "pop")
2136    (set_attr "mode" "DI")])
2137
2138 (define_insn "*movdi_xor_rex64"
2139   [(set (match_operand:DI 0 "register_operand" "=r")
2140         (match_operand:DI 1 "const0_operand" "i"))
2141    (clobber (reg:CC FLAGS_REG))]
2142   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143    && reload_completed"
2144   "xor{l}\t%k0, %k0";
2145   [(set_attr "type" "alu1")
2146    (set_attr "mode" "SI")
2147    (set_attr "length_immediate" "0")])
2148
2149 (define_insn "*movdi_or_rex64"
2150   [(set (match_operand:DI 0 "register_operand" "=r")
2151         (match_operand:DI 1 "const_int_operand" "i"))
2152    (clobber (reg:CC FLAGS_REG))]
2153   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2154    && reload_completed
2155    && operands[1] == constm1_rtx"
2156 {
2157   operands[1] = constm1_rtx;
2158   return "or{q}\t{%1, %0|%0, %1}";
2159 }
2160   [(set_attr "type" "alu1")
2161    (set_attr "mode" "DI")
2162    (set_attr "length_immediate" "1")])
2163
2164 (define_insn "*movdi_2"
2165   [(set (match_operand:DI 0 "nonimmediate_operand"
2166                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2167         (match_operand:DI 1 "general_operand"
2168                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2169   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2170   "@
2171    #
2172    #
2173    pxor\t%0, %0
2174    movq\t{%1, %0|%0, %1}
2175    movq\t{%1, %0|%0, %1}
2176    pxor\t%0, %0
2177    movq\t{%1, %0|%0, %1}
2178    movdqa\t{%1, %0|%0, %1}
2179    movq\t{%1, %0|%0, %1}
2180    xorps\t%0, %0
2181    movlps\t{%1, %0|%0, %1}
2182    movaps\t{%1, %0|%0, %1}
2183    movlps\t{%1, %0|%0, %1}"
2184   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2186
2187 (define_split
2188   [(set (match_operand:DI 0 "push_operand" "")
2189         (match_operand:DI 1 "general_operand" ""))]
2190   "!TARGET_64BIT && reload_completed
2191    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2192   [(const_int 0)]
2193   "ix86_split_long_move (operands); DONE;")
2194
2195 ;; %%% This multiword shite has got to go.
2196 (define_split
2197   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198         (match_operand:DI 1 "general_operand" ""))]
2199   "!TARGET_64BIT && reload_completed
2200    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2202   [(const_int 0)]
2203   "ix86_split_long_move (operands); DONE;")
2204
2205 (define_insn "*movdi_1_rex64"
2206   [(set (match_operand:DI 0 "nonimmediate_operand"
2207           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208         (match_operand:DI 1 "general_operand"
2209           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2210   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2211 {
2212   switch (get_attr_type (insn))
2213     {
2214     case TYPE_SSECVT:
2215       if (SSE_REG_P (operands[0]))
2216         return "movq2dq\t{%1, %0|%0, %1}";
2217       else
2218         return "movdq2q\t{%1, %0|%0, %1}";
2219
2220     case TYPE_SSEMOV:
2221       if (get_attr_mode (insn) == MODE_TI)
2222         return "movdqa\t{%1, %0|%0, %1}";
2223       /* FALLTHRU */
2224
2225     case TYPE_MMXMOV:
2226       /* Moves from and into integer register is done using movd
2227          opcode with REX prefix.  */
2228       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229         return "movd\t{%1, %0|%0, %1}";
2230       return "movq\t{%1, %0|%0, %1}";
2231
2232     case TYPE_SSELOG1:
2233     case TYPE_MMXADD:
2234       return "pxor\t%0, %0";
2235
2236     case TYPE_MULTI:
2237       return "#";
2238
2239     case TYPE_LEA:
2240       return "lea{q}\t{%a1, %0|%0, %a1}";
2241
2242     default:
2243       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244       if (get_attr_mode (insn) == MODE_SI)
2245         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246       else if (which_alternative == 2)
2247         return "movabs{q}\t{%1, %0|%0, %1}";
2248       else
2249         return "mov{q}\t{%1, %0|%0, %1}";
2250     }
2251 }
2252   [(set (attr "type")
2253      (cond [(eq_attr "alternative" "5")
2254               (const_string "mmxadd")
2255             (eq_attr "alternative" "6,7,8,9,10")
2256               (const_string "mmxmov")
2257             (eq_attr "alternative" "11")
2258               (const_string "sselog1")
2259             (eq_attr "alternative" "12,13,14,15,16")
2260               (const_string "ssemov")
2261             (eq_attr "alternative" "17,18")
2262               (const_string "ssecvt")
2263             (eq_attr "alternative" "4")
2264               (const_string "multi")
2265             (match_operand:DI 1 "pic_32bit_operand" "")
2266               (const_string "lea")
2267            ]
2268            (const_string "imov")))
2269    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2272
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2280   "@
2281    movabs{q}\t{%1, %P0|%P0, %1}
2282    mov{q}\t{%1, %a0|%a0, %1}"
2283   [(set_attr "type" "imov")
2284    (set_attr "modrm" "0,*")
2285    (set_attr "length_address" "8,0")
2286    (set_attr "length_immediate" "0,*")
2287    (set_attr "memory" "store")
2288    (set_attr "mode" "DI")])
2289
2290 (define_insn "*movabsdi_2_rex64"
2291   [(set (match_operand:DI 0 "register_operand" "=a,r")
2292         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2294   "@
2295    movabs{q}\t{%P1, %0|%0, %P1}
2296    mov{q}\t{%a1, %0|%0, %a1}"
2297   [(set_attr "type" "imov")
2298    (set_attr "modrm" "0,*")
2299    (set_attr "length_address" "8,0")
2300    (set_attr "length_immediate" "0")
2301    (set_attr "memory" "load")
2302    (set_attr "mode" "DI")])
2303
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it.  In case this
2306 ;; fails, move by 32bit parts.
2307 (define_peephole2
2308   [(match_scratch:DI 2 "r")
2309    (set (match_operand:DI 0 "memory_operand" "")
2310         (match_operand:DI 1 "immediate_operand" ""))]
2311   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312    && !x86_64_immediate_operand (operands[1], DImode)"
2313   [(set (match_dup 2) (match_dup 1))
2314    (set (match_dup 0) (match_dup 2))]
2315   "")
2316
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2320 (define_peephole2
2321   [(set (match_operand:DI 0 "memory_operand" "")
2322         (match_operand:DI 1 "immediate_operand" ""))]
2323   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325   [(set (match_dup 2) (match_dup 3))
2326    (set (match_dup 4) (match_dup 5))]
2327   "split_di (operands, 2, operands + 2, operands + 4);")
2328
2329 (define_split
2330   [(set (match_operand:DI 0 "memory_operand" "")
2331         (match_operand:DI 1 "immediate_operand" ""))]
2332   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333                     ? epilogue_completed : reload_completed)
2334    && !symbolic_operand (operands[1], DImode)
2335    && !x86_64_immediate_operand (operands[1], DImode)"
2336   [(set (match_dup 2) (match_dup 3))
2337    (set (match_dup 4) (match_dup 5))]
2338   "split_di (operands, 2, operands + 2, operands + 4);")
2339
2340 (define_insn "*swapdi_rex64"
2341   [(set (match_operand:DI 0 "register_operand" "+r")
2342         (match_operand:DI 1 "register_operand" "+r"))
2343    (set (match_dup 1)
2344         (match_dup 0))]
2345   "TARGET_64BIT"
2346   "xchg{q}\t%1, %0"
2347   [(set_attr "type" "imov")
2348    (set_attr "mode" "DI")
2349    (set_attr "pent_pair" "np")
2350    (set_attr "athlon_decode" "vector")
2351    (set_attr "amdfam10_decode" "double")])
2352
2353 (define_expand "movti"
2354   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355         (match_operand:TI 1 "nonimmediate_operand" ""))]
2356   "TARGET_SSE || TARGET_64BIT"
2357 {
2358   if (TARGET_64BIT)
2359     ix86_expand_move (TImode, operands);
2360   else if (push_operand (operands[0], TImode))
2361     ix86_expand_push (TImode, operands[1]);
2362   else
2363     ix86_expand_vector_move (TImode, operands);
2364   DONE;
2365 })
2366
2367 (define_insn "*movti_internal"
2368   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370   "TARGET_SSE && !TARGET_64BIT
2371    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2372 {
2373   switch (which_alternative)
2374     {
2375     case 0:
2376       if (get_attr_mode (insn) == MODE_V4SF)
2377         return "xorps\t%0, %0";
2378       else
2379         return "pxor\t%0, %0";
2380     case 1:
2381     case 2:
2382       if (get_attr_mode (insn) == MODE_V4SF)
2383         return "movaps\t{%1, %0|%0, %1}";
2384       else
2385         return "movdqa\t{%1, %0|%0, %1}";
2386     default:
2387       gcc_unreachable ();
2388     }
2389 }
2390   [(set_attr "type" "sselog1,ssemov,ssemov")
2391    (set (attr "mode")
2392         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393                     (ne (symbol_ref "optimize_size") (const_int 0)))
2394                  (const_string "V4SF")
2395                (and (eq_attr "alternative" "2")
2396                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2397                         (const_int 0)))
2398                  (const_string "V4SF")]
2399               (const_string "TI")))])
2400
2401 (define_insn "*movti_rex64"
2402   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2404   "TARGET_64BIT
2405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2406 {
2407   switch (which_alternative)
2408     {
2409     case 0:
2410     case 1:
2411       return "#";
2412     case 2:
2413       if (get_attr_mode (insn) == MODE_V4SF)
2414         return "xorps\t%0, %0";
2415       else
2416         return "pxor\t%0, %0";
2417     case 3:
2418     case 4:
2419       if (get_attr_mode (insn) == MODE_V4SF)
2420         return "movaps\t{%1, %0|%0, %1}";
2421       else
2422         return "movdqa\t{%1, %0|%0, %1}";
2423     default:
2424       gcc_unreachable ();
2425     }
2426 }
2427   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2428    (set (attr "mode")
2429         (cond [(eq_attr "alternative" "2,3")
2430                  (if_then_else
2431                    (ne (symbol_ref "optimize_size")
2432                        (const_int 0))
2433                    (const_string "V4SF")
2434                    (const_string "TI"))
2435                (eq_attr "alternative" "4")
2436                  (if_then_else
2437                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2438                             (const_int 0))
2439                         (ne (symbol_ref "optimize_size")
2440                             (const_int 0)))
2441                    (const_string "V4SF")
2442                    (const_string "TI"))]
2443                (const_string "DI")))])
2444
2445 (define_split
2446   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447         (match_operand:TI 1 "general_operand" ""))]
2448   "reload_completed && !SSE_REG_P (operands[0])
2449    && !SSE_REG_P (operands[1])"
2450   [(const_int 0)]
2451   "ix86_split_long_move (operands); DONE;")
2452
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern.  Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459         (match_operand:CDI 1 "general_operand" ""))]
2460   ""
2461 {
2462   if (push_operand (operands[0], CDImode))
2463     emit_move_complex_push (CDImode, operands[0], operands[1]);
2464   else
2465     emit_move_complex_parts (operands[0], operands[1]);
2466   DONE;
2467 })
2468
2469 (define_expand "movsf"
2470   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471         (match_operand:SF 1 "general_operand" ""))]
2472   ""
2473   "ix86_expand_move (SFmode, operands); DONE;")
2474
2475 (define_insn "*pushsf"
2476   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2478   "!TARGET_64BIT"
2479 {
2480   /* Anything else should be already split before reg-stack.  */
2481   gcc_assert (which_alternative == 1);
2482   return "push{l}\t%1";
2483 }
2484   [(set_attr "type" "multi,push,multi")
2485    (set_attr "unit" "i387,*,*")
2486    (set_attr "mode" "SF,SI,SF")])
2487
2488 (define_insn "*pushsf_rex64"
2489   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2491   "TARGET_64BIT"
2492 {
2493   /* Anything else should be already split before reg-stack.  */
2494   gcc_assert (which_alternative == 1);
2495   return "push{q}\t%q1";
2496 }
2497   [(set_attr "type" "multi,push,multi")
2498    (set_attr "unit" "i387,*,*")
2499    (set_attr "mode" "SF,DI,SF")])
2500
2501 (define_split
2502   [(set (match_operand:SF 0 "push_operand" "")
2503         (match_operand:SF 1 "memory_operand" ""))]
2504   "reload_completed
2505    && MEM_P (operands[1])
2506    && (operands[2] = find_constant_src (insn))"
2507   [(set (match_dup 0)
2508         (match_dup 2))])
2509
2510
2511 ;; %%% Kill this when call knows how to work this out.
2512 (define_split
2513   [(set (match_operand:SF 0 "push_operand" "")
2514         (match_operand:SF 1 "any_fp_register_operand" ""))]
2515   "!TARGET_64BIT"
2516   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2518
2519 (define_split
2520   [(set (match_operand:SF 0 "push_operand" "")
2521         (match_operand:SF 1 "any_fp_register_operand" ""))]
2522   "TARGET_64BIT"
2523   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2525
2526 (define_insn "*movsf_1"
2527   [(set (match_operand:SF 0 "nonimmediate_operand"
2528           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529         (match_operand:SF 1 "general_operand"
2530           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2531   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532    && (reload_in_progress || reload_completed
2533        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534        || (!TARGET_SSE_MATH && optimize_size
2535            && standard_80387_constant_p (operands[1]))
2536        || GET_CODE (operands[1]) != CONST_DOUBLE
2537        || memory_operand (operands[0], SFmode))"
2538 {
2539   switch (which_alternative)
2540     {
2541     case 0:
2542     case 1:
2543       return output_387_reg_move (insn, operands);
2544
2545     case 2:
2546       return standard_80387_constant_opcode (operands[1]);
2547
2548     case 3:
2549     case 4:
2550       return "mov{l}\t{%1, %0|%0, %1}";
2551     case 5:
2552       if (get_attr_mode (insn) == MODE_TI)
2553         return "pxor\t%0, %0";
2554       else
2555         return "xorps\t%0, %0";
2556     case 6:
2557       if (get_attr_mode (insn) == MODE_V4SF)
2558         return "movaps\t{%1, %0|%0, %1}";
2559       else
2560         return "movss\t{%1, %0|%0, %1}";
2561     case 7: case 8:
2562       return "movss\t{%1, %0|%0, %1}";
2563
2564     case 9: case 10:
2565     case 12: case 13: case 14: case 15:
2566       return "movd\t{%1, %0|%0, %1}";
2567
2568     case 11:
2569       return "movq\t{%1, %0|%0, %1}";
2570
2571     default:
2572       gcc_unreachable ();
2573     }
2574 }
2575   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2576    (set (attr "mode")
2577         (cond [(eq_attr "alternative" "3,4,9,10")
2578                  (const_string "SI")
2579                (eq_attr "alternative" "5")
2580                  (if_then_else
2581                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582                                  (const_int 0))
2583                              (ne (symbol_ref "TARGET_SSE2")
2584                                  (const_int 0)))
2585                         (eq (symbol_ref "optimize_size")
2586                             (const_int 0)))
2587                    (const_string "TI")
2588                    (const_string "V4SF"))
2589                /* For architectures resolving dependencies on
2590                   whole SSE registers use APS move to break dependency
2591                   chains, otherwise use short move to avoid extra work.
2592
2593                   Do the same for architectures resolving dependencies on
2594                   the parts.  While in DF mode it is better to always handle
2595                   just register parts, the SF mode is different due to lack
2596                   of instructions to load just part of the register.  It is
2597                   better to maintain the whole registers in single format
2598                   to avoid problems on using packed logical operations.  */
2599                (eq_attr "alternative" "6")
2600                  (if_then_else
2601                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602                             (const_int 0))
2603                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604                             (const_int 0)))
2605                    (const_string "V4SF")
2606                    (const_string "SF"))
2607                (eq_attr "alternative" "11")
2608                  (const_string "DI")]
2609                (const_string "SF")))])
2610
2611 (define_insn "*swapsf"
2612   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613         (match_operand:SF 1 "fp_register_operand" "+f"))
2614    (set (match_dup 1)
2615         (match_dup 0))]
2616   "reload_completed || TARGET_80387"
2617 {
2618   if (STACK_TOP_P (operands[0]))
2619     return "fxch\t%1";
2620   else
2621     return "fxch\t%0";
2622 }
2623   [(set_attr "type" "fxch")
2624    (set_attr "mode" "SF")])
2625
2626 (define_expand "movdf"
2627   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628         (match_operand:DF 1 "general_operand" ""))]
2629   ""
2630   "ix86_expand_move (DFmode, operands); DONE;")
2631
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter.  Allow this
2635 ;; pattern for optimize_size too.
2636
2637 (define_insn "*pushdf_nointeger"
2638   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2641 {
2642   /* This insn should be already split before reg-stack.  */
2643   gcc_unreachable ();
2644 }
2645   [(set_attr "type" "multi")
2646    (set_attr "unit" "i387,*,*,*")
2647    (set_attr "mode" "DF,SI,SI,DF")])
2648
2649 (define_insn "*pushdf_integer"
2650   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2653 {
2654   /* This insn should be already split before reg-stack.  */
2655   gcc_unreachable ();
2656 }
2657   [(set_attr "type" "multi")
2658    (set_attr "unit" "i387,*,*")
2659    (set_attr "mode" "DF,SI,DF")])
2660
2661 ;; %%% Kill this when call knows how to work this out.
2662 (define_split
2663   [(set (match_operand:DF 0 "push_operand" "")
2664         (match_operand:DF 1 "any_fp_register_operand" ""))]
2665   "!TARGET_64BIT && reload_completed"
2666   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2668   "")
2669
2670 (define_split
2671   [(set (match_operand:DF 0 "push_operand" "")
2672         (match_operand:DF 1 "any_fp_register_operand" ""))]
2673   "TARGET_64BIT && reload_completed"
2674   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2676   "")
2677
2678 (define_split
2679   [(set (match_operand:DF 0 "push_operand" "")
2680         (match_operand:DF 1 "general_operand" ""))]
2681   "reload_completed"
2682   [(const_int 0)]
2683   "ix86_split_long_move (operands); DONE;")
2684
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2688
2689 (define_insn "*movdf_nointeger"
2690   [(set (match_operand:DF 0 "nonimmediate_operand"
2691                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2692         (match_operand:DF 1 "general_operand"
2693                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2694   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696    && (reload_in_progress || reload_completed
2697        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699            && standard_80387_constant_p (operands[1]))
2700        || GET_CODE (operands[1]) != CONST_DOUBLE
2701        || memory_operand (operands[0], DFmode))"
2702 {
2703   switch (which_alternative)
2704     {
2705     case 0:
2706     case 1:
2707       return output_387_reg_move (insn, operands);
2708
2709     case 2:
2710       return standard_80387_constant_opcode (operands[1]);
2711
2712     case 3:
2713     case 4:
2714       return "#";
2715     case 5:
2716       switch (get_attr_mode (insn))
2717         {
2718         case MODE_V4SF:
2719           return "xorps\t%0, %0";
2720         case MODE_V2DF:
2721           return "xorpd\t%0, %0";
2722         case MODE_TI:
2723           return "pxor\t%0, %0";
2724         default:
2725           gcc_unreachable ();
2726         }
2727     case 6:
2728     case 7:
2729     case 8:
2730       switch (get_attr_mode (insn))
2731         {
2732         case MODE_V4SF:
2733           return "movaps\t{%1, %0|%0, %1}";
2734         case MODE_V2DF:
2735           return "movapd\t{%1, %0|%0, %1}";
2736         case MODE_TI:
2737           return "movdqa\t{%1, %0|%0, %1}";
2738         case MODE_DI:
2739           return "movq\t{%1, %0|%0, %1}";
2740         case MODE_DF:
2741           return "movsd\t{%1, %0|%0, %1}";
2742         case MODE_V1DF:
2743           return "movlpd\t{%1, %0|%0, %1}";
2744         case MODE_V2SF:
2745           return "movlps\t{%1, %0|%0, %1}";
2746         default:
2747           gcc_unreachable ();
2748         }
2749
2750     default:
2751       gcc_unreachable ();
2752     }
2753 }
2754   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2755    (set (attr "mode")
2756         (cond [(eq_attr "alternative" "0,1,2")
2757                  (const_string "DF")
2758                (eq_attr "alternative" "3,4")
2759                  (const_string "SI")
2760
2761                /* For SSE1, we have many fewer alternatives.  */
2762                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2763                  (cond [(eq_attr "alternative" "5,6")
2764                           (const_string "V4SF")
2765                        ]
2766                    (const_string "V2SF"))
2767
2768                /* xorps is one byte shorter.  */
2769                (eq_attr "alternative" "5")
2770                  (cond [(ne (symbol_ref "optimize_size")
2771                             (const_int 0))
2772                           (const_string "V4SF")
2773                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2774                             (const_int 0))
2775                           (const_string "TI")
2776                        ]
2777                        (const_string "V2DF"))
2778
2779                /* For architectures resolving dependencies on
2780                   whole SSE registers use APD move to break dependency
2781                   chains, otherwise use short move to avoid extra work.
2782
2783                   movaps encodes one byte shorter.  */
2784                (eq_attr "alternative" "6")
2785                  (cond
2786                    [(ne (symbol_ref "optimize_size")
2787                         (const_int 0))
2788                       (const_string "V4SF")
2789                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2790                         (const_int 0))
2791                       (const_string "V2DF")
2792                    ]
2793                    (const_string "DF"))
2794                /* For architectures resolving dependencies on register
2795                   parts we may avoid extra work to zero out upper part
2796                   of register.  */
2797                (eq_attr "alternative" "7")
2798                  (if_then_else
2799                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2800                        (const_int 0))
2801                    (const_string "V1DF")
2802                    (const_string "DF"))
2803               ]
2804               (const_string "DF")))])
2805
2806 (define_insn "*movdf_integer_rex64"
2807   [(set (match_operand:DF 0 "nonimmediate_operand"
2808                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2809         (match_operand:DF 1 "general_operand"
2810                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2811   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812    && (reload_in_progress || reload_completed
2813        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2814        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2815            && standard_80387_constant_p (operands[1]))
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], DFmode))"
2818 {
2819   switch (which_alternative)
2820     {
2821     case 0:
2822     case 1:
2823       return output_387_reg_move (insn, operands);
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3:
2829     case 4:
2830       return "#";
2831
2832     case 5:
2833       switch (get_attr_mode (insn))
2834         {
2835         case MODE_V4SF:
2836           return "xorps\t%0, %0";
2837         case MODE_V2DF:
2838           return "xorpd\t%0, %0";
2839         case MODE_TI:
2840           return "pxor\t%0, %0";
2841         default:
2842           gcc_unreachable ();
2843         }
2844     case 6:
2845     case 7:
2846     case 8:
2847       switch (get_attr_mode (insn))
2848         {
2849         case MODE_V4SF:
2850           return "movaps\t{%1, %0|%0, %1}";
2851         case MODE_V2DF:
2852           return "movapd\t{%1, %0|%0, %1}";
2853         case MODE_TI:
2854           return "movdqa\t{%1, %0|%0, %1}";
2855         case MODE_DI:
2856           return "movq\t{%1, %0|%0, %1}";
2857         case MODE_DF:
2858           return "movsd\t{%1, %0|%0, %1}";
2859         case MODE_V1DF:
2860           return "movlpd\t{%1, %0|%0, %1}";
2861         case MODE_V2SF:
2862           return "movlps\t{%1, %0|%0, %1}";
2863         default:
2864           gcc_unreachable ();
2865         }
2866
2867     case 9:
2868     case 10:
2869       return "movd\t{%1, %0|%0, %1}";
2870
2871     default:
2872       gcc_unreachable();
2873     }
2874 }
2875   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2876    (set (attr "mode")
2877         (cond [(eq_attr "alternative" "0,1,2")
2878                  (const_string "DF")
2879                (eq_attr "alternative" "3,4,9,10")
2880                  (const_string "DI")
2881
2882                /* For SSE1, we have many fewer alternatives.  */
2883                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2884                  (cond [(eq_attr "alternative" "5,6")
2885                           (const_string "V4SF")
2886                        ]
2887                    (const_string "V2SF"))
2888
2889                /* xorps is one byte shorter.  */
2890                (eq_attr "alternative" "5")
2891                  (cond [(ne (symbol_ref "optimize_size")
2892                             (const_int 0))
2893                           (const_string "V4SF")
2894                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2895                             (const_int 0))
2896                           (const_string "TI")
2897                        ]
2898                        (const_string "V2DF"))
2899
2900                /* For architectures resolving dependencies on
2901                   whole SSE registers use APD move to break dependency
2902                   chains, otherwise use short move to avoid extra work.
2903
2904                   movaps encodes one byte shorter.  */
2905                (eq_attr "alternative" "6")
2906                  (cond
2907                    [(ne (symbol_ref "optimize_size")
2908                         (const_int 0))
2909                       (const_string "V4SF")
2910                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2911                         (const_int 0))
2912                       (const_string "V2DF")
2913                    ]
2914                    (const_string "DF"))
2915                /* For architectures resolving dependencies on register
2916                   parts we may avoid extra work to zero out upper part
2917                   of register.  */
2918                (eq_attr "alternative" "7")
2919                  (if_then_else
2920                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2921                        (const_int 0))
2922                    (const_string "V1DF")
2923                    (const_string "DF"))
2924               ]
2925               (const_string "DF")))])
2926
2927 (define_insn "*movdf_integer"
2928   [(set (match_operand:DF 0 "nonimmediate_operand"
2929                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2930         (match_operand:DF 1 "general_operand"
2931                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2932   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2933    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2934    && (reload_in_progress || reload_completed
2935        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2936        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2937            && standard_80387_constant_p (operands[1]))
2938        || GET_CODE (operands[1]) != CONST_DOUBLE
2939        || memory_operand (operands[0], DFmode))"
2940 {
2941   switch (which_alternative)
2942     {
2943     case 0:
2944     case 1:
2945       return output_387_reg_move (insn, operands);
2946
2947     case 2:
2948       return standard_80387_constant_opcode (operands[1]);
2949
2950     case 3:
2951     case 4:
2952       return "#";
2953
2954     case 5:
2955       switch (get_attr_mode (insn))
2956         {
2957         case MODE_V4SF:
2958           return "xorps\t%0, %0";
2959         case MODE_V2DF:
2960           return "xorpd\t%0, %0";
2961         case MODE_TI:
2962           return "pxor\t%0, %0";
2963         default:
2964           gcc_unreachable ();
2965         }
2966     case 6:
2967     case 7:
2968     case 8:
2969       switch (get_attr_mode (insn))
2970         {
2971         case MODE_V4SF:
2972           return "movaps\t{%1, %0|%0, %1}";
2973         case MODE_V2DF:
2974           return "movapd\t{%1, %0|%0, %1}";
2975         case MODE_TI:
2976           return "movdqa\t{%1, %0|%0, %1}";
2977         case MODE_DI:
2978           return "movq\t{%1, %0|%0, %1}";
2979         case MODE_DF:
2980           return "movsd\t{%1, %0|%0, %1}";
2981         case MODE_V1DF:
2982           return "movlpd\t{%1, %0|%0, %1}";
2983         case MODE_V2SF:
2984           return "movlps\t{%1, %0|%0, %1}";
2985         default:
2986           gcc_unreachable ();
2987         }
2988
2989     default:
2990       gcc_unreachable();
2991     }
2992 }
2993   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2994    (set (attr "mode")
2995         (cond [(eq_attr "alternative" "0,1,2")
2996                  (const_string "DF")
2997                (eq_attr "alternative" "3,4")
2998                  (const_string "SI")
2999
3000                /* For SSE1, we have many fewer alternatives.  */
3001                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3002                  (cond [(eq_attr "alternative" "5,6")
3003                           (const_string "V4SF")
3004                        ]
3005                    (const_string "V2SF"))
3006
3007                /* xorps is one byte shorter.  */
3008                (eq_attr "alternative" "5")
3009                  (cond [(ne (symbol_ref "optimize_size")
3010                             (const_int 0))
3011                           (const_string "V4SF")
3012                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3013                             (const_int 0))
3014                           (const_string "TI")
3015                        ]
3016                        (const_string "V2DF"))
3017
3018                /* For architectures resolving dependencies on
3019                   whole SSE registers use APD move to break dependency
3020                   chains, otherwise use short move to avoid extra work.
3021
3022                   movaps encodes one byte shorter.  */
3023                (eq_attr "alternative" "6")
3024                  (cond
3025                    [(ne (symbol_ref "optimize_size")
3026                         (const_int 0))
3027                       (const_string "V4SF")
3028                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029                         (const_int 0))
3030                       (const_string "V2DF")
3031                    ]
3032                    (const_string "DF"))
3033                /* For architectures resolving dependencies on register
3034                   parts we may avoid extra work to zero out upper part
3035                   of register.  */
3036                (eq_attr "alternative" "7")
3037                  (if_then_else
3038                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3039                        (const_int 0))
3040                    (const_string "V1DF")
3041                    (const_string "DF"))
3042               ]
3043               (const_string "DF")))])
3044
3045 (define_split
3046   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3047         (match_operand:DF 1 "general_operand" ""))]
3048   "reload_completed
3049    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050    && ! (ANY_FP_REG_P (operands[0]) ||
3051          (GET_CODE (operands[0]) == SUBREG
3052           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3053    && ! (ANY_FP_REG_P (operands[1]) ||
3054          (GET_CODE (operands[1]) == SUBREG
3055           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3056   [(const_int 0)]
3057   "ix86_split_long_move (operands); DONE;")
3058
3059 (define_insn "*swapdf"
3060   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3061         (match_operand:DF 1 "fp_register_operand" "+f"))
3062    (set (match_dup 1)
3063         (match_dup 0))]
3064   "reload_completed || TARGET_80387"
3065 {
3066   if (STACK_TOP_P (operands[0]))
3067     return "fxch\t%1";
3068   else
3069     return "fxch\t%0";
3070 }
3071   [(set_attr "type" "fxch")
3072    (set_attr "mode" "DF")])
3073
3074 (define_expand "movxf"
3075   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3076         (match_operand:XF 1 "general_operand" ""))]
3077   ""
3078   "ix86_expand_move (XFmode, operands); DONE;")
3079
3080 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3081 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3082 ;; Pushing using integer instructions is longer except for constants
3083 ;; and direct memory references.
3084 ;; (assuming that any given constant is pushed only once, but this ought to be
3085 ;;  handled elsewhere).
3086
3087 (define_insn "*pushxf_nointeger"
3088   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3089         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3090   "optimize_size"
3091 {
3092   /* This insn should be already split before reg-stack.  */
3093   gcc_unreachable ();
3094 }
3095   [(set_attr "type" "multi")
3096    (set_attr "unit" "i387,*,*")
3097    (set_attr "mode" "XF,SI,SI")])
3098
3099 (define_insn "*pushxf_integer"
3100   [(set (match_operand:XF 0 "push_operand" "=<,<")
3101         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3102   "!optimize_size"
3103 {
3104   /* This insn should be already split before reg-stack.  */
3105   gcc_unreachable ();
3106 }
3107   [(set_attr "type" "multi")
3108    (set_attr "unit" "i387,*")
3109    (set_attr "mode" "XF,SI")])
3110
3111 (define_split
3112   [(set (match_operand 0 "push_operand" "")
3113         (match_operand 1 "general_operand" ""))]
3114   "reload_completed
3115    && (GET_MODE (operands[0]) == XFmode
3116        || GET_MODE (operands[0]) == DFmode)
3117    && !ANY_FP_REG_P (operands[1])"
3118   [(const_int 0)]
3119   "ix86_split_long_move (operands); DONE;")
3120
3121 (define_split
3122   [(set (match_operand:XF 0 "push_operand" "")
3123         (match_operand:XF 1 "any_fp_register_operand" ""))]
3124   "!TARGET_64BIT"
3125   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3126    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3127   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3128
3129 (define_split
3130   [(set (match_operand:XF 0 "push_operand" "")
3131         (match_operand:XF 1 "any_fp_register_operand" ""))]
3132   "TARGET_64BIT"
3133   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3134    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3135   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3136
3137 ;; Do not use integer registers when optimizing for size
3138 (define_insn "*movxf_nointeger"
3139   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3140         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3141   "optimize_size
3142    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3143    && (reload_in_progress || reload_completed
3144        || (optimize_size && standard_80387_constant_p (operands[1]))
3145        || GET_CODE (operands[1]) != CONST_DOUBLE
3146        || memory_operand (operands[0], XFmode))"
3147 {
3148   switch (which_alternative)
3149     {
3150     case 0:
3151     case 1:
3152       return output_387_reg_move (insn, operands);
3153
3154     case 2:
3155       return standard_80387_constant_opcode (operands[1]);
3156
3157     case 3: case 4:
3158       return "#";
3159     default:
3160       gcc_unreachable ();
3161     }
3162 }
3163   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3164    (set_attr "mode" "XF,XF,XF,SI,SI")])
3165
3166 (define_insn "*movxf_integer"
3167   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3168         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3169   "!optimize_size
3170    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3171    && (reload_in_progress || reload_completed
3172        || (optimize_size && standard_80387_constant_p (operands[1]))
3173        || GET_CODE (operands[1]) != CONST_DOUBLE
3174        || memory_operand (operands[0], XFmode))"
3175 {
3176   switch (which_alternative)
3177     {
3178     case 0:
3179     case 1:
3180       return output_387_reg_move (insn, operands);
3181
3182     case 2:
3183       return standard_80387_constant_opcode (operands[1]);
3184
3185     case 3: case 4:
3186       return "#";
3187
3188     default:
3189       gcc_unreachable ();
3190     }
3191 }
3192   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3193    (set_attr "mode" "XF,XF,XF,SI,SI")])
3194
3195 (define_expand "movtf"
3196   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3197         (match_operand:TF 1 "nonimmediate_operand" ""))]
3198   "TARGET_64BIT"
3199 {
3200   ix86_expand_move (TFmode, operands);
3201   DONE;
3202 })
3203
3204 (define_insn "*movtf_internal"
3205   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3206         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3207   "TARGET_64BIT
3208    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3209 {
3210   switch (which_alternative)
3211     {
3212     case 0:
3213     case 1:
3214       if (get_attr_mode (insn) == MODE_V4SF)
3215         return "movaps\t{%1, %0|%0, %1}";
3216       else
3217         return "movdqa\t{%1, %0|%0, %1}";
3218     case 2:
3219       if (get_attr_mode (insn) == MODE_V4SF)
3220         return "xorps\t%0, %0";
3221       else
3222         return "pxor\t%0, %0";
3223     case 3:
3224     case 4:
3225         return "#";
3226     default:
3227       gcc_unreachable ();
3228     }
3229 }
3230   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3231    (set (attr "mode")
3232         (cond [(eq_attr "alternative" "0,2")
3233                  (if_then_else
3234                    (ne (symbol_ref "optimize_size")
3235                        (const_int 0))
3236                    (const_string "V4SF")
3237                    (const_string "TI"))
3238                (eq_attr "alternative" "1")
3239                  (if_then_else
3240                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3241                             (const_int 0))
3242                         (ne (symbol_ref "optimize_size")
3243                             (const_int 0)))
3244                    (const_string "V4SF")
3245                    (const_string "TI"))]
3246                (const_string "DI")))])
3247
3248 (define_split
3249   [(set (match_operand 0 "nonimmediate_operand" "")
3250         (match_operand 1 "general_operand" ""))]
3251   "reload_completed
3252    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3253    && GET_MODE (operands[0]) == XFmode
3254    && ! (ANY_FP_REG_P (operands[0]) ||
3255          (GET_CODE (operands[0]) == SUBREG
3256           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3257    && ! (ANY_FP_REG_P (operands[1]) ||
3258          (GET_CODE (operands[1]) == SUBREG
3259           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3260   [(const_int 0)]
3261   "ix86_split_long_move (operands); DONE;")
3262
3263 (define_split
3264   [(set (match_operand 0 "register_operand" "")
3265         (match_operand 1 "memory_operand" ""))]
3266   "reload_completed
3267    && MEM_P (operands[1])
3268    && (GET_MODE (operands[0]) == TFmode
3269        || GET_MODE (operands[0]) == XFmode
3270        || GET_MODE (operands[0]) == SFmode
3271        || GET_MODE (operands[0]) == DFmode)
3272    && (operands[2] = find_constant_src (insn))"
3273   [(set (match_dup 0) (match_dup 2))]
3274 {
3275   rtx c = operands[2];
3276   rtx r = operands[0];
3277
3278   if (GET_CODE (r) == SUBREG)
3279     r = SUBREG_REG (r);
3280
3281   if (SSE_REG_P (r))
3282     {
3283       if (!standard_sse_constant_p (c))
3284         FAIL;
3285     }
3286   else if (FP_REG_P (r))
3287     {
3288       if (!standard_80387_constant_p (c))
3289         FAIL;
3290     }
3291   else if (MMX_REG_P (r))
3292     FAIL;
3293 })
3294
3295 (define_split
3296   [(set (match_operand 0 "register_operand" "")
3297         (float_extend (match_operand 1 "memory_operand" "")))]
3298   "reload_completed
3299    && MEM_P (operands[1])
3300    && (GET_MODE (operands[0]) == TFmode
3301        || GET_MODE (operands[0]) == XFmode
3302        || GET_MODE (operands[0]) == SFmode
3303        || GET_MODE (operands[0]) == DFmode)
3304    && (operands[2] = find_constant_src (insn))"
3305   [(set (match_dup 0) (match_dup 2))]
3306 {
3307   rtx c = operands[2];
3308   rtx r = operands[0];
3309
3310   if (GET_CODE (r) == SUBREG)
3311     r = SUBREG_REG (r);
3312
3313   if (SSE_REG_P (r))
3314     {
3315       if (!standard_sse_constant_p (c))
3316         FAIL;
3317     }
3318   else if (FP_REG_P (r))
3319     {
3320       if (!standard_80387_constant_p (c))
3321         FAIL;
3322     }
3323   else if (MMX_REG_P (r))
3324     FAIL;
3325 })
3326
3327 (define_insn "swapxf"
3328   [(set (match_operand:XF 0 "register_operand" "+f")
3329         (match_operand:XF 1 "register_operand" "+f"))
3330    (set (match_dup 1)
3331         (match_dup 0))]
3332   "TARGET_80387"
3333 {
3334   if (STACK_TOP_P (operands[0]))
3335     return "fxch\t%1";
3336   else
3337     return "fxch\t%0";
3338 }
3339   [(set_attr "type" "fxch")
3340    (set_attr "mode" "XF")])
3341
3342 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3343 (define_split
3344   [(set (match_operand:X87MODEF 0 "register_operand" "")
3345         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3346   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3347    && (standard_80387_constant_p (operands[1]) == 8
3348        || standard_80387_constant_p (operands[1]) == 9)"
3349   [(set (match_dup 0)(match_dup 1))
3350    (set (match_dup 0)
3351         (neg:X87MODEF (match_dup 0)))]
3352 {
3353   REAL_VALUE_TYPE r;
3354
3355   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3356   if (real_isnegzero (&r))
3357     operands[1] = CONST0_RTX (<MODE>mode);
3358   else
3359     operands[1] = CONST1_RTX (<MODE>mode);
3360 })
3361
3362 (define_split
3363   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3364         (match_operand:TF 1 "general_operand" ""))]
3365   "reload_completed
3366    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3367   [(const_int 0)]
3368   "ix86_split_long_move (operands); DONE;")
3369 \f
3370 ;; Zero extension instructions
3371
3372 (define_expand "zero_extendhisi2"
3373   [(set (match_operand:SI 0 "register_operand" "")
3374      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3375   ""
3376 {
3377   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3378     {
3379       operands[1] = force_reg (HImode, operands[1]);
3380       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3381       DONE;
3382     }
3383 })
3384
3385 (define_insn "zero_extendhisi2_and"
3386   [(set (match_operand:SI 0 "register_operand" "=r")
3387      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3388    (clobber (reg:CC FLAGS_REG))]
3389   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3390   "#"
3391   [(set_attr "type" "alu1")
3392    (set_attr "mode" "SI")])
3393
3394 (define_split
3395   [(set (match_operand:SI 0 "register_operand" "")
3396         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3397    (clobber (reg:CC FLAGS_REG))]
3398   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3399   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3400               (clobber (reg:CC FLAGS_REG))])]
3401   "")
3402
3403 (define_insn "*zero_extendhisi2_movzwl"
3404   [(set (match_operand:SI 0 "register_operand" "=r")
3405      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3406   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3407   "movz{wl|x}\t{%1, %0|%0, %1}"
3408   [(set_attr "type" "imovx")
3409    (set_attr "mode" "SI")])
3410
3411 (define_expand "zero_extendqihi2"
3412   [(parallel
3413     [(set (match_operand:HI 0 "register_operand" "")
3414        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3415      (clobber (reg:CC FLAGS_REG))])]
3416   ""
3417   "")
3418
3419 (define_insn "*zero_extendqihi2_and"
3420   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3421      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3422    (clobber (reg:CC FLAGS_REG))]
3423   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3424   "#"
3425   [(set_attr "type" "alu1")
3426    (set_attr "mode" "HI")])
3427
3428 (define_insn "*zero_extendqihi2_movzbw_and"
3429   [(set (match_operand:HI 0 "register_operand" "=r,r")
3430      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3431    (clobber (reg:CC FLAGS_REG))]
3432   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3433   "#"
3434   [(set_attr "type" "imovx,alu1")
3435    (set_attr "mode" "HI")])
3436
3437 ; zero extend to SImode here to avoid partial register stalls
3438 (define_insn "*zero_extendqihi2_movzbl"
3439   [(set (match_operand:HI 0 "register_operand" "=r")
3440      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3441   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3442   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3443   [(set_attr "type" "imovx")
3444    (set_attr "mode" "SI")])
3445
3446 ;; For the movzbw case strip only the clobber
3447 (define_split
3448   [(set (match_operand:HI 0 "register_operand" "")
3449         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3450    (clobber (reg:CC FLAGS_REG))]
3451   "reload_completed
3452    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3453    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3454   [(set (match_operand:HI 0 "register_operand" "")
3455         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3456
3457 ;; When source and destination does not overlap, clear destination
3458 ;; first and then do the movb
3459 (define_split
3460   [(set (match_operand:HI 0 "register_operand" "")
3461         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3462    (clobber (reg:CC FLAGS_REG))]
3463   "reload_completed
3464    && ANY_QI_REG_P (operands[0])
3465    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3466    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3467   [(set (match_dup 0) (const_int 0))
3468    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3469   "operands[2] = gen_lowpart (QImode, operands[0]);")
3470
3471 ;; Rest is handled by single and.
3472 (define_split
3473   [(set (match_operand:HI 0 "register_operand" "")
3474         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3475    (clobber (reg:CC FLAGS_REG))]
3476   "reload_completed
3477    && true_regnum (operands[0]) == true_regnum (operands[1])"
3478   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3479               (clobber (reg:CC FLAGS_REG))])]
3480   "")
3481
3482 (define_expand "zero_extendqisi2"
3483   [(parallel
3484     [(set (match_operand:SI 0 "register_operand" "")
3485        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3486      (clobber (reg:CC FLAGS_REG))])]
3487   ""
3488   "")
3489
3490 (define_insn "*zero_extendqisi2_and"
3491   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3492      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3493    (clobber (reg:CC FLAGS_REG))]
3494   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3495   "#"
3496   [(set_attr "type" "alu1")
3497    (set_attr "mode" "SI")])
3498
3499 (define_insn "*zero_extendqisi2_movzbw_and"
3500   [(set (match_operand:SI 0 "register_operand" "=r,r")
3501      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3502    (clobber (reg:CC FLAGS_REG))]
3503   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3504   "#"
3505   [(set_attr "type" "imovx,alu1")
3506    (set_attr "mode" "SI")])
3507
3508 (define_insn "*zero_extendqisi2_movzbw"
3509   [(set (match_operand:SI 0 "register_operand" "=r")
3510      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3511   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3512   "movz{bl|x}\t{%1, %0|%0, %1}"
3513   [(set_attr "type" "imovx")
3514    (set_attr "mode" "SI")])
3515
3516 ;; For the movzbl case strip only the clobber
3517 (define_split
3518   [(set (match_operand:SI 0 "register_operand" "")
3519         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3520    (clobber (reg:CC FLAGS_REG))]
3521   "reload_completed
3522    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3523    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3524   [(set (match_dup 0)
3525         (zero_extend:SI (match_dup 1)))])
3526
3527 ;; When source and destination does not overlap, clear destination
3528 ;; first and then do the movb
3529 (define_split
3530   [(set (match_operand:SI 0 "register_operand" "")
3531         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3532    (clobber (reg:CC FLAGS_REG))]
3533   "reload_completed
3534    && ANY_QI_REG_P (operands[0])
3535    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3536    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3537    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3538   [(set (match_dup 0) (const_int 0))
3539    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3540   "operands[2] = gen_lowpart (QImode, operands[0]);")
3541
3542 ;; Rest is handled by single and.
3543 (define_split
3544   [(set (match_operand:SI 0 "register_operand" "")
3545         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3546    (clobber (reg:CC FLAGS_REG))]
3547   "reload_completed
3548    && true_regnum (operands[0]) == true_regnum (operands[1])"
3549   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3550               (clobber (reg:CC FLAGS_REG))])]
3551   "")
3552
3553 ;; %%% Kill me once multi-word ops are sane.
3554 (define_expand "zero_extendsidi2"
3555   [(set (match_operand:DI 0 "register_operand" "")
3556      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3557   ""
3558 {
3559   if (!TARGET_64BIT)
3560     {
3561       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3562       DONE;
3563     }
3564 })
3565
3566 (define_insn "zero_extendsidi2_32"
3567   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3568         (zero_extend:DI
3569          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3570    (clobber (reg:CC FLAGS_REG))]
3571   "!TARGET_64BIT"
3572   "@
3573    #
3574    #
3575    #
3576    movd\t{%1, %0|%0, %1}
3577    movd\t{%1, %0|%0, %1}
3578    movd\t{%1, %0|%0, %1}
3579    movd\t{%1, %0|%0, %1}"
3580   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3581    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3582
3583 (define_insn "zero_extendsidi2_rex64"
3584   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3585      (zero_extend:DI
3586        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3587   "TARGET_64BIT"
3588   "@
3589    mov\t{%k1, %k0|%k0, %k1}
3590    #
3591    movd\t{%1, %0|%0, %1}
3592    movd\t{%1, %0|%0, %1}
3593    movd\t{%1, %0|%0, %1}
3594    movd\t{%1, %0|%0, %1}"
3595   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3596    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3597
3598 (define_split
3599   [(set (match_operand:DI 0 "memory_operand" "")
3600      (zero_extend:DI (match_dup 0)))]
3601   "TARGET_64BIT"
3602   [(set (match_dup 4) (const_int 0))]
3603   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3604
3605 (define_split
3606   [(set (match_operand:DI 0 "register_operand" "")
3607         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3608    (clobber (reg:CC FLAGS_REG))]
3609   "!TARGET_64BIT && reload_completed
3610    && true_regnum (operands[0]) == true_regnum (operands[1])"
3611   [(set (match_dup 4) (const_int 0))]
3612   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3613
3614 (define_split
3615   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3616         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3617    (clobber (reg:CC FLAGS_REG))]
3618   "!TARGET_64BIT && reload_completed
3619    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3620   [(set (match_dup 3) (match_dup 1))
3621    (set (match_dup 4) (const_int 0))]
3622   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3623
3624 (define_insn "zero_extendhidi2"
3625   [(set (match_operand:DI 0 "register_operand" "=r")
3626      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3627   "TARGET_64BIT"
3628   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3629   [(set_attr "type" "imovx")
3630    (set_attr "mode" "DI")])
3631
3632 (define_insn "zero_extendqidi2"
3633   [(set (match_operand:DI 0 "register_operand" "=r")
3634      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3635   "TARGET_64BIT"
3636   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3637   [(set_attr "type" "imovx")
3638    (set_attr "mode" "DI")])
3639 \f
3640 ;; Sign extension instructions
3641
3642 (define_expand "extendsidi2"
3643   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3644                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3645               (clobber (reg:CC FLAGS_REG))
3646               (clobber (match_scratch:SI 2 ""))])]
3647   ""
3648 {
3649   if (TARGET_64BIT)
3650     {
3651       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3652       DONE;
3653     }
3654 })
3655
3656 (define_insn "*extendsidi2_1"
3657   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3658         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3659    (clobber (reg:CC FLAGS_REG))
3660    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3661   "!TARGET_64BIT"
3662   "#")
3663
3664 (define_insn "extendsidi2_rex64"
3665   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3667   "TARGET_64BIT"
3668   "@
3669    {cltq|cdqe}
3670    movs{lq|x}\t{%1,%0|%0, %1}"
3671   [(set_attr "type" "imovx")
3672    (set_attr "mode" "DI")
3673    (set_attr "prefix_0f" "0")
3674    (set_attr "modrm" "0,1")])
3675
3676 (define_insn "extendhidi2"
3677   [(set (match_operand:DI 0 "register_operand" "=r")
3678         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3679   "TARGET_64BIT"
3680   "movs{wq|x}\t{%1,%0|%0, %1}"
3681   [(set_attr "type" "imovx")
3682    (set_attr "mode" "DI")])
3683
3684 (define_insn "extendqidi2"
3685   [(set (match_operand:DI 0 "register_operand" "=r")
3686         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3687   "TARGET_64BIT"
3688   "movs{bq|x}\t{%1,%0|%0, %1}"
3689    [(set_attr "type" "imovx")
3690     (set_attr "mode" "DI")])
3691
3692 ;; Extend to memory case when source register does die.
3693 (define_split
3694   [(set (match_operand:DI 0 "memory_operand" "")
3695         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3696    (clobber (reg:CC FLAGS_REG))
3697    (clobber (match_operand:SI 2 "register_operand" ""))]
3698   "(reload_completed
3699     && dead_or_set_p (insn, operands[1])
3700     && !reg_mentioned_p (operands[1], operands[0]))"
3701   [(set (match_dup 3) (match_dup 1))
3702    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3703               (clobber (reg:CC FLAGS_REG))])
3704    (set (match_dup 4) (match_dup 1))]
3705   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3706
3707 ;; Extend to memory case when source register does not die.
3708 (define_split
3709   [(set (match_operand:DI 0 "memory_operand" "")
3710         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711    (clobber (reg:CC FLAGS_REG))
3712    (clobber (match_operand:SI 2 "register_operand" ""))]
3713   "reload_completed"
3714   [(const_int 0)]
3715 {
3716   split_di (&operands[0], 1, &operands[3], &operands[4]);
3717
3718   emit_move_insn (operands[3], operands[1]);
3719
3720   /* Generate a cltd if possible and doing so it profitable.  */
3721   if ((optimize_size || TARGET_USE_CLTD)
3722       && true_regnum (operands[1]) == AX_REG
3723       && true_regnum (operands[2]) == DX_REG)
3724     {
3725       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3726     }
3727   else
3728     {
3729       emit_move_insn (operands[2], operands[1]);
3730       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3731     }
3732   emit_move_insn (operands[4], operands[2]);
3733   DONE;
3734 })
3735
3736 ;; Extend to register case.  Optimize case where source and destination
3737 ;; registers match and cases where we can use cltd.
3738 (define_split
3739   [(set (match_operand:DI 0 "register_operand" "")
3740         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741    (clobber (reg:CC FLAGS_REG))
3742    (clobber (match_scratch:SI 2 ""))]
3743   "reload_completed"
3744   [(const_int 0)]
3745 {
3746   split_di (&operands[0], 1, &operands[3], &operands[4]);
3747
3748   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3749     emit_move_insn (operands[3], operands[1]);
3750
3751   /* Generate a cltd if possible and doing so it profitable.  */
3752   if ((optimize_size || TARGET_USE_CLTD)
3753       && true_regnum (operands[3]) == AX_REG)
3754     {
3755       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3756       DONE;
3757     }
3758
3759   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3760     emit_move_insn (operands[4], operands[1]);
3761
3762   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3763   DONE;
3764 })
3765
3766 (define_insn "extendhisi2"
3767   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3768         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3769   ""
3770 {
3771   switch (get_attr_prefix_0f (insn))
3772     {
3773     case 0:
3774       return "{cwtl|cwde}";
3775     default:
3776       return "movs{wl|x}\t{%1,%0|%0, %1}";
3777     }
3778 }
3779   [(set_attr "type" "imovx")
3780    (set_attr "mode" "SI")
3781    (set (attr "prefix_0f")
3782      ;; movsx is short decodable while cwtl is vector decoded.
3783      (if_then_else (and (eq_attr "cpu" "!k6")
3784                         (eq_attr "alternative" "0"))
3785         (const_string "0")
3786         (const_string "1")))
3787    (set (attr "modrm")
3788      (if_then_else (eq_attr "prefix_0f" "0")
3789         (const_string "0")
3790         (const_string "1")))])
3791
3792 (define_insn "*extendhisi2_zext"
3793   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3794         (zero_extend:DI
3795           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3796   "TARGET_64BIT"
3797 {
3798   switch (get_attr_prefix_0f (insn))
3799     {
3800     case 0:
3801       return "{cwtl|cwde}";
3802     default:
3803       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3804     }
3805 }
3806   [(set_attr "type" "imovx")
3807    (set_attr "mode" "SI")
3808    (set (attr "prefix_0f")
3809      ;; movsx is short decodable while cwtl is vector decoded.
3810      (if_then_else (and (eq_attr "cpu" "!k6")
3811                         (eq_attr "alternative" "0"))
3812         (const_string "0")
3813         (const_string "1")))
3814    (set (attr "modrm")
3815      (if_then_else (eq_attr "prefix_0f" "0")
3816         (const_string "0")
3817         (const_string "1")))])
3818
3819 (define_insn "extendqihi2"
3820   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3821         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3822   ""
3823 {
3824   switch (get_attr_prefix_0f (insn))
3825     {
3826     case 0:
3827       return "{cbtw|cbw}";
3828     default:
3829       return "movs{bw|x}\t{%1,%0|%0, %1}";
3830     }
3831 }
3832   [(set_attr "type" "imovx")
3833    (set_attr "mode" "HI")
3834    (set (attr "prefix_0f")
3835      ;; movsx is short decodable while cwtl is vector decoded.
3836      (if_then_else (and (eq_attr "cpu" "!k6")
3837                         (eq_attr "alternative" "0"))
3838         (const_string "0")
3839         (const_string "1")))
3840    (set (attr "modrm")
3841      (if_then_else (eq_attr "prefix_0f" "0")
3842         (const_string "0")
3843         (const_string "1")))])
3844
3845 (define_insn "extendqisi2"
3846   [(set (match_operand:SI 0 "register_operand" "=r")
3847         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3848   ""
3849   "movs{bl|x}\t{%1,%0|%0, %1}"
3850    [(set_attr "type" "imovx")
3851     (set_attr "mode" "SI")])
3852
3853 (define_insn "*extendqisi2_zext"
3854   [(set (match_operand:DI 0 "register_operand" "=r")
3855         (zero_extend:DI
3856           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3857   "TARGET_64BIT"
3858   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3859    [(set_attr "type" "imovx")
3860     (set_attr "mode" "SI")])
3861 \f
3862 ;; Conversions between float and double.
3863
3864 ;; These are all no-ops in the model used for the 80387.  So just
3865 ;; emit moves.
3866
3867 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3868 (define_insn "*dummy_extendsfdf2"
3869   [(set (match_operand:DF 0 "push_operand" "=<")
3870         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3871   "0"
3872   "#")
3873
3874 (define_split
3875   [(set (match_operand:DF 0 "push_operand" "")
3876         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3877   "!TARGET_64BIT"
3878   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3879    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3880
3881 (define_split
3882   [(set (match_operand:DF 0 "push_operand" "")
3883         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3884   "TARGET_64BIT"
3885   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3886    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3887
3888 (define_insn "*dummy_extendsfxf2"
3889   [(set (match_operand:XF 0 "push_operand" "=<")
3890         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3891   "0"
3892   "#")
3893
3894 (define_split
3895   [(set (match_operand:XF 0 "push_operand" "")
3896         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3897   ""
3898   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3899    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3900   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3901
3902 (define_split
3903   [(set (match_operand:XF 0 "push_operand" "")
3904         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3905   "TARGET_64BIT"
3906   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3907    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3908   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3909
3910 (define_split
3911   [(set (match_operand:XF 0 "push_operand" "")
3912         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3913   ""
3914   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3915    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3916   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3917
3918 (define_split
3919   [(set (match_operand:XF 0 "push_operand" "")
3920         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3921   "TARGET_64BIT"
3922   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3923    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3924   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3925
3926 (define_expand "extendsfdf2"
3927   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3928         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3929   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3930 {
3931   /* ??? Needed for compress_float_constant since all fp constants
3932      are LEGITIMATE_CONSTANT_P.  */
3933   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3934     {
3935       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3936           && standard_80387_constant_p (operands[1]) > 0)
3937         {
3938           operands[1] = simplify_const_unary_operation
3939             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3940           emit_move_insn_1 (operands[0], operands[1]);
3941           DONE;
3942         }
3943       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3944     }
3945 })
3946
3947 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3948    cvtss2sd:
3949       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3950       cvtps2pd xmm2,xmm1
3951    We do the conversion post reload to avoid producing of 128bit spills
3952    that might lead to ICE on 32bit target.  The sequence unlikely combine
3953    anyway.  */
3954 (define_split
3955   [(set (match_operand:DF 0 "register_operand" "")
3956         (float_extend:DF
3957           (match_operand:SF 1 "nonimmediate_operand" "")))]
3958   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3959    && reload_completed && SSE_REG_P (operands[0])"
3960    [(set (match_dup 2)
3961          (float_extend:V2DF
3962            (vec_select:V2SF
3963              (match_dup 3)
3964              (parallel [(const_int 0) (const_int 1)]))))]
3965 {
3966   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3967   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3968   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3969      Try to avoid move when unpacking can be done in source.  */
3970   if (REG_P (operands[1]))
3971     {
3972       /* If it is unsafe to overwrite upper half of source, we need
3973          to move to destination and unpack there.  */
3974       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3975            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3976           && true_regnum (operands[0]) != true_regnum (operands[1]))
3977         {
3978           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3979           emit_move_insn (tmp, operands[1]);
3980         }
3981       else
3982         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3983       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3984     }
3985   else
3986     emit_insn (gen_vec_setv4sf_0 (operands[3],
3987                                   CONST0_RTX (V4SFmode), operands[1]));
3988 })
3989
3990 (define_insn "*extendsfdf2_mixed"
3991   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3992         (float_extend:DF
3993           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3994   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3995 {
3996   switch (which_alternative)
3997     {
3998     case 0:
3999     case 1:
4000       return output_387_reg_move (insn, operands);
4001
4002     case 2:
4003       return "cvtss2sd\t{%1, %0|%0, %1}";
4004
4005     default:
4006       gcc_unreachable ();
4007     }
4008 }
4009   [(set_attr "type" "fmov,fmov,ssecvt")
4010    (set_attr "mode" "SF,XF,DF")])
4011
4012 (define_insn "*extendsfdf2_sse"
4013   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4014         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4015   "TARGET_SSE2 && TARGET_SSE_MATH"
4016   "cvtss2sd\t{%1, %0|%0, %1}"
4017   [(set_attr "type" "ssecvt")
4018    (set_attr "mode" "DF")])
4019
4020 (define_insn "*extendsfdf2_i387"
4021   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4022         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4023   "TARGET_80387"
4024   "* return output_387_reg_move (insn, operands);"
4025   [(set_attr "type" "fmov")
4026    (set_attr "mode" "SF,XF")])
4027
4028 (define_expand "extend<mode>xf2"
4029   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4030         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4031   "TARGET_80387"
4032 {
4033   /* ??? Needed for compress_float_constant since all fp constants
4034      are LEGITIMATE_CONSTANT_P.  */
4035   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4036     {
4037       if (standard_80387_constant_p (operands[1]) > 0)
4038         {
4039           operands[1] = simplify_const_unary_operation
4040             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4041           emit_move_insn_1 (operands[0], operands[1]);
4042           DONE;
4043         }
4044       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4045     }
4046 })
4047
4048 (define_insn "*extend<mode>xf2_i387"
4049   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4050         (float_extend:XF
4051           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4052   "TARGET_80387"
4053   "* return output_387_reg_move (insn, operands);"
4054   [(set_attr "type" "fmov")
4055    (set_attr "mode" "<MODE>,XF")])
4056
4057 ;; %%% This seems bad bad news.
4058 ;; This cannot output into an f-reg because there is no way to be sure
4059 ;; of truncating in that case.  Otherwise this is just like a simple move
4060 ;; insn.  So we pretend we can output to a reg in order to get better
4061 ;; register preferencing, but we really use a stack slot.
4062
4063 ;; Conversion from DFmode to SFmode.
4064
4065 (define_expand "truncdfsf2"
4066   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4067         (float_truncate:SF
4068           (match_operand:DF 1 "nonimmediate_operand" "")))]
4069   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4070 {
4071   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4072     ;
4073   else if (flag_unsafe_math_optimizations)
4074     ;
4075   else
4076     {
4077       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4078       rtx temp = assign_386_stack_local (SFmode, slot);
4079       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4080       DONE;
4081     }
4082 })
4083
4084 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4085    cvtsd2ss:
4086       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4087       cvtpd2ps xmm2,xmm1
4088    We do the conversion post reload to avoid producing of 128bit spills
4089    that might lead to ICE on 32bit target.  The sequence unlikely combine
4090    anyway.  */
4091 (define_split
4092   [(set (match_operand:SF 0 "register_operand" "")
4093         (float_truncate:SF
4094           (match_operand:DF 1 "nonimmediate_operand" "")))]
4095   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4096    && reload_completed && SSE_REG_P (operands[0])"
4097    [(set (match_dup 2)
4098          (vec_concat:V4SF
4099            (float_truncate:V2SF
4100              (match_dup 4))
4101            (match_dup 3)))]
4102 {
4103   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4104   operands[3] = CONST0_RTX (V2SFmode);
4105   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4106   /* Use movsd for loading from memory, unpcklpd for registers.
4107      Try to avoid move when unpacking can be done in source, or SSE3
4108      movddup is available.  */
4109   if (REG_P (operands[1]))
4110     {
4111       if (!TARGET_SSE3
4112           && true_regnum (operands[0]) != true_regnum (operands[1])
4113           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4114               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4115         {
4116           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4117           emit_move_insn (tmp, operands[1]);
4118           operands[1] = tmp;
4119         }
4120       else if (!TARGET_SSE3)
4121         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4122       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4123     }
4124   else
4125     emit_insn (gen_sse2_loadlpd (operands[4],
4126                                  CONST0_RTX (V2DFmode), operands[1]));
4127 })
4128
4129 (define_expand "truncdfsf2_with_temp"
4130   [(parallel [(set (match_operand:SF 0 "" "")
4131                    (float_truncate:SF (match_operand:DF 1 "" "")))
4132               (clobber (match_operand:SF 2 "" ""))])]
4133   "")
4134
4135 (define_insn "*truncdfsf_fast_mixed"
4136   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4137         (float_truncate:SF
4138           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4139   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4140 {
4141   switch (which_alternative)
4142     {
4143     case 0:
4144     case 1:
4145       return output_387_reg_move (insn, operands);
4146     case 2:
4147       return "cvtsd2ss\t{%1, %0|%0, %1}";
4148     default:
4149       gcc_unreachable ();
4150     }
4151 }
4152   [(set_attr "type" "fmov,fmov,ssecvt")
4153    (set_attr "mode" "SF")])
4154
4155 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4156 ;; because nothing we do here is unsafe.
4157 (define_insn "*truncdfsf_fast_sse"
4158   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4159         (float_truncate:SF
4160           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4161   "TARGET_SSE2 && TARGET_SSE_MATH"
4162   "cvtsd2ss\t{%1, %0|%0, %1}"
4163   [(set_attr "type" "ssecvt")
4164    (set_attr "mode" "SF")])
4165
4166 (define_insn "*truncdfsf_fast_i387"
4167   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4168         (float_truncate:SF
4169           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170   "TARGET_80387 && flag_unsafe_math_optimizations"
4171   "* return output_387_reg_move (insn, operands);"
4172   [(set_attr "type" "fmov")
4173    (set_attr "mode" "SF")])
4174
4175 (define_insn "*truncdfsf_mixed"
4176   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4177         (float_truncate:SF
4178           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4179    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4180   "TARGET_MIX_SSE_I387"
4181 {
4182   switch (which_alternative)
4183     {
4184     case 0:
4185       return output_387_reg_move (insn, operands);
4186
4187     case 1:
4188       return "#";
4189     case 2:
4190       return "cvtsd2ss\t{%1, %0|%0, %1}";
4191     default:
4192       gcc_unreachable ();
4193     }
4194 }
4195   [(set_attr "type" "fmov,multi,ssecvt")
4196    (set_attr "unit" "*,i387,*")
4197    (set_attr "mode" "SF")])
4198
4199 (define_insn "*truncdfsf_i387"
4200   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4201         (float_truncate:SF
4202           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4203    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4204   "TARGET_80387"
4205 {
4206   switch (which_alternative)
4207     {
4208     case 0:
4209       return output_387_reg_move (insn, operands);
4210
4211     case 1:
4212       return "#";
4213     default:
4214       gcc_unreachable ();
4215     }
4216 }
4217   [(set_attr "type" "fmov,multi")
4218    (set_attr "unit" "*,i387")
4219    (set_attr "mode" "SF")])
4220
4221 (define_insn "*truncdfsf2_i387_1"
4222   [(set (match_operand:SF 0 "memory_operand" "=m")
4223         (float_truncate:SF
4224           (match_operand:DF 1 "register_operand" "f")))]
4225   "TARGET_80387
4226    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4227    && !TARGET_MIX_SSE_I387"
4228   "* return output_387_reg_move (insn, operands);"
4229   [(set_attr "type" "fmov")
4230    (set_attr "mode" "SF")])
4231
4232 (define_split
4233   [(set (match_operand:SF 0 "register_operand" "")
4234         (float_truncate:SF
4235          (match_operand:DF 1 "fp_register_operand" "")))
4236    (clobber (match_operand 2 "" ""))]
4237   "reload_completed"
4238   [(set (match_dup 2) (match_dup 1))
4239    (set (match_dup 0) (match_dup 2))]
4240 {
4241   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4242 })
4243
4244 ;; Conversion from XFmode to {SF,DF}mode
4245
4246 (define_expand "truncxf<mode>2"
4247   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4248                    (float_truncate:MODEF
4249                      (match_operand:XF 1 "register_operand" "")))
4250               (clobber (match_dup 2))])]
4251   "TARGET_80387"
4252 {
4253   if (flag_unsafe_math_optimizations)
4254     {
4255       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4256       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4257       if (reg != operands[0])
4258         emit_move_insn (operands[0], reg);
4259       DONE;
4260     }
4261   else
4262     {
4263       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4264       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4265     }
4266 })
4267
4268 (define_insn "*truncxfsf2_mixed"
4269   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4270         (float_truncate:SF
4271           (match_operand:XF 1 "register_operand" "f,f")))
4272    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4273   "TARGET_80387"
4274 {
4275   gcc_assert (!which_alternative);
4276   return output_387_reg_move (insn, operands);
4277 }
4278   [(set_attr "type" "fmov,multi")
4279    (set_attr "unit" "*,i387")
4280    (set_attr "mode" "SF")])
4281
4282 (define_insn "*truncxfdf2_mixed"
4283   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4284         (float_truncate:DF
4285           (match_operand:XF 1 "register_operand" "f,f")))
4286    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4287   "TARGET_80387"
4288 {
4289   gcc_assert (!which_alternative);
4290   return output_387_reg_move (insn, operands);
4291 }
4292   [(set_attr "type" "fmov,multi")
4293    (set_attr "unit" "*,i387")
4294    (set_attr "mode" "DF")])
4295
4296 (define_insn "truncxf<mode>2_i387_noop"
4297   [(set (match_operand:MODEF 0 "register_operand" "=f")
4298         (float_truncate:MODEF
4299           (match_operand:XF 1 "register_operand" "f")))]
4300   "TARGET_80387 && flag_unsafe_math_optimizations"
4301   "* return output_387_reg_move (insn, operands);"
4302   [(set_attr "type" "fmov")
4303    (set_attr "mode" "<MODE>")])
4304
4305 (define_insn "*truncxf<mode>2_i387"
4306   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4307         (float_truncate:MODEF
4308           (match_operand:XF 1 "register_operand" "f")))]
4309   "TARGET_80387"
4310   "* return output_387_reg_move (insn, operands);"
4311   [(set_attr "type" "fmov")
4312    (set_attr "mode" "<MODE>")])
4313
4314 (define_split
4315   [(set (match_operand:MODEF 0 "register_operand" "")
4316         (float_truncate:MODEF
4317           (match_operand:XF 1 "register_operand" "")))
4318    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4319   "TARGET_80387 && reload_completed"
4320   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4321    (set (match_dup 0) (match_dup 2))]
4322   "")
4323
4324 (define_split
4325   [(set (match_operand:MODEF 0 "memory_operand" "")
4326         (float_truncate:MODEF
4327           (match_operand:XF 1 "register_operand" "")))
4328    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4329   "TARGET_80387"
4330   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4331   "")
4332 \f
4333 ;; Signed conversion to DImode.
4334
4335 (define_expand "fix_truncxfdi2"
4336   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4337                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4338               (clobber (reg:CC FLAGS_REG))])]
4339   "TARGET_80387"
4340 {
4341   if (TARGET_FISTTP)
4342    {
4343      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4344      DONE;
4345    }
4346 })
4347
4348 (define_expand "fix_trunc<mode>di2"
4349   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4350                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4351               (clobber (reg:CC FLAGS_REG))])]
4352   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4353 {
4354   if (TARGET_FISTTP
4355       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4356    {
4357      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4358      DONE;
4359    }
4360   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4361    {
4362      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4363      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4364      if (out != operands[0])
4365         emit_move_insn (operands[0], out);
4366      DONE;
4367    }
4368 })
4369
4370 ;; Signed conversion to SImode.
4371
4372 (define_expand "fix_truncxfsi2"
4373   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4374                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4375               (clobber (reg:CC FLAGS_REG))])]
4376   "TARGET_80387"
4377 {
4378   if (TARGET_FISTTP)
4379    {
4380      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4381      DONE;
4382    }
4383 })
4384
4385 (define_expand "fix_trunc<mode>si2"
4386   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4387                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4388               (clobber (reg:CC FLAGS_REG))])]
4389   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4390 {
4391   if (TARGET_FISTTP
4392       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4393    {
4394      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4395      DONE;
4396    }
4397   if (SSE_FLOAT_MODE_P (<MODE>mode))
4398    {
4399      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4400      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4401      if (out != operands[0])
4402         emit_move_insn (operands[0], out);
4403      DONE;
4404    }
4405 })
4406
4407 ;; Signed conversion to HImode.
4408
4409 (define_expand "fix_trunc<mode>hi2"
4410   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4411                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4412               (clobber (reg:CC FLAGS_REG))])]
4413   "TARGET_80387
4414    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4415 {
4416   if (TARGET_FISTTP)
4417    {
4418      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4419      DONE;
4420    }
4421 })
4422
4423 ;; Unsigned conversion to SImode.
4424
4425 (define_expand "fixuns_trunc<mode>si2"
4426   [(parallel
4427     [(set (match_operand:SI 0 "register_operand" "")
4428           (unsigned_fix:SI
4429             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4430      (use (match_dup 2))
4431      (clobber (match_scratch:<ssevecmode> 3 ""))
4432      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4433   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4434 {
4435   enum machine_mode mode = <MODE>mode;
4436   enum machine_mode vecmode = <ssevecmode>mode;
4437   REAL_VALUE_TYPE TWO31r;
4438   rtx two31;
4439
4440   real_ldexp (&TWO31r, &dconst1, 31);
4441   two31 = const_double_from_real_value (TWO31r, mode);
4442   two31 = ix86_build_const_vector (mode, true, two31);
4443   operands[2] = force_reg (vecmode, two31);
4444 })
4445
4446 (define_insn_and_split "*fixuns_trunc<mode>_1"
4447   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4448         (unsigned_fix:SI
4449           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4450    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4451    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4452    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4453   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4454   "#"
4455   "&& reload_completed"
4456   [(const_int 0)]
4457 {
4458   ix86_split_convert_uns_si_sse (operands);
4459   DONE;
4460 })
4461
4462 ;; Unsigned conversion to HImode.
4463 ;; Without these patterns, we'll try the unsigned SI conversion which
4464 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4465
4466 (define_expand "fixuns_trunc<mode>hi2"
4467   [(set (match_dup 2)
4468         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4469    (set (match_operand:HI 0 "nonimmediate_operand" "")
4470         (subreg:HI (match_dup 2) 0))]
4471   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4472   "operands[2] = gen_reg_rtx (SImode);")
4473
4474 ;; When SSE is available, it is always faster to use it!
4475 (define_insn "fix_trunc<mode>di_sse"
4476   [(set (match_operand:DI 0 "register_operand" "=r,r")
4477         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4478   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4479    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4480   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4481   [(set_attr "type" "sseicvt")
4482    (set_attr "mode" "<MODE>")
4483    (set_attr "athlon_decode" "double,vector")
4484    (set_attr "amdfam10_decode" "double,double")])
4485
4486 (define_insn "fix_trunc<mode>si_sse"
4487   [(set (match_operand:SI 0 "register_operand" "=r,r")
4488         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4489   "SSE_FLOAT_MODE_P (<MODE>mode)
4490    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4491   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4492   [(set_attr "type" "sseicvt")
4493    (set_attr "mode" "<MODE>")
4494    (set_attr "athlon_decode" "double,vector")
4495    (set_attr "amdfam10_decode" "double,double")])
4496
4497 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4498 (define_peephole2
4499   [(set (match_operand:MODEF 0 "register_operand" "")
4500         (match_operand:MODEF 1 "memory_operand" ""))
4501    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4502         (fix:SSEMODEI24 (match_dup 0)))]
4503   "TARGET_SHORTEN_X87_SSE
4504    && peep2_reg_dead_p (2, operands[0])"
4505   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4506   "")
4507
4508 ;; Avoid vector decoded forms of the instruction.
4509 (define_peephole2
4510   [(match_scratch:DF 2 "Y2")
4511    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4512         (fix:SSEMODEI24 (match_operand:DF 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_peephole2
4519   [(match_scratch:SF 2 "x")
4520    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4521         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4522   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4523   [(set (match_dup 2) (match_dup 1))
4524    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4525   "")
4526
4527 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4528   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4529         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4530   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531    && TARGET_FISTTP
4532    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533          && (TARGET_64BIT || <MODE>mode != DImode))
4534         && TARGET_SSE_MATH)
4535    && !(reload_completed || reload_in_progress)"
4536   "#"
4537   "&& 1"
4538   [(const_int 0)]
4539 {
4540   if (memory_operand (operands[0], VOIDmode))
4541     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4542   else
4543     {
4544       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4545       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4546                                                             operands[1],
4547                                                             operands[2]));
4548     }
4549   DONE;
4550 }
4551   [(set_attr "type" "fisttp")
4552    (set_attr "mode" "<MODE>")])
4553
4554 (define_insn "fix_trunc<mode>_i387_fisttp"
4555   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4556         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4557    (clobber (match_scratch:XF 2 "=&1f"))]
4558   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4559    && TARGET_FISTTP
4560    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561          && (TARGET_64BIT || <MODE>mode != DImode))
4562         && TARGET_SSE_MATH)"
4563   "* return output_fix_trunc (insn, operands, 1);"
4564   [(set_attr "type" "fisttp")
4565    (set_attr "mode" "<MODE>")])
4566
4567 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4568   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4569         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4570    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4571    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4572   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4573    && TARGET_FISTTP
4574    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575         && (TARGET_64BIT || <MODE>mode != DImode))
4576         && TARGET_SSE_MATH)"
4577   "#"
4578   [(set_attr "type" "fisttp")
4579    (set_attr "mode" "<MODE>")])
4580
4581 (define_split
4582   [(set (match_operand:X87MODEI 0 "register_operand" "")
4583         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4584    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4585    (clobber (match_scratch 3 ""))]
4586   "reload_completed"
4587   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4588               (clobber (match_dup 3))])
4589    (set (match_dup 0) (match_dup 2))]
4590   "")
4591
4592 (define_split
4593   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4594         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4595    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4596    (clobber (match_scratch 3 ""))]
4597   "reload_completed"
4598   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4599               (clobber (match_dup 3))])]
4600   "")
4601
4602 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4603 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4604 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4605 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4606 ;; function in i386.c.
4607 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4608   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4609         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4610    (clobber (reg:CC FLAGS_REG))]
4611   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612    && !TARGET_FISTTP
4613    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614          && (TARGET_64BIT || <MODE>mode != DImode))
4615    && !(reload_completed || reload_in_progress)"
4616   "#"
4617   "&& 1"
4618   [(const_int 0)]
4619 {
4620   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4621
4622   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4623   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4624   if (memory_operand (operands[0], VOIDmode))
4625     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4626                                          operands[2], operands[3]));
4627   else
4628     {
4629       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4630       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4631                                                      operands[2], operands[3],
4632                                                      operands[4]));
4633     }
4634   DONE;
4635 }
4636   [(set_attr "type" "fistp")
4637    (set_attr "i387_cw" "trunc")
4638    (set_attr "mode" "<MODE>")])
4639
4640 (define_insn "fix_truncdi_i387"
4641   [(set (match_operand:DI 0 "memory_operand" "=m")
4642         (fix:DI (match_operand 1 "register_operand" "f")))
4643    (use (match_operand:HI 2 "memory_operand" "m"))
4644    (use (match_operand:HI 3 "memory_operand" "m"))
4645    (clobber (match_scratch:XF 4 "=&1f"))]
4646   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4647    && !TARGET_FISTTP
4648    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4649   "* return output_fix_trunc (insn, operands, 0);"
4650   [(set_attr "type" "fistp")
4651    (set_attr "i387_cw" "trunc")
4652    (set_attr "mode" "DI")])
4653
4654 (define_insn "fix_truncdi_i387_with_temp"
4655   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4656         (fix:DI (match_operand 1 "register_operand" "f,f")))
4657    (use (match_operand:HI 2 "memory_operand" "m,m"))
4658    (use (match_operand:HI 3 "memory_operand" "m,m"))
4659    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4660    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4661   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4662    && !TARGET_FISTTP
4663    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4664   "#"
4665   [(set_attr "type" "fistp")
4666    (set_attr "i387_cw" "trunc")
4667    (set_attr "mode" "DI")])
4668
4669 (define_split
4670   [(set (match_operand:DI 0 "register_operand" "")
4671         (fix:DI (match_operand 1 "register_operand" "")))
4672    (use (match_operand:HI 2 "memory_operand" ""))
4673    (use (match_operand:HI 3 "memory_operand" ""))
4674    (clobber (match_operand:DI 4 "memory_operand" ""))
4675    (clobber (match_scratch 5 ""))]
4676   "reload_completed"
4677   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4678               (use (match_dup 2))
4679               (use (match_dup 3))
4680               (clobber (match_dup 5))])
4681    (set (match_dup 0) (match_dup 4))]
4682   "")
4683
4684 (define_split
4685   [(set (match_operand:DI 0 "memory_operand" "")
4686         (fix:DI (match_operand 1 "register_operand" "")))
4687    (use (match_operand:HI 2 "memory_operand" ""))
4688    (use (match_operand:HI 3 "memory_operand" ""))
4689    (clobber (match_operand:DI 4 "memory_operand" ""))
4690    (clobber (match_scratch 5 ""))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))
4695               (clobber (match_dup 5))])]
4696   "")
4697
4698 (define_insn "fix_trunc<mode>_i387"
4699   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4700         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4701    (use (match_operand:HI 2 "memory_operand" "m"))
4702    (use (match_operand:HI 3 "memory_operand" "m"))]
4703   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704    && !TARGET_FISTTP
4705    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4706   "* return output_fix_trunc (insn, operands, 0);"
4707   [(set_attr "type" "fistp")
4708    (set_attr "i387_cw" "trunc")
4709    (set_attr "mode" "<MODE>")])
4710
4711 (define_insn "fix_trunc<mode>_i387_with_temp"
4712   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4713         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4714    (use (match_operand:HI 2 "memory_operand" "m,m"))
4715    (use (match_operand:HI 3 "memory_operand" "m,m"))
4716    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4717   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718    && !TARGET_FISTTP
4719    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4720   "#"
4721   [(set_attr "type" "fistp")
4722    (set_attr "i387_cw" "trunc")
4723    (set_attr "mode" "<MODE>")])
4724
4725 (define_split
4726   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4727         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4728    (use (match_operand:HI 2 "memory_operand" ""))
4729    (use (match_operand:HI 3 "memory_operand" ""))
4730    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4731   "reload_completed"
4732   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4733               (use (match_dup 2))
4734               (use (match_dup 3))])
4735    (set (match_dup 0) (match_dup 4))]
4736   "")
4737
4738 (define_split
4739   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4740         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4741    (use (match_operand:HI 2 "memory_operand" ""))
4742    (use (match_operand:HI 3 "memory_operand" ""))
4743    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4744   "reload_completed"
4745   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4746               (use (match_dup 2))
4747               (use (match_dup 3))])]
4748   "")
4749
4750 (define_insn "x86_fnstcw_1"
4751   [(set (match_operand:HI 0 "memory_operand" "=m")
4752         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4753   "TARGET_80387"
4754   "fnstcw\t%0"
4755   [(set_attr "length" "2")
4756    (set_attr "mode" "HI")
4757    (set_attr "unit" "i387")])
4758
4759 (define_insn "x86_fldcw_1"
4760   [(set (reg:HI FPCR_REG)
4761         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4762   "TARGET_80387"
4763   "fldcw\t%0"
4764   [(set_attr "length" "2")
4765    (set_attr "mode" "HI")
4766    (set_attr "unit" "i387")
4767    (set_attr "athlon_decode" "vector")
4768    (set_attr "amdfam10_decode" "vector")])
4769 \f
4770 ;; Conversion between fixed point and floating point.
4771
4772 ;; Even though we only accept memory inputs, the backend _really_
4773 ;; wants to be able to do this between registers.
4774
4775 (define_expand "floathi<mode>2"
4776   [(set (match_operand:MODEF 0 "register_operand" "")
4777         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4778   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4779 {
4780   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4781     {
4782       emit_insn
4783         (gen_floatsi<mode>2 (operands[0],
4784                              convert_to_mode (SImode, operands[1], 0)));
4785       DONE;
4786     }
4787 })
4788
4789 (define_insn "*floathi<mode>2_i387"
4790   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4791         (float:MODEF
4792           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4793   "TARGET_80387
4794    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4795        || TARGET_MIX_SSE_I387)"
4796   "@
4797    fild%z1\t%1
4798    #"
4799   [(set_attr "type" "fmov,multi")
4800    (set_attr "mode" "<MODE>")
4801    (set_attr "unit" "*,i387")
4802    (set_attr "fp_int_src" "true")])
4803
4804 (define_expand "floatsi<mode>2"
4805   [(set (match_operand:MODEF 0 "register_operand" "")
4806         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4807   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4808   "
4809    /* When we use vector converts, we can't have input in memory.  */
4810    if (GET_MODE (operands[0]) == DFmode
4811        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4812        && SSE_FLOAT_MODE_P (DFmode))
4813      operands[1] = force_reg (SImode, operands[1]);
4814    else if (GET_MODE (operands[0]) == SFmode
4815             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4816             && SSE_FLOAT_MODE_P (SFmode))
4817      {
4818        /* When !flag_trapping_math, we handle SImode->SFmode vector
4819           conversions same way as SImode->DFmode.
4820
4821           For flat_trapping_math we can't safely use vector conversion without
4822           clearing upper half, otherwise precision exception might occur.
4823           However we can still generate the common sequence converting value
4824           from general register to XMM register as:
4825
4826             mov         reg32, mem32
4827             movd        mem32, xmm
4828             cvtdq2pd xmm,xmm
4829
4830           because we know that movd clears the upper half.
4831
4832           Sadly in this case we can't rely on reload moving the value to XMM
4833           register, since we need to know if upper half is OK, so we need
4834           to do reloading by hand.  We force operand to memory unless target
4835           supports inter unit moves.  */
4836        if (!flag_trapping_math)
4837          operands[1] = force_reg (SImode, operands[1]);
4838        else if (!MEM_P (operands[1]))
4839          {
4840            int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4841            rtx tmp = assign_386_stack_local (SImode, slot);
4842            emit_move_insn (tmp, operands[1]);
4843            operands[1] = tmp;
4844          }
4845      }
4846    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4847       !TARGET_INTER_UNIT_CONVERSIONS
4848       It is necessary for the patterns to not accept nonmemory operands
4849       as we would optimize out later.  */
4850    else if (!TARGET_INTER_UNIT_CONVERSIONS
4851             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4852             && !optimize_size
4853             && !MEM_P (operands[1]))
4854      {
4855        int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4856        rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4857        emit_move_insn (tmp, operands[1]);
4858        operands[1] = tmp;
4859      }
4860   ")
4861
4862 (define_insn "*floatsisf2_mixed_vector"
4863   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4864         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4865   "TARGET_MIX_SSE_I387 && !flag_trapping_math
4866    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4867   "@
4868    cvtdq2ps\t{%1, %0|%0, %1}
4869    fild%z1\t%1
4870    #"
4871   [(set_attr "type" "sseicvt,fmov,multi")
4872    (set_attr "mode" "SF")
4873    (set_attr "unit" "*,i387,*")
4874    (set_attr "athlon_decode" "double,*,*")
4875    (set_attr "amdfam10_decode" "double,*,*")
4876    (set_attr "fp_int_src" "false,true,true")])
4877
4878 (define_insn "*floatsisf2_mixed"
4879   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4880         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4881   "TARGET_MIX_SSE_I387
4882    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4883        || optimize_size)"
4884   "@
4885    fild%z1\t%1
4886    #
4887    cvtsi2ss\t{%1, %0|%0, %1}
4888    cvtsi2ss\t{%1, %0|%0, %1}"
4889   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4890    (set_attr "mode" "SF")
4891    (set_attr "unit" "*,i387,*,*")
4892    (set_attr "athlon_decode" "*,*,vector,double")
4893    (set_attr "amdfam10_decode" "*,*,vector,double")
4894    (set_attr "fp_int_src" "true")])
4895
4896 (define_insn "*floatsisf2_mixed_memory"
4897   [(set (match_operand:SF 0 "register_operand" "=f,x")
4898         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4899   "TARGET_MIX_SSE_I387
4900    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4901   "@
4902    fild%z1\t%1
4903    cvtsi2ss\t{%1, %0|%0, %1}"
4904   [(set_attr "type" "fmov,sseicvt")
4905    (set_attr "mode" "SF")
4906    (set_attr "athlon_decode" "*,double")
4907    (set_attr "amdfam10_decode" "*,double")
4908    (set_attr "fp_int_src" "true")])
4909
4910 (define_insn "*floatsisf2_sse_vector_nointernunit"
4911   [(set (match_operand:SF 0 "register_operand" "=x")
4912         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4913   "TARGET_SSE_MATH && flag_trapping_math
4914    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4915    && !TARGET_INTER_UNIT_MOVES"
4916   "#"
4917   [(set_attr "type" "multi")])
4918
4919 (define_insn "*floatsisf2_sse_vector_internunit"
4920   [(set (match_operand:SF 0 "register_operand" "=x,x")
4921         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4922   "TARGET_SSE_MATH && flag_trapping_math
4923    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4924    && TARGET_INTER_UNIT_MOVES"
4925   "#"
4926   [(set_attr "type" "multi")])
4927
4928 (define_split
4929   [(set (match_operand:SF 0 "register_operand" "")
4930         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4931   "flag_trapping_math
4932    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4933    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4934    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4935   [(set (match_dup 0)
4936         (float:V4SF (match_dup 2)))]
4937 {
4938   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4939   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4940   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4941 })
4942
4943 (define_split
4944   [(set (match_operand:SF 0 "register_operand" "")
4945         (float:SF (match_operand:SI 1 "register_operand" "")))]
4946   "flag_trapping_math
4947    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4948    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4949   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4950    (set (match_dup 0)
4951         (float:V4SF (match_dup 2)))]
4952 {
4953   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4954   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4955 })
4956
4957 (define_insn "*floatsisf2_sse_vector"
4958   [(set (match_operand:SF 0 "register_operand" "=x")
4959         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4960   "TARGET_SSE_MATH && !flag_trapping_math
4961    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4962    && !TARGET_INTER_UNIT_MOVES"
4963   "cvtdq2ps\t{%1, %0|%0, %1}"
4964   [(set_attr "type" "sseicvt")
4965    (set_attr "mode" "SF")
4966    (set_attr "athlon_decode" "double")
4967    (set_attr "amdfam10_decode" "double")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "*floatsisf2_sse"
4971   [(set (match_operand:SF 0 "register_operand" "=x,x")
4972         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4973   "TARGET_SSE_MATH
4974    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4975        || optimize_size)"
4976   "cvtsi2ss\t{%1, %0|%0, %1}"
4977   [(set_attr "type" "sseicvt")
4978    (set_attr "mode" "SF")
4979    (set_attr "athlon_decode" "vector,double")
4980    (set_attr "amdfam10_decode" "vector,double")
4981    (set_attr "fp_int_src" "true")])
4982
4983 (define_insn "*floatsisf2_sse_memory"
4984   [(set (match_operand:SF 0 "register_operand" "=x")
4985         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4986   "TARGET_SSE_MATH
4987    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4988   "cvtsi2ss\t{%1, %0|%0, %1}"
4989   [(set_attr "type" "sseicvt")
4990    (set_attr "mode" "SF")
4991    (set_attr "athlon_decode" "double")
4992    (set_attr "amdfam10_decode" "double")
4993    (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsidf2_mixed_vector"
4996   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4997         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4998   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5000   "@
5001    cvtdq2pd\t{%1, %0|%0, %1}
5002    fild%z1\t%1
5003    #"
5004   [(set_attr "type" "sseicvt,fmov,multi")
5005    (set_attr "mode" "V2DF,DF,DF")
5006    (set_attr "unit" "*,*,i387")
5007    (set_attr "athlon_decode" "double,*,*")
5008    (set_attr "amdfam10_decode" "double,*,*")
5009    (set_attr "fp_int_src" "false,true,true")])
5010
5011 (define_insn "*floatsidf2_mixed"
5012   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5013         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5014   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5015    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5016        || optimize_size)"
5017   "@
5018    fild%z1\t%1
5019    #
5020    cvtsi2sd\t{%1, %0|%0, %1}
5021    cvtsi2sd\t{%1, %0|%0, %1}
5022    cvtdq2pd\t{%1, %0|%0, %1}"
5023   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5024    (set_attr "mode" "DF,DF,DF,DF,V2DF")
5025    (set_attr "unit" "*,i387,*,*,*")
5026    (set_attr "athlon_decode" "*,*,double,direct,double")
5027    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5028    (set_attr "fp_int_src" "true,true,true,true,false")])
5029
5030 (define_insn "*floatsidf2_mixed_memory"
5031   [(set (match_operand:DF 0 "register_operand" "=f,x")
5032         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5033   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5034    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5035   "@
5036    fild%z1\t%1
5037    cvtsi2sd\t{%1, %0|%0, %1}"
5038   [(set_attr "type" "fmov,sseicvt")
5039    (set_attr "mode" "DF")
5040    (set_attr "athlon_decode" "*,direct")
5041    (set_attr "amdfam10_decode" "*,double")
5042    (set_attr "fp_int_src" "true")])
5043
5044 (define_insn "*floatsidf2_sse_vector"
5045   [(set (match_operand:DF 0 "register_operand" "=x")
5046         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5047   "TARGET_SSE2 && TARGET_SSE_MATH
5048    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5049   "cvtdq2pd\t{%1, %0|%0, %1}"
5050   [(set_attr "type" "sseicvt")
5051    (set_attr "mode" "V2DF")
5052    (set_attr "athlon_decode" "double")
5053    (set_attr "amdfam10_decode" "double")
5054    (set_attr "fp_int_src" "true")])
5055
5056 (define_split
5057   [(set (match_operand:DF 0 "register_operand" "")
5058         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5059   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5060    && SSE_REG_P (operands[0])"
5061   [(set (match_dup 0)
5062         (float:V2DF
5063           (vec_select:V2SI
5064             (match_dup 2)
5065             (parallel [(const_int 0) (const_int 1)]))))]
5066 {
5067   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5068   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5069   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5070 })
5071
5072 (define_insn "*floatsidf2_sse"
5073   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5074         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5075   "TARGET_SSE2 && TARGET_SSE_MATH
5076    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5077        || optimize_size)"
5078   "@
5079    cvtsi2sd\t{%1, %0|%0, %1}
5080    cvtsi2sd\t{%1, %0|%0, %1}
5081    cvtdq2pd\t{%1, %0|%0, %1}"
5082   [(set_attr "type" "sseicvt")
5083    (set_attr "mode" "DF,DF,V2DF")
5084    (set_attr "athlon_decode" "double,direct,double")
5085    (set_attr "amdfam10_decode" "vector,double,double")
5086    (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "*floatsidf2_memory"
5089   [(set (match_operand:DF 0 "register_operand" "=x")
5090         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5091   "TARGET_SSE2 && TARGET_SSE_MATH
5092    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5093        || optimize_size)"
5094   "cvtsi2sd\t{%1, %0|%0, %1}"
5095   [(set_attr "type" "sseicvt")
5096    (set_attr "mode" "DF")
5097    (set_attr "athlon_decode" "direct")
5098    (set_attr "amdfam10_decode" "double")
5099    (set_attr "fp_int_src" "true")])
5100
5101 (define_insn "*floatsi<mode>2_i387"
5102   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5103         (float:MODEF
5104           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5105   "TARGET_80387
5106    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5107   "@
5108    fild%z1\t%1
5109    #"
5110   [(set_attr "type" "fmov,multi")
5111    (set_attr "mode" "<MODE>")
5112    (set_attr "unit" "*,i387")
5113    (set_attr "fp_int_src" "true")])
5114
5115 (define_expand "floatdisf2"
5116   [(set (match_operand:SF 0 "register_operand" "")
5117         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5118   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5119 {
5120   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5121       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5122       && !optimize_size
5123       && !MEM_P (operands[1]))
5124     {
5125       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5126       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5127       emit_move_insn (tmp, operands[1]);
5128       operands[1] = tmp;
5129     }
5130 })
5131
5132 (define_insn "*floatdisf2_mixed"
5133   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5134         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5135   "TARGET_64BIT && TARGET_MIX_SSE_I387
5136    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5137   "@
5138    fild%z1\t%1
5139    #
5140    cvtsi2ss{q}\t{%1, %0|%0, %1}
5141    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5142   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5143    (set_attr "mode" "SF")
5144    (set_attr "unit" "*,i387,*,*")
5145    (set_attr "athlon_decode" "*,*,vector,double")
5146    (set_attr "amdfam10_decode" "*,*,vector,double")
5147    (set_attr "fp_int_src" "true")])
5148
5149 (define_insn "*floatdisf2_mixed"
5150   [(set (match_operand:SF 0 "register_operand" "=f,x")
5151         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5152   "TARGET_64BIT && TARGET_MIX_SSE_I387
5153    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5154   "@
5155    fild%z1\t%1
5156    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5157   [(set_attr "type" "fmov,sseicvt")
5158    (set_attr "mode" "SF")
5159    (set_attr "athlon_decode" "*,double")
5160    (set_attr "amdfam10_decode" "*,double")
5161    (set_attr "fp_int_src" "true")])
5162
5163 (define_insn "*floatdisf2_sse"
5164   [(set (match_operand:SF 0 "register_operand" "=x,x")
5165         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,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" "vector,double")
5172    (set_attr "amdfam10_decode" "vector,double")
5173    (set_attr "fp_int_src" "true")])
5174
5175 (define_insn "*floatdisf2_memory"
5176   [(set (match_operand:SF 0 "register_operand" "=x")
5177         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5178   "TARGET_64BIT && TARGET_SSE_MATH
5179    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5180   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5181   [(set_attr "type" "sseicvt")
5182    (set_attr "mode" "SF")
5183    (set_attr "athlon_decode" "double")
5184    (set_attr "amdfam10_decode" "double")
5185    (set_attr "fp_int_src" "true")])
5186
5187 (define_expand "floatdidf2"
5188   [(set (match_operand:DF 0 "register_operand" "")
5189         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5190   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5191 {
5192   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5193     {
5194       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5195       DONE;
5196     }
5197   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5198       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5199       && !optimize_size
5200       && !MEM_P (operands[1]))
5201     {
5202       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5203       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5204       emit_move_insn (tmp, operands[1]);
5205       operands[1] = tmp;
5206     }
5207 })
5208
5209 (define_insn "*floatdidf2_mixed"
5210   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5211         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5212   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5213    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5214   "@
5215    fild%z1\t%1
5216    #
5217    cvtsi2sd{q}\t{%1, %0|%0, %1}
5218    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5219   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5220    (set_attr "mode" "DF")
5221    (set_attr "unit" "*,i387,*,*")
5222    (set_attr "athlon_decode" "*,*,double,direct")
5223    (set_attr "amdfam10_decode" "*,*,vector,double")
5224    (set_attr "fp_int_src" "true")])
5225
5226 (define_insn "*floatdidf2_mixed_memory"
5227   [(set (match_operand:DF 0 "register_operand" "=f,x")
5228         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5229   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5230    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5231   "@
5232    fild%z1\t%1
5233    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5234   [(set_attr "type" "fmov,sseicvt")
5235    (set_attr "mode" "DF")
5236    (set_attr "athlon_decode" "*,direct")
5237    (set_attr "amdfam10_decode" "*,double")
5238    (set_attr "fp_int_src" "true")])
5239
5240 (define_insn "*floatdidf2_sse"
5241   [(set (match_operand:DF 0 "register_operand" "=x,x")
5242         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5243   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5244    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5245   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5246   [(set_attr "type" "sseicvt")
5247    (set_attr "mode" "DF")
5248    (set_attr "athlon_decode" "double,direct")
5249    (set_attr "amdfam10_decode" "vector,double")
5250    (set_attr "fp_int_src" "true")])
5251
5252 (define_insn "*floatdidf2_sse_memory"
5253   [(set (match_operand:DF 0 "register_operand" "=x")
5254         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5255   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5256    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5257   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5258   [(set_attr "type" "sseicvt")
5259    (set_attr "mode" "DF")
5260    (set_attr "athlon_decode" "direct")
5261    (set_attr "amdfam10_decode" "double")
5262    (set_attr "fp_int_src" "true")])
5263
5264 (define_insn "*floatdi<mode>2_i387"
5265   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5266         (float:MODEF
5267           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5268   "TARGET_80387
5269    && (!TARGET_SSE_MATH || !TARGET_64BIT
5270        || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5271   "@
5272    fild%z1\t%1
5273    #"
5274   [(set_attr "type" "fmov,multi")
5275    (set_attr "mode" "<MODE>")
5276    (set_attr "unit" "*,i387")
5277    (set_attr "fp_int_src" "true")])
5278
5279 (define_insn "float<mode>xf2"
5280   [(set (match_operand:XF 0 "register_operand" "=f,f")
5281         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5282   "TARGET_80387"
5283   "@
5284    fild%z1\t%1
5285    #"
5286   [(set_attr "type" "fmov,multi")
5287    (set_attr "mode" "XF")
5288    (set_attr "unit" "*,i387")
5289    (set_attr "fp_int_src" "true")])
5290
5291 ;; %%% Kill these when reload knows how to do it.
5292 (define_split
5293   [(set (match_operand 0 "fp_register_operand" "")
5294         (float (match_operand 1 "register_operand" "")))]
5295   "reload_completed
5296    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5297   [(const_int 0)]
5298 {
5299   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5300   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5301   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5302   ix86_free_from_memory (GET_MODE (operands[1]));
5303   DONE;
5304 })
5305
5306 (define_expand "floatunssisf2"
5307   [(use (match_operand:SF 0 "register_operand" ""))
5308    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5309   "!TARGET_64BIT"
5310 {
5311   if (TARGET_SSE_MATH && TARGET_SSE2)
5312     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5313   else
5314     x86_emit_floatuns (operands);
5315   DONE;
5316 })
5317
5318 (define_expand "floatunssidf2"
5319   [(use (match_operand:DF 0 "register_operand" ""))
5320    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5321   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5322   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5323
5324 (define_expand "floatunsdisf2"
5325   [(use (match_operand:SF 0 "register_operand" ""))
5326    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327   "TARGET_64BIT && TARGET_SSE_MATH"
5328   "x86_emit_floatuns (operands); DONE;")
5329
5330 (define_expand "floatunsdidf2"
5331   [(use (match_operand:DF 0 "register_operand" ""))
5332    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5333   "TARGET_SSE_MATH && TARGET_SSE2
5334    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5335 {
5336   if (TARGET_64BIT)
5337     x86_emit_floatuns (operands);
5338   else
5339     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5340   DONE;
5341 })
5342 \f
5343 ;; Add instructions
5344
5345 ;; %%% splits for addditi3
5346
5347 (define_expand "addti3"
5348   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5349         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5350                  (match_operand:TI 2 "x86_64_general_operand" "")))
5351    (clobber (reg:CC FLAGS_REG))]
5352   "TARGET_64BIT"
5353   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5354
5355 (define_insn "*addti3_1"
5356   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5357         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5358                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5359    (clobber (reg:CC FLAGS_REG))]
5360   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5361   "#")
5362
5363 (define_split
5364   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5365         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5366                  (match_operand:TI 2 "x86_64_general_operand" "")))
5367    (clobber (reg:CC FLAGS_REG))]
5368   "TARGET_64BIT && reload_completed"
5369   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5370                                           UNSPEC_ADD_CARRY))
5371               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5372    (parallel [(set (match_dup 3)
5373                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5374                                      (match_dup 4))
5375                             (match_dup 5)))
5376               (clobber (reg:CC FLAGS_REG))])]
5377   "split_ti (operands+0, 1, operands+0, operands+3);
5378    split_ti (operands+1, 1, operands+1, operands+4);
5379    split_ti (operands+2, 1, operands+2, operands+5);")
5380
5381 ;; %%% splits for addsidi3
5382 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5384 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5385
5386 (define_expand "adddi3"
5387   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5388         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5389                  (match_operand:DI 2 "x86_64_general_operand" "")))
5390    (clobber (reg:CC FLAGS_REG))]
5391   ""
5392   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5393
5394 (define_insn "*adddi3_1"
5395   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5396         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5397                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5398    (clobber (reg:CC FLAGS_REG))]
5399   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5400   "#")
5401
5402 (define_split
5403   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5404         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5405                  (match_operand:DI 2 "general_operand" "")))
5406    (clobber (reg:CC FLAGS_REG))]
5407   "!TARGET_64BIT && reload_completed"
5408   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5409                                           UNSPEC_ADD_CARRY))
5410               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5411    (parallel [(set (match_dup 3)
5412                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5413                                      (match_dup 4))
5414                             (match_dup 5)))
5415               (clobber (reg:CC FLAGS_REG))])]
5416   "split_di (operands+0, 1, operands+0, operands+3);
5417    split_di (operands+1, 1, operands+1, operands+4);
5418    split_di (operands+2, 1, operands+2, operands+5);")
5419
5420 (define_insn "adddi3_carry_rex64"
5421   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5422           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5423                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5424                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5425    (clobber (reg:CC FLAGS_REG))]
5426   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5427   "adc{q}\t{%2, %0|%0, %2}"
5428   [(set_attr "type" "alu")
5429    (set_attr "pent_pair" "pu")
5430    (set_attr "mode" "DI")])
5431
5432 (define_insn "*adddi3_cc_rex64"
5433   [(set (reg:CC FLAGS_REG)
5434         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5435                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5436                    UNSPEC_ADD_CARRY))
5437    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5438         (plus:DI (match_dup 1) (match_dup 2)))]
5439   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5440   "add{q}\t{%2, %0|%0, %2}"
5441   [(set_attr "type" "alu")
5442    (set_attr "mode" "DI")])
5443
5444 (define_insn "*<addsub><mode>3_cc_overflow"
5445   [(set (reg:CCC FLAGS_REG)
5446         (compare:CCC
5447             (plusminus:SWI
5448                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5449                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5450             (match_dup 1)))
5451    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5452         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5453   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5454   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5455   [(set_attr "type" "alu")
5456    (set_attr "mode" "<MODE>")])
5457
5458 (define_insn "*add<mode>3_cconly_overflow"
5459   [(set (reg:CCC FLAGS_REG)
5460         (compare:CCC
5461                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5462                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5463                 (match_dup 1)))
5464    (clobber (match_scratch:SWI 0 "=<r>"))]
5465   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5466   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5467   [(set_attr "type" "alu")
5468    (set_attr "mode" "<MODE>")])
5469
5470 (define_insn "*sub<mode>3_cconly_overflow"
5471   [(set (reg:CCC FLAGS_REG)
5472         (compare:CCC
5473              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5474                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5475              (match_dup 0)))]
5476   ""
5477   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5478   [(set_attr "type" "icmp")
5479    (set_attr "mode" "<MODE>")])
5480
5481 (define_insn "*<addsub>si3_zext_cc_overflow"
5482   [(set (reg:CCC FLAGS_REG)
5483         (compare:CCC
5484             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5485                           (match_operand:SI 2 "general_operand" "g"))
5486             (match_dup 1)))
5487    (set (match_operand:DI 0 "register_operand" "=r")
5488         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5489   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5490   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5491   [(set_attr "type" "alu")
5492    (set_attr "mode" "SI")])
5493
5494 (define_insn "addqi3_carry"
5495   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5496           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5497                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5498                    (match_operand:QI 2 "general_operand" "qi,qm")))
5499    (clobber (reg:CC FLAGS_REG))]
5500   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5501   "adc{b}\t{%2, %0|%0, %2}"
5502   [(set_attr "type" "alu")
5503    (set_attr "pent_pair" "pu")
5504    (set_attr "mode" "QI")])
5505
5506 (define_insn "addhi3_carry"
5507   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5508           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5509                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5510                    (match_operand:HI 2 "general_operand" "ri,rm")))
5511    (clobber (reg:CC FLAGS_REG))]
5512   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5513   "adc{w}\t{%2, %0|%0, %2}"
5514   [(set_attr "type" "alu")
5515    (set_attr "pent_pair" "pu")
5516    (set_attr "mode" "HI")])
5517
5518 (define_insn "addsi3_carry"
5519   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5520           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5521                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5522                    (match_operand:SI 2 "general_operand" "ri,rm")))
5523    (clobber (reg:CC FLAGS_REG))]
5524   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5525   "adc{l}\t{%2, %0|%0, %2}"
5526   [(set_attr "type" "alu")
5527    (set_attr "pent_pair" "pu")
5528    (set_attr "mode" "SI")])
5529
5530 (define_insn "*addsi3_carry_zext"
5531   [(set (match_operand:DI 0 "register_operand" "=r")
5532           (zero_extend:DI
5533             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5534                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5535                      (match_operand:SI 2 "general_operand" "g"))))
5536    (clobber (reg:CC FLAGS_REG))]
5537   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5538   "adc{l}\t{%2, %k0|%k0, %2}"
5539   [(set_attr "type" "alu")
5540    (set_attr "pent_pair" "pu")
5541    (set_attr "mode" "SI")])
5542
5543 (define_insn "*addsi3_cc"
5544   [(set (reg:CC FLAGS_REG)
5545         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5546                     (match_operand:SI 2 "general_operand" "ri,rm")]
5547                    UNSPEC_ADD_CARRY))
5548    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5549         (plus:SI (match_dup 1) (match_dup 2)))]
5550   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5551   "add{l}\t{%2, %0|%0, %2}"
5552   [(set_attr "type" "alu")
5553    (set_attr "mode" "SI")])
5554
5555 (define_insn "addqi3_cc"
5556   [(set (reg:CC FLAGS_REG)
5557         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5558                     (match_operand:QI 2 "general_operand" "qi,qm")]
5559                    UNSPEC_ADD_CARRY))
5560    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5561         (plus:QI (match_dup 1) (match_dup 2)))]
5562   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5563   "add{b}\t{%2, %0|%0, %2}"
5564   [(set_attr "type" "alu")
5565    (set_attr "mode" "QI")])
5566
5567 (define_expand "addsi3"
5568   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5569                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5570                             (match_operand:SI 2 "general_operand" "")))
5571               (clobber (reg:CC FLAGS_REG))])]
5572   ""
5573   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5574
5575 (define_insn "*lea_1"
5576   [(set (match_operand:SI 0 "register_operand" "=r")
5577         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5578   "!TARGET_64BIT"
5579   "lea{l}\t{%a1, %0|%0, %a1}"
5580   [(set_attr "type" "lea")
5581    (set_attr "mode" "SI")])
5582
5583 (define_insn "*lea_1_rex64"
5584   [(set (match_operand:SI 0 "register_operand" "=r")
5585         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5586   "TARGET_64BIT"
5587   "lea{l}\t{%a1, %0|%0, %a1}"
5588   [(set_attr "type" "lea")
5589    (set_attr "mode" "SI")])
5590
5591 (define_insn "*lea_1_zext"
5592   [(set (match_operand:DI 0 "register_operand" "=r")
5593         (zero_extend:DI
5594          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5595   "TARGET_64BIT"
5596   "lea{l}\t{%a1, %k0|%k0, %a1}"
5597   [(set_attr "type" "lea")
5598    (set_attr "mode" "SI")])
5599
5600 (define_insn "*lea_2_rex64"
5601   [(set (match_operand:DI 0 "register_operand" "=r")
5602         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5603   "TARGET_64BIT"
5604   "lea{q}\t{%a1, %0|%0, %a1}"
5605   [(set_attr "type" "lea")
5606    (set_attr "mode" "DI")])
5607
5608 ;; The lea patterns for non-Pmodes needs to be matched by several
5609 ;; insns converted to real lea by splitters.
5610
5611 (define_insn_and_split "*lea_general_1"
5612   [(set (match_operand 0 "register_operand" "=r")
5613         (plus (plus (match_operand 1 "index_register_operand" "l")
5614                     (match_operand 2 "register_operand" "r"))
5615               (match_operand 3 "immediate_operand" "i")))]
5616   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5617     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5618    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5619    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5620    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5621    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5622        || GET_MODE (operands[3]) == VOIDmode)"
5623   "#"
5624   "&& reload_completed"
5625   [(const_int 0)]
5626 {
5627   rtx pat;
5628   operands[0] = gen_lowpart (SImode, operands[0]);
5629   operands[1] = gen_lowpart (Pmode, operands[1]);
5630   operands[2] = gen_lowpart (Pmode, operands[2]);
5631   operands[3] = gen_lowpart (Pmode, operands[3]);
5632   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5633                       operands[3]);
5634   if (Pmode != SImode)
5635     pat = gen_rtx_SUBREG (SImode, pat, 0);
5636   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5637   DONE;
5638 }
5639   [(set_attr "type" "lea")
5640    (set_attr "mode" "SI")])
5641
5642 (define_insn_and_split "*lea_general_1_zext"
5643   [(set (match_operand:DI 0 "register_operand" "=r")
5644         (zero_extend:DI
5645           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5646                             (match_operand:SI 2 "register_operand" "r"))
5647                    (match_operand:SI 3 "immediate_operand" "i"))))]
5648   "TARGET_64BIT"
5649   "#"
5650   "&& reload_completed"
5651   [(set (match_dup 0)
5652         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5653                                                      (match_dup 2))
5654                                             (match_dup 3)) 0)))]
5655 {
5656   operands[1] = gen_lowpart (Pmode, operands[1]);
5657   operands[2] = gen_lowpart (Pmode, operands[2]);
5658   operands[3] = gen_lowpart (Pmode, operands[3]);
5659 }
5660   [(set_attr "type" "lea")
5661    (set_attr "mode" "SI")])
5662
5663 (define_insn_and_split "*lea_general_2"
5664   [(set (match_operand 0 "register_operand" "=r")
5665         (plus (mult (match_operand 1 "index_register_operand" "l")
5666                     (match_operand 2 "const248_operand" "i"))
5667               (match_operand 3 "nonmemory_operand" "ri")))]
5668   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5669     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5670    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5671    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5672    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5673        || GET_MODE (operands[3]) == VOIDmode)"
5674   "#"
5675   "&& reload_completed"
5676   [(const_int 0)]
5677 {
5678   rtx pat;
5679   operands[0] = gen_lowpart (SImode, operands[0]);
5680   operands[1] = gen_lowpart (Pmode, operands[1]);
5681   operands[3] = gen_lowpart (Pmode, operands[3]);
5682   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5683                       operands[3]);
5684   if (Pmode != SImode)
5685     pat = gen_rtx_SUBREG (SImode, pat, 0);
5686   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5687   DONE;
5688 }
5689   [(set_attr "type" "lea")
5690    (set_attr "mode" "SI")])
5691
5692 (define_insn_and_split "*lea_general_2_zext"
5693   [(set (match_operand:DI 0 "register_operand" "=r")
5694         (zero_extend:DI
5695           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5696                             (match_operand:SI 2 "const248_operand" "n"))
5697                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5698   "TARGET_64BIT"
5699   "#"
5700   "&& reload_completed"
5701   [(set (match_dup 0)
5702         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5703                                                      (match_dup 2))
5704                                             (match_dup 3)) 0)))]
5705 {
5706   operands[1] = gen_lowpart (Pmode, operands[1]);
5707   operands[3] = gen_lowpart (Pmode, operands[3]);
5708 }
5709   [(set_attr "type" "lea")
5710    (set_attr "mode" "SI")])
5711
5712 (define_insn_and_split "*lea_general_3"
5713   [(set (match_operand 0 "register_operand" "=r")
5714         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5715                           (match_operand 2 "const248_operand" "i"))
5716                     (match_operand 3 "register_operand" "r"))
5717               (match_operand 4 "immediate_operand" "i")))]
5718   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5719     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5720    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5721    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5722    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5723   "#"
5724   "&& reload_completed"
5725   [(const_int 0)]
5726 {
5727   rtx pat;
5728   operands[0] = gen_lowpart (SImode, operands[0]);
5729   operands[1] = gen_lowpart (Pmode, operands[1]);
5730   operands[3] = gen_lowpart (Pmode, operands[3]);
5731   operands[4] = gen_lowpart (Pmode, operands[4]);
5732   pat = gen_rtx_PLUS (Pmode,
5733                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5734                                                          operands[2]),
5735                                     operands[3]),
5736                       operands[4]);
5737   if (Pmode != SImode)
5738     pat = gen_rtx_SUBREG (SImode, pat, 0);
5739   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5740   DONE;
5741 }
5742   [(set_attr "type" "lea")
5743    (set_attr "mode" "SI")])
5744
5745 (define_insn_and_split "*lea_general_3_zext"
5746   [(set (match_operand:DI 0 "register_operand" "=r")
5747         (zero_extend:DI
5748           (plus:SI (plus:SI (mult:SI
5749                               (match_operand:SI 1 "index_register_operand" "l")
5750                               (match_operand:SI 2 "const248_operand" "n"))
5751                             (match_operand:SI 3 "register_operand" "r"))
5752                    (match_operand:SI 4 "immediate_operand" "i"))))]
5753   "TARGET_64BIT"
5754   "#"
5755   "&& reload_completed"
5756   [(set (match_dup 0)
5757         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5758                                                               (match_dup 2))
5759                                                      (match_dup 3))
5760                                             (match_dup 4)) 0)))]
5761 {
5762   operands[1] = gen_lowpart (Pmode, operands[1]);
5763   operands[3] = gen_lowpart (Pmode, operands[3]);
5764   operands[4] = gen_lowpart (Pmode, operands[4]);
5765 }
5766   [(set_attr "type" "lea")
5767    (set_attr "mode" "SI")])
5768
5769 (define_insn "*adddi_1_rex64"
5770   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5771         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5772                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775 {
5776   switch (get_attr_type (insn))
5777     {
5778     case TYPE_LEA:
5779       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5780       return "lea{q}\t{%a2, %0|%0, %a2}";
5781
5782     case TYPE_INCDEC:
5783       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784       if (operands[2] == const1_rtx)
5785         return "inc{q}\t%0";
5786       else
5787         {
5788           gcc_assert (operands[2] == constm1_rtx);
5789           return "dec{q}\t%0";
5790         }
5791
5792     default:
5793       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794
5795       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5796          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5797       if (CONST_INT_P (operands[2])
5798           /* Avoid overflows.  */
5799           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{q}\t{%2, %0|%0, %2}";
5806         }
5807       return "add{q}\t{%2, %0|%0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (cond [(eq_attr "alternative" "2")
5812               (const_string "lea")
5813             ; Current assemblers are broken and do not allow @GOTOFF in
5814             ; ought but a memory context.
5815             (match_operand:DI 2 "pic_symbolic_operand" "")
5816               (const_string "lea")
5817             (match_operand:DI 2 "incdec_operand" "")
5818               (const_string "incdec")
5819            ]
5820            (const_string "alu")))
5821    (set_attr "mode" "DI")])
5822
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5824 (define_split
5825   [(set (match_operand:DI 0 "register_operand" "")
5826         (plus:DI (match_operand:DI 1 "register_operand" "")
5827                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5828    (clobber (reg:CC FLAGS_REG))]
5829   "TARGET_64BIT && reload_completed
5830    && true_regnum (operands[0]) != true_regnum (operands[1])"
5831   [(set (match_dup 0)
5832         (plus:DI (match_dup 1)
5833                  (match_dup 2)))]
5834   "")
5835
5836 (define_insn "*adddi_2_rex64"
5837   [(set (reg FLAGS_REG)
5838         (compare
5839           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5840                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5841           (const_int 0)))
5842    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5843         (plus:DI (match_dup 1) (match_dup 2)))]
5844   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845    && ix86_binary_operator_ok (PLUS, DImode, operands)
5846    /* Current assemblers are broken and do not allow @GOTOFF in
5847       ought but a memory context.  */
5848    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5849 {
5850   switch (get_attr_type (insn))
5851     {
5852     case TYPE_INCDEC:
5853       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854       if (operands[2] == const1_rtx)
5855         return "inc{q}\t%0";
5856       else
5857         {
5858           gcc_assert (operands[2] == constm1_rtx);
5859           return "dec{q}\t%0";
5860         }
5861
5862     default:
5863       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5864       /* ???? We ought to handle there the 32bit case too
5865          - do we need new constraint?  */
5866       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5868       if (CONST_INT_P (operands[2])
5869           /* Avoid overflows.  */
5870           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5871           && (INTVAL (operands[2]) == 128
5872               || (INTVAL (operands[2]) < 0
5873                   && INTVAL (operands[2]) != -128)))
5874         {
5875           operands[2] = GEN_INT (-INTVAL (operands[2]));
5876           return "sub{q}\t{%2, %0|%0, %2}";
5877         }
5878       return "add{q}\t{%2, %0|%0, %2}";
5879     }
5880 }
5881   [(set (attr "type")
5882      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5883         (const_string "incdec")
5884         (const_string "alu")))
5885    (set_attr "mode" "DI")])
5886
5887 (define_insn "*adddi_3_rex64"
5888   [(set (reg FLAGS_REG)
5889         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5890                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5891    (clobber (match_scratch:DI 0 "=r"))]
5892   "TARGET_64BIT
5893    && ix86_match_ccmode (insn, CCZmode)
5894    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5895    /* Current assemblers are broken and do not allow @GOTOFF in
5896       ought but a memory context.  */
5897    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5898 {
5899   switch (get_attr_type (insn))
5900     {
5901     case TYPE_INCDEC:
5902       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5903       if (operands[2] == const1_rtx)
5904         return "inc{q}\t%0";
5905       else
5906         {
5907           gcc_assert (operands[2] == constm1_rtx);
5908           return "dec{q}\t%0";
5909         }
5910
5911     default:
5912       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5913       /* ???? We ought to handle there the 32bit case too
5914          - do we need new constraint?  */
5915       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917       if (CONST_INT_P (operands[2])
5918           /* Avoid overflows.  */
5919           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5920           && (INTVAL (operands[2]) == 128
5921               || (INTVAL (operands[2]) < 0
5922                   && INTVAL (operands[2]) != -128)))
5923         {
5924           operands[2] = GEN_INT (-INTVAL (operands[2]));
5925           return "sub{q}\t{%2, %0|%0, %2}";
5926         }
5927       return "add{q}\t{%2, %0|%0, %2}";
5928     }
5929 }
5930   [(set (attr "type")
5931      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5932         (const_string "incdec")
5933         (const_string "alu")))
5934    (set_attr "mode" "DI")])
5935
5936 ; For comparisons against 1, -1 and 128, we may generate better code
5937 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5938 ; is matched then.  We can't accept general immediate, because for
5939 ; case of overflows,  the result is messed up.
5940 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5941 ; when negated.
5942 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5943 ; only for comparisons not depending on it.
5944 (define_insn "*adddi_4_rex64"
5945   [(set (reg FLAGS_REG)
5946         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5947                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5948    (clobber (match_scratch:DI 0 "=rm"))]
5949   "TARGET_64BIT
5950    &&  ix86_match_ccmode (insn, CCGCmode)"
5951 {
5952   switch (get_attr_type (insn))
5953     {
5954     case TYPE_INCDEC:
5955       if (operands[2] == constm1_rtx)
5956         return "inc{q}\t%0";
5957       else
5958         {
5959           gcc_assert (operands[2] == const1_rtx);
5960           return "dec{q}\t%0";
5961         }
5962
5963     default:
5964       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5967       if ((INTVAL (operands[2]) == -128
5968            || (INTVAL (operands[2]) > 0
5969                && INTVAL (operands[2]) != 128))
5970           /* Avoid overflows.  */
5971           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5972         return "sub{q}\t{%2, %0|%0, %2}";
5973       operands[2] = GEN_INT (-INTVAL (operands[2]));
5974       return "add{q}\t{%2, %0|%0, %2}";
5975     }
5976 }
5977   [(set (attr "type")
5978      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5979         (const_string "incdec")
5980         (const_string "alu")))
5981    (set_attr "mode" "DI")])
5982
5983 (define_insn "*adddi_5_rex64"
5984   [(set (reg FLAGS_REG)
5985         (compare
5986           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5987                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5988           (const_int 0)))
5989    (clobber (match_scratch:DI 0 "=r"))]
5990   "TARGET_64BIT
5991    && ix86_match_ccmode (insn, CCGOCmode)
5992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5993    /* Current assemblers are broken and do not allow @GOTOFF in
5994       ought but a memory context.  */
5995    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5996 {
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001       if (operands[2] == const1_rtx)
6002         return "inc{q}\t%0";
6003       else
6004         {
6005           gcc_assert (operands[2] == constm1_rtx);
6006           return "dec{q}\t%0";
6007         }
6008
6009     default:
6010       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6013       if (CONST_INT_P (operands[2])
6014           /* Avoid overflows.  */
6015           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6016           && (INTVAL (operands[2]) == 128
6017               || (INTVAL (operands[2]) < 0
6018                   && INTVAL (operands[2]) != -128)))
6019         {
6020           operands[2] = GEN_INT (-INTVAL (operands[2]));
6021           return "sub{q}\t{%2, %0|%0, %2}";
6022         }
6023       return "add{q}\t{%2, %0|%0, %2}";
6024     }
6025 }
6026   [(set (attr "type")
6027      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6028         (const_string "incdec")
6029         (const_string "alu")))
6030    (set_attr "mode" "DI")])
6031
6032
6033 (define_insn "*addsi_1"
6034   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6035         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6036                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6037    (clobber (reg:CC FLAGS_REG))]
6038   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6039 {
6040   switch (get_attr_type (insn))
6041     {
6042     case TYPE_LEA:
6043       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6044       return "lea{l}\t{%a2, %0|%0, %a2}";
6045
6046     case TYPE_INCDEC:
6047       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048       if (operands[2] == const1_rtx)
6049         return "inc{l}\t%0";
6050       else
6051         {
6052           gcc_assert (operands[2] == constm1_rtx);
6053           return "dec{l}\t%0";
6054         }
6055
6056     default:
6057       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058
6059       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6060          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6061       if (CONST_INT_P (operands[2])
6062           && (INTVAL (operands[2]) == 128
6063               || (INTVAL (operands[2]) < 0
6064                   && INTVAL (operands[2]) != -128)))
6065         {
6066           operands[2] = GEN_INT (-INTVAL (operands[2]));
6067           return "sub{l}\t{%2, %0|%0, %2}";
6068         }
6069       return "add{l}\t{%2, %0|%0, %2}";
6070     }
6071 }
6072   [(set (attr "type")
6073      (cond [(eq_attr "alternative" "2")
6074               (const_string "lea")
6075             ; Current assemblers are broken and do not allow @GOTOFF in
6076             ; ought but a memory context.
6077             (match_operand:SI 2 "pic_symbolic_operand" "")
6078               (const_string "lea")
6079             (match_operand:SI 2 "incdec_operand" "")
6080               (const_string "incdec")
6081            ]
6082            (const_string "alu")))
6083    (set_attr "mode" "SI")])
6084
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6086 (define_split
6087   [(set (match_operand 0 "register_operand" "")
6088         (plus (match_operand 1 "register_operand" "")
6089               (match_operand 2 "nonmemory_operand" "")))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "reload_completed
6092    && true_regnum (operands[0]) != true_regnum (operands[1])"
6093   [(const_int 0)]
6094 {
6095   rtx pat;
6096   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6097      may confuse gen_lowpart.  */
6098   if (GET_MODE (operands[0]) != Pmode)
6099     {
6100       operands[1] = gen_lowpart (Pmode, operands[1]);
6101       operands[2] = gen_lowpart (Pmode, operands[2]);
6102     }
6103   operands[0] = gen_lowpart (SImode, operands[0]);
6104   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6105   if (Pmode != SImode)
6106     pat = gen_rtx_SUBREG (SImode, pat, 0);
6107   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6108   DONE;
6109 })
6110
6111 ;; It may seem that nonimmediate operand is proper one for operand 1.
6112 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6113 ;; we take care in ix86_binary_operator_ok to not allow two memory
6114 ;; operands so proper swapping will be done in reload.  This allow
6115 ;; patterns constructed from addsi_1 to match.
6116 (define_insn "addsi_1_zext"
6117   [(set (match_operand:DI 0 "register_operand" "=r,r")
6118         (zero_extend:DI
6119           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6120                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6123 {
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_LEA:
6127       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6129
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return "inc{l}\t%k0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return "dec{l}\t%k0";
6137         }
6138
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (CONST_INT_P (operands[2])
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           return "sub{l}\t{%2, %k0|%k0, %2}";
6149         }
6150       return "add{l}\t{%2, %k0|%k0, %2}";
6151     }
6152 }
6153   [(set (attr "type")
6154      (cond [(eq_attr "alternative" "1")
6155               (const_string "lea")
6156             ; Current assemblers are broken and do not allow @GOTOFF in
6157             ; ought but a memory context.
6158             (match_operand:SI 2 "pic_symbolic_operand" "")
6159               (const_string "lea")
6160             (match_operand:SI 2 "incdec_operand" "")
6161               (const_string "incdec")
6162            ]
6163            (const_string "alu")))
6164    (set_attr "mode" "SI")])
6165
6166 ;; Convert lea to the lea pattern to avoid flags dependency.
6167 (define_split
6168   [(set (match_operand:DI 0 "register_operand" "")
6169         (zero_extend:DI
6170           (plus:SI (match_operand:SI 1 "register_operand" "")
6171                    (match_operand:SI 2 "nonmemory_operand" ""))))
6172    (clobber (reg:CC FLAGS_REG))]
6173   "TARGET_64BIT && reload_completed
6174    && true_regnum (operands[0]) != true_regnum (operands[1])"
6175   [(set (match_dup 0)
6176         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6177 {
6178   operands[1] = gen_lowpart (Pmode, operands[1]);
6179   operands[2] = gen_lowpart (Pmode, operands[2]);
6180 })
6181
6182 (define_insn "*addsi_2"
6183   [(set (reg FLAGS_REG)
6184         (compare
6185           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6186                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6187           (const_int 0)))
6188    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6189         (plus:SI (match_dup 1) (match_dup 2)))]
6190   "ix86_match_ccmode (insn, CCGOCmode)
6191    && ix86_binary_operator_ok (PLUS, SImode, operands)
6192    /* Current assemblers are broken and do not allow @GOTOFF in
6193       ought but a memory context.  */
6194    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6195 {
6196   switch (get_attr_type (insn))
6197     {
6198     case TYPE_INCDEC:
6199       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6200       if (operands[2] == const1_rtx)
6201         return "inc{l}\t%0";
6202       else
6203         {
6204           gcc_assert (operands[2] == constm1_rtx);
6205           return "dec{l}\t%0";
6206         }
6207
6208     default:
6209       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6210       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6211          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6212       if (CONST_INT_P (operands[2])
6213           && (INTVAL (operands[2]) == 128
6214               || (INTVAL (operands[2]) < 0
6215                   && INTVAL (operands[2]) != -128)))
6216         {
6217           operands[2] = GEN_INT (-INTVAL (operands[2]));
6218           return "sub{l}\t{%2, %0|%0, %2}";
6219         }
6220       return "add{l}\t{%2, %0|%0, %2}";
6221     }
6222 }
6223   [(set (attr "type")
6224      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6225         (const_string "incdec")
6226         (const_string "alu")))
6227    (set_attr "mode" "SI")])
6228
6229 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6230 (define_insn "*addsi_2_zext"
6231   [(set (reg FLAGS_REG)
6232         (compare
6233           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6234                    (match_operand:SI 2 "general_operand" "rmni"))
6235           (const_int 0)))
6236    (set (match_operand:DI 0 "register_operand" "=r")
6237         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6238   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6239    && ix86_binary_operator_ok (PLUS, SImode, operands)
6240    /* Current assemblers are broken and do not allow @GOTOFF in
6241       ought but a memory context.  */
6242    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6243 {
6244   switch (get_attr_type (insn))
6245     {
6246     case TYPE_INCDEC:
6247       if (operands[2] == const1_rtx)
6248         return "inc{l}\t%k0";
6249       else
6250         {
6251           gcc_assert (operands[2] == constm1_rtx);
6252           return "dec{l}\t%k0";
6253         }
6254
6255     default:
6256       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6258       if (CONST_INT_P (operands[2])
6259           && (INTVAL (operands[2]) == 128
6260               || (INTVAL (operands[2]) < 0
6261                   && INTVAL (operands[2]) != -128)))
6262         {
6263           operands[2] = GEN_INT (-INTVAL (operands[2]));
6264           return "sub{l}\t{%2, %k0|%k0, %2}";
6265         }
6266       return "add{l}\t{%2, %k0|%k0, %2}";
6267     }
6268 }
6269   [(set (attr "type")
6270      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6271         (const_string "incdec")
6272         (const_string "alu")))
6273    (set_attr "mode" "SI")])
6274
6275 (define_insn "*addsi_3"
6276   [(set (reg FLAGS_REG)
6277         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6278                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6279    (clobber (match_scratch:SI 0 "=r"))]
6280   "ix86_match_ccmode (insn, CCZmode)
6281    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6282    /* Current assemblers are broken and do not allow @GOTOFF in
6283       ought but a memory context.  */
6284    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6285 {
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6290       if (operands[2] == const1_rtx)
6291         return "inc{l}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == constm1_rtx);
6295           return "dec{l}\t%0";
6296         }
6297
6298     default:
6299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6301          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6302       if (CONST_INT_P (operands[2])
6303           && (INTVAL (operands[2]) == 128
6304               || (INTVAL (operands[2]) < 0
6305                   && INTVAL (operands[2]) != -128)))
6306         {
6307           operands[2] = GEN_INT (-INTVAL (operands[2]));
6308           return "sub{l}\t{%2, %0|%0, %2}";
6309         }
6310       return "add{l}\t{%2, %0|%0, %2}";
6311     }
6312 }
6313   [(set (attr "type")
6314      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6315         (const_string "incdec")
6316         (const_string "alu")))
6317    (set_attr "mode" "SI")])
6318
6319 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6320 (define_insn "*addsi_3_zext"
6321   [(set (reg FLAGS_REG)
6322         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6323                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6324    (set (match_operand:DI 0 "register_operand" "=r")
6325         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6326   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6327    && ix86_binary_operator_ok (PLUS, SImode, operands)
6328    /* Current assemblers are broken and do not allow @GOTOFF in
6329       ought but a memory context.  */
6330    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6331 {
6332   switch (get_attr_type (insn))
6333     {
6334     case TYPE_INCDEC:
6335       if (operands[2] == const1_rtx)
6336         return "inc{l}\t%k0";
6337       else
6338         {
6339           gcc_assert (operands[2] == constm1_rtx);
6340           return "dec{l}\t%k0";
6341         }
6342
6343     default:
6344       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6346       if (CONST_INT_P (operands[2])
6347           && (INTVAL (operands[2]) == 128
6348               || (INTVAL (operands[2]) < 0
6349                   && INTVAL (operands[2]) != -128)))
6350         {
6351           operands[2] = GEN_INT (-INTVAL (operands[2]));
6352           return "sub{l}\t{%2, %k0|%k0, %2}";
6353         }
6354       return "add{l}\t{%2, %k0|%k0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "SI")])
6362
6363 ; For comparisons against 1, -1 and 128, we may generate better code
6364 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6365 ; is matched then.  We can't accept general immediate, because for
6366 ; case of overflows,  the result is messed up.
6367 ; This pattern also don't hold of 0x80000000, since the value overflows
6368 ; when negated.
6369 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6370 ; only for comparisons not depending on it.
6371 (define_insn "*addsi_4"
6372   [(set (reg FLAGS_REG)
6373         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6374                  (match_operand:SI 2 "const_int_operand" "n")))
6375    (clobber (match_scratch:SI 0 "=rm"))]
6376   "ix86_match_ccmode (insn, CCGCmode)
6377    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6378 {
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == constm1_rtx)
6383         return "inc{l}\t%0";
6384       else
6385         {
6386           gcc_assert (operands[2] == const1_rtx);
6387           return "dec{l}\t%0";
6388         }
6389
6390     default:
6391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6392       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6393          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6394       if ((INTVAL (operands[2]) == -128
6395            || (INTVAL (operands[2]) > 0
6396                && INTVAL (operands[2]) != 128)))
6397         return "sub{l}\t{%2, %0|%0, %2}";
6398       operands[2] = GEN_INT (-INTVAL (operands[2]));
6399       return "add{l}\t{%2, %0|%0, %2}";
6400     }
6401 }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set_attr "mode" "SI")])
6407
6408 (define_insn "*addsi_5"
6409   [(set (reg FLAGS_REG)
6410         (compare
6411           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6412                    (match_operand:SI 2 "general_operand" "rmni"))
6413           (const_int 0)))
6414    (clobber (match_scratch:SI 0 "=r"))]
6415   "ix86_match_ccmode (insn, CCGOCmode)
6416    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6417    /* Current assemblers are broken and do not allow @GOTOFF in
6418       ought but a memory context.  */
6419    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6420 {
6421   switch (get_attr_type (insn))
6422     {
6423     case TYPE_INCDEC:
6424       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6425       if (operands[2] == const1_rtx)
6426         return "inc{l}\t%0";
6427       else
6428         {
6429           gcc_assert (operands[2] == constm1_rtx);
6430           return "dec{l}\t%0";
6431         }
6432
6433     default:
6434       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6435       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6436          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6437       if (CONST_INT_P (operands[2])
6438           && (INTVAL (operands[2]) == 128
6439               || (INTVAL (operands[2]) < 0
6440                   && INTVAL (operands[2]) != -128)))
6441         {
6442           operands[2] = GEN_INT (-INTVAL (operands[2]));
6443           return "sub{l}\t{%2, %0|%0, %2}";
6444         }
6445       return "add{l}\t{%2, %0|%0, %2}";
6446     }
6447 }
6448   [(set (attr "type")
6449      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6450         (const_string "incdec")
6451         (const_string "alu")))
6452    (set_attr "mode" "SI")])
6453
6454 (define_expand "addhi3"
6455   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6456                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6457                             (match_operand:HI 2 "general_operand" "")))
6458               (clobber (reg:CC FLAGS_REG))])]
6459   "TARGET_HIMODE_MATH"
6460   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6461
6462 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6463 ;; type optimizations enabled by define-splits.  This is not important
6464 ;; for PII, and in fact harmful because of partial register stalls.
6465
6466 (define_insn "*addhi_1_lea"
6467   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6468         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6469                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6470    (clobber (reg:CC FLAGS_REG))]
6471   "!TARGET_PARTIAL_REG_STALL
6472    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6473 {
6474   switch (get_attr_type (insn))
6475     {
6476     case TYPE_LEA:
6477       return "#";
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{w}\t%0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{w}\t%0";
6485         }
6486
6487     default:
6488       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{w}\t{%2, %0|%0, %2}";
6497         }
6498       return "add{w}\t{%2, %0|%0, %2}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (eq_attr "alternative" "2")
6503         (const_string "lea")
6504         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6505            (const_string "incdec")
6506            (const_string "alu"))))
6507    (set_attr "mode" "HI,HI,SI")])
6508
6509 (define_insn "*addhi_1"
6510   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6511         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6512                  (match_operand:HI 2 "general_operand" "ri,rm")))
6513    (clobber (reg:CC FLAGS_REG))]
6514   "TARGET_PARTIAL_REG_STALL
6515    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6516 {
6517   switch (get_attr_type (insn))
6518     {
6519     case TYPE_INCDEC:
6520       if (operands[2] == const1_rtx)
6521         return "inc{w}\t%0";
6522       else
6523         {
6524           gcc_assert (operands[2] == constm1_rtx);
6525           return "dec{w}\t%0";
6526         }
6527
6528     default:
6529       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6531       if (CONST_INT_P (operands[2])
6532           && (INTVAL (operands[2]) == 128
6533               || (INTVAL (operands[2]) < 0
6534                   && INTVAL (operands[2]) != -128)))
6535         {
6536           operands[2] = GEN_INT (-INTVAL (operands[2]));
6537           return "sub{w}\t{%2, %0|%0, %2}";
6538         }
6539       return "add{w}\t{%2, %0|%0, %2}";
6540     }
6541 }
6542   [(set (attr "type")
6543      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6544         (const_string "incdec")
6545         (const_string "alu")))
6546    (set_attr "mode" "HI")])
6547
6548 (define_insn "*addhi_2"
6549   [(set (reg FLAGS_REG)
6550         (compare
6551           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6552                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6553           (const_int 0)))
6554    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6555         (plus:HI (match_dup 1) (match_dup 2)))]
6556   "ix86_match_ccmode (insn, CCGOCmode)
6557    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6558 {
6559   switch (get_attr_type (insn))
6560     {
6561     case TYPE_INCDEC:
6562       if (operands[2] == const1_rtx)
6563         return "inc{w}\t%0";
6564       else
6565         {
6566           gcc_assert (operands[2] == constm1_rtx);
6567           return "dec{w}\t%0";
6568         }
6569
6570     default:
6571       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6572          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6573       if (CONST_INT_P (operands[2])
6574           && (INTVAL (operands[2]) == 128
6575               || (INTVAL (operands[2]) < 0
6576                   && INTVAL (operands[2]) != -128)))
6577         {
6578           operands[2] = GEN_INT (-INTVAL (operands[2]));
6579           return "sub{w}\t{%2, %0|%0, %2}";
6580         }
6581       return "add{w}\t{%2, %0|%0, %2}";
6582     }
6583 }
6584   [(set (attr "type")
6585      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6586         (const_string "incdec")
6587         (const_string "alu")))
6588    (set_attr "mode" "HI")])
6589
6590 (define_insn "*addhi_3"
6591   [(set (reg FLAGS_REG)
6592         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6593                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6594    (clobber (match_scratch:HI 0 "=r"))]
6595   "ix86_match_ccmode (insn, CCZmode)
6596    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6597 {
6598   switch (get_attr_type (insn))
6599     {
6600     case TYPE_INCDEC:
6601       if (operands[2] == const1_rtx)
6602         return "inc{w}\t%0";
6603       else
6604         {
6605           gcc_assert (operands[2] == constm1_rtx);
6606           return "dec{w}\t%0";
6607         }
6608
6609     default:
6610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6612       if (CONST_INT_P (operands[2])
6613           && (INTVAL (operands[2]) == 128
6614               || (INTVAL (operands[2]) < 0
6615                   && INTVAL (operands[2]) != -128)))
6616         {
6617           operands[2] = GEN_INT (-INTVAL (operands[2]));
6618           return "sub{w}\t{%2, %0|%0, %2}";
6619         }
6620       return "add{w}\t{%2, %0|%0, %2}";
6621     }
6622 }
6623   [(set (attr "type")
6624      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6625         (const_string "incdec")
6626         (const_string "alu")))
6627    (set_attr "mode" "HI")])
6628
6629 ; See comments above addsi_4 for details.
6630 (define_insn "*addhi_4"
6631   [(set (reg FLAGS_REG)
6632         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6633                  (match_operand:HI 2 "const_int_operand" "n")))
6634    (clobber (match_scratch:HI 0 "=rm"))]
6635   "ix86_match_ccmode (insn, CCGCmode)
6636    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6637 {
6638   switch (get_attr_type (insn))
6639     {
6640     case TYPE_INCDEC:
6641       if (operands[2] == constm1_rtx)
6642         return "inc{w}\t%0";
6643       else
6644         {
6645           gcc_assert (operands[2] == const1_rtx);
6646           return "dec{w}\t%0";
6647         }
6648
6649     default:
6650       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6651       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6653       if ((INTVAL (operands[2]) == -128
6654            || (INTVAL (operands[2]) > 0
6655                && INTVAL (operands[2]) != 128)))
6656         return "sub{w}\t{%2, %0|%0, %2}";
6657       operands[2] = GEN_INT (-INTVAL (operands[2]));
6658       return "add{w}\t{%2, %0|%0, %2}";
6659     }
6660 }
6661   [(set (attr "type")
6662      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6663         (const_string "incdec")
6664         (const_string "alu")))
6665    (set_attr "mode" "SI")])
6666
6667
6668 (define_insn "*addhi_5"
6669   [(set (reg FLAGS_REG)
6670         (compare
6671           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6672                    (match_operand:HI 2 "general_operand" "rmni"))
6673           (const_int 0)))
6674    (clobber (match_scratch:HI 0 "=r"))]
6675   "ix86_match_ccmode (insn, CCGOCmode)
6676    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 {
6678   switch (get_attr_type (insn))
6679     {
6680     case TYPE_INCDEC:
6681       if (operands[2] == const1_rtx)
6682         return "inc{w}\t%0";
6683       else
6684         {
6685           gcc_assert (operands[2] == constm1_rtx);
6686           return "dec{w}\t%0";
6687         }
6688
6689     default:
6690       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6691          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6692       if (CONST_INT_P (operands[2])
6693           && (INTVAL (operands[2]) == 128
6694               || (INTVAL (operands[2]) < 0
6695                   && INTVAL (operands[2]) != -128)))
6696         {
6697           operands[2] = GEN_INT (-INTVAL (operands[2]));
6698           return "sub{w}\t{%2, %0|%0, %2}";
6699         }
6700       return "add{w}\t{%2, %0|%0, %2}";
6701     }
6702 }
6703   [(set (attr "type")
6704      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6705         (const_string "incdec")
6706         (const_string "alu")))
6707    (set_attr "mode" "HI")])
6708
6709 (define_expand "addqi3"
6710   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6711                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6712                             (match_operand:QI 2 "general_operand" "")))
6713               (clobber (reg:CC FLAGS_REG))])]
6714   "TARGET_QIMODE_MATH"
6715   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6716
6717 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6718 (define_insn "*addqi_1_lea"
6719   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6720         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6721                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6722    (clobber (reg:CC FLAGS_REG))]
6723   "!TARGET_PARTIAL_REG_STALL
6724    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6725 {
6726   int widen = (which_alternative == 2);
6727   switch (get_attr_type (insn))
6728     {
6729     case TYPE_LEA:
6730       return "#";
6731     case TYPE_INCDEC:
6732       if (operands[2] == const1_rtx)
6733         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6734       else
6735         {
6736           gcc_assert (operands[2] == constm1_rtx);
6737           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6738         }
6739
6740     default:
6741       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6742          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6743       if (CONST_INT_P (operands[2])
6744           && (INTVAL (operands[2]) == 128
6745               || (INTVAL (operands[2]) < 0
6746                   && INTVAL (operands[2]) != -128)))
6747         {
6748           operands[2] = GEN_INT (-INTVAL (operands[2]));
6749           if (widen)
6750             return "sub{l}\t{%2, %k0|%k0, %2}";
6751           else
6752             return "sub{b}\t{%2, %0|%0, %2}";
6753         }
6754       if (widen)
6755         return "add{l}\t{%k2, %k0|%k0, %k2}";
6756       else
6757         return "add{b}\t{%2, %0|%0, %2}";
6758     }
6759 }
6760   [(set (attr "type")
6761      (if_then_else (eq_attr "alternative" "3")
6762         (const_string "lea")
6763         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6764            (const_string "incdec")
6765            (const_string "alu"))))
6766    (set_attr "mode" "QI,QI,SI,SI")])
6767
6768 (define_insn "*addqi_1"
6769   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6770         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6771                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6772    (clobber (reg:CC FLAGS_REG))]
6773   "TARGET_PARTIAL_REG_STALL
6774    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6775 {
6776   int widen = (which_alternative == 2);
6777   switch (get_attr_type (insn))
6778     {
6779     case TYPE_INCDEC:
6780       if (operands[2] == const1_rtx)
6781         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6782       else
6783         {
6784           gcc_assert (operands[2] == constm1_rtx);
6785           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6786         }
6787
6788     default:
6789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6791       if (CONST_INT_P (operands[2])
6792           && (INTVAL (operands[2]) == 128
6793               || (INTVAL (operands[2]) < 0
6794                   && INTVAL (operands[2]) != -128)))
6795         {
6796           operands[2] = GEN_INT (-INTVAL (operands[2]));
6797           if (widen)
6798             return "sub{l}\t{%2, %k0|%k0, %2}";
6799           else
6800             return "sub{b}\t{%2, %0|%0, %2}";
6801         }
6802       if (widen)
6803         return "add{l}\t{%k2, %k0|%k0, %k2}";
6804       else
6805         return "add{b}\t{%2, %0|%0, %2}";
6806     }
6807 }
6808   [(set (attr "type")
6809      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6810         (const_string "incdec")
6811         (const_string "alu")))
6812    (set_attr "mode" "QI,QI,SI")])
6813
6814 (define_insn "*addqi_1_slp"
6815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6816         (plus:QI (match_dup 0)
6817                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6818    (clobber (reg:CC FLAGS_REG))]
6819   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6821 {
6822   switch (get_attr_type (insn))
6823     {
6824     case TYPE_INCDEC:
6825       if (operands[1] == const1_rtx)
6826         return "inc{b}\t%0";
6827       else
6828         {
6829           gcc_assert (operands[1] == constm1_rtx);
6830           return "dec{b}\t%0";
6831         }
6832
6833     default:
6834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6835       if (CONST_INT_P (operands[1])
6836           && INTVAL (operands[1]) < 0)
6837         {
6838           operands[1] = GEN_INT (-INTVAL (operands[1]));
6839           return "sub{b}\t{%1, %0|%0, %1}";
6840         }
6841       return "add{b}\t{%1, %0|%0, %1}";
6842     }
6843 }
6844   [(set (attr "type")
6845      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6846         (const_string "incdec")
6847         (const_string "alu1")))
6848    (set (attr "memory")
6849      (if_then_else (match_operand 1 "memory_operand" "")
6850         (const_string "load")
6851         (const_string "none")))
6852    (set_attr "mode" "QI")])
6853
6854 (define_insn "*addqi_2"
6855   [(set (reg FLAGS_REG)
6856         (compare
6857           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6858                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6859           (const_int 0)))
6860    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6861         (plus:QI (match_dup 1) (match_dup 2)))]
6862   "ix86_match_ccmode (insn, CCGOCmode)
6863    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6864 {
6865   switch (get_attr_type (insn))
6866     {
6867     case TYPE_INCDEC:
6868       if (operands[2] == const1_rtx)
6869         return "inc{b}\t%0";
6870       else
6871         {
6872           gcc_assert (operands[2] == constm1_rtx
6873                       || (CONST_INT_P (operands[2])
6874                           && INTVAL (operands[2]) == 255));
6875           return "dec{b}\t%0";
6876         }
6877
6878     default:
6879       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6880       if (CONST_INT_P (operands[2])
6881           && INTVAL (operands[2]) < 0)
6882         {
6883           operands[2] = GEN_INT (-INTVAL (operands[2]));
6884           return "sub{b}\t{%2, %0|%0, %2}";
6885         }
6886       return "add{b}\t{%2, %0|%0, %2}";
6887     }
6888 }
6889   [(set (attr "type")
6890      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6891         (const_string "incdec")
6892         (const_string "alu")))
6893    (set_attr "mode" "QI")])
6894
6895 (define_insn "*addqi_3"
6896   [(set (reg FLAGS_REG)
6897         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6898                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6899    (clobber (match_scratch:QI 0 "=q"))]
6900   "ix86_match_ccmode (insn, CCZmode)
6901    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 {
6903   switch (get_attr_type (insn))
6904     {
6905     case TYPE_INCDEC:
6906       if (operands[2] == const1_rtx)
6907         return "inc{b}\t%0";
6908       else
6909         {
6910           gcc_assert (operands[2] == constm1_rtx
6911                       || (CONST_INT_P (operands[2])
6912                           && INTVAL (operands[2]) == 255));
6913           return "dec{b}\t%0";
6914         }
6915
6916     default:
6917       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6918       if (CONST_INT_P (operands[2])
6919           && INTVAL (operands[2]) < 0)
6920         {
6921           operands[2] = GEN_INT (-INTVAL (operands[2]));
6922           return "sub{b}\t{%2, %0|%0, %2}";
6923         }
6924       return "add{b}\t{%2, %0|%0, %2}";
6925     }
6926 }
6927   [(set (attr "type")
6928      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6929         (const_string "incdec")
6930         (const_string "alu")))
6931    (set_attr "mode" "QI")])
6932
6933 ; See comments above addsi_4 for details.
6934 (define_insn "*addqi_4"
6935   [(set (reg FLAGS_REG)
6936         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6937                  (match_operand:QI 2 "const_int_operand" "n")))
6938    (clobber (match_scratch:QI 0 "=qm"))]
6939   "ix86_match_ccmode (insn, CCGCmode)
6940    && (INTVAL (operands[2]) & 0xff) != 0x80"
6941 {
6942   switch (get_attr_type (insn))
6943     {
6944     case TYPE_INCDEC:
6945       if (operands[2] == constm1_rtx
6946           || (CONST_INT_P (operands[2])
6947               && INTVAL (operands[2]) == 255))
6948         return "inc{b}\t%0";
6949       else
6950         {
6951           gcc_assert (operands[2] == const1_rtx);
6952           return "dec{b}\t%0";
6953         }
6954
6955     default:
6956       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6957       if (INTVAL (operands[2]) < 0)
6958         {
6959           operands[2] = GEN_INT (-INTVAL (operands[2]));
6960           return "add{b}\t{%2, %0|%0, %2}";
6961         }
6962       return "sub{b}\t{%2, %0|%0, %2}";
6963     }
6964 }
6965   [(set (attr "type")
6966      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6967         (const_string "incdec")
6968         (const_string "alu")))
6969    (set_attr "mode" "QI")])
6970
6971
6972 (define_insn "*addqi_5"
6973   [(set (reg FLAGS_REG)
6974         (compare
6975           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976                    (match_operand:QI 2 "general_operand" "qmni"))
6977           (const_int 0)))
6978    (clobber (match_scratch:QI 0 "=q"))]
6979   "ix86_match_ccmode (insn, CCGOCmode)
6980    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6981 {
6982   switch (get_attr_type (insn))
6983     {
6984     case TYPE_INCDEC:
6985       if (operands[2] == const1_rtx)
6986         return "inc{b}\t%0";
6987       else
6988         {
6989           gcc_assert (operands[2] == constm1_rtx
6990                       || (CONST_INT_P (operands[2])
6991                           && INTVAL (operands[2]) == 255));
6992           return "dec{b}\t%0";
6993         }
6994
6995     default:
6996       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6997       if (CONST_INT_P (operands[2])
6998           && INTVAL (operands[2]) < 0)
6999         {
7000           operands[2] = GEN_INT (-INTVAL (operands[2]));
7001           return "sub{b}\t{%2, %0|%0, %2}";
7002         }
7003       return "add{b}\t{%2, %0|%0, %2}";
7004     }
7005 }
7006   [(set (attr "type")
7007      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7008         (const_string "incdec")
7009         (const_string "alu")))
7010    (set_attr "mode" "QI")])
7011
7012
7013 (define_insn "addqi_ext_1"
7014   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7015                          (const_int 8)
7016                          (const_int 8))
7017         (plus:SI
7018           (zero_extract:SI
7019             (match_operand 1 "ext_register_operand" "0")
7020             (const_int 8)
7021             (const_int 8))
7022           (match_operand:QI 2 "general_operand" "Qmn")))
7023    (clobber (reg:CC FLAGS_REG))]
7024   "!TARGET_64BIT"
7025 {
7026   switch (get_attr_type (insn))
7027     {
7028     case TYPE_INCDEC:
7029       if (operands[2] == const1_rtx)
7030         return "inc{b}\t%h0";
7031       else
7032         {
7033           gcc_assert (operands[2] == constm1_rtx
7034                       || (CONST_INT_P (operands[2])
7035                           && INTVAL (operands[2]) == 255));
7036           return "dec{b}\t%h0";
7037         }
7038
7039     default:
7040       return "add{b}\t{%2, %h0|%h0, %2}";
7041     }
7042 }
7043   [(set (attr "type")
7044      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7045         (const_string "incdec")
7046         (const_string "alu")))
7047    (set_attr "mode" "QI")])
7048
7049 (define_insn "*addqi_ext_1_rex64"
7050   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7051                          (const_int 8)
7052                          (const_int 8))
7053         (plus:SI
7054           (zero_extract:SI
7055             (match_operand 1 "ext_register_operand" "0")
7056             (const_int 8)
7057             (const_int 8))
7058           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7059    (clobber (reg:CC FLAGS_REG))]
7060   "TARGET_64BIT"
7061 {
7062   switch (get_attr_type (insn))
7063     {
7064     case TYPE_INCDEC:
7065       if (operands[2] == const1_rtx)
7066         return "inc{b}\t%h0";
7067       else
7068         {
7069           gcc_assert (operands[2] == constm1_rtx
7070                       || (CONST_INT_P (operands[2])
7071                           && INTVAL (operands[2]) == 255));
7072           return "dec{b}\t%h0";
7073         }
7074
7075     default:
7076       return "add{b}\t{%2, %h0|%h0, %2}";
7077     }
7078 }
7079   [(set (attr "type")
7080      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7081         (const_string "incdec")
7082         (const_string "alu")))
7083    (set_attr "mode" "QI")])
7084
7085 (define_insn "*addqi_ext_2"
7086   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7087                          (const_int 8)
7088                          (const_int 8))
7089         (plus:SI
7090           (zero_extract:SI
7091             (match_operand 1 "ext_register_operand" "%0")
7092             (const_int 8)
7093             (const_int 8))
7094           (zero_extract:SI
7095             (match_operand 2 "ext_register_operand" "Q")
7096             (const_int 8)
7097             (const_int 8))))
7098    (clobber (reg:CC FLAGS_REG))]
7099   ""
7100   "add{b}\t{%h2, %h0|%h0, %h2}"
7101   [(set_attr "type" "alu")
7102    (set_attr "mode" "QI")])
7103
7104 ;; The patterns that match these are at the end of this file.
7105
7106 (define_expand "addxf3"
7107   [(set (match_operand:XF 0 "register_operand" "")
7108         (plus:XF (match_operand:XF 1 "register_operand" "")
7109                  (match_operand:XF 2 "register_operand" "")))]
7110   "TARGET_80387"
7111   "")
7112
7113 (define_expand "add<mode>3"
7114   [(set (match_operand:MODEF 0 "register_operand" "")
7115         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7116                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7117   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7118   "")
7119 \f
7120 ;; Subtract instructions
7121
7122 ;; %%% splits for subditi3
7123
7124 (define_expand "subti3"
7125   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7126                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7127                              (match_operand:TI 2 "x86_64_general_operand" "")))
7128               (clobber (reg:CC FLAGS_REG))])]
7129   "TARGET_64BIT"
7130   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7131
7132 (define_insn "*subti3_1"
7133   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7134         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7135                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7138   "#")
7139
7140 (define_split
7141   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7142         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7143                   (match_operand:TI 2 "x86_64_general_operand" "")))
7144    (clobber (reg:CC FLAGS_REG))]
7145   "TARGET_64BIT && reload_completed"
7146   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7147               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7148    (parallel [(set (match_dup 3)
7149                    (minus:DI (match_dup 4)
7150                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7151                                       (match_dup 5))))
7152               (clobber (reg:CC FLAGS_REG))])]
7153   "split_ti (operands+0, 1, operands+0, operands+3);
7154    split_ti (operands+1, 1, operands+1, operands+4);
7155    split_ti (operands+2, 1, operands+2, operands+5);")
7156
7157 ;; %%% splits for subsidi3
7158
7159 (define_expand "subdi3"
7160   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7161                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7162                              (match_operand:DI 2 "x86_64_general_operand" "")))
7163               (clobber (reg:CC FLAGS_REG))])]
7164   ""
7165   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7166
7167 (define_insn "*subdi3_1"
7168   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7169         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7170                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7173   "#")
7174
7175 (define_split
7176   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7177         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7178                   (match_operand:DI 2 "general_operand" "")))
7179    (clobber (reg:CC FLAGS_REG))]
7180   "!TARGET_64BIT && reload_completed"
7181   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7182               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7183    (parallel [(set (match_dup 3)
7184                    (minus:SI (match_dup 4)
7185                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7186                                       (match_dup 5))))
7187               (clobber (reg:CC FLAGS_REG))])]
7188   "split_di (operands+0, 1, operands+0, operands+3);
7189    split_di (operands+1, 1, operands+1, operands+4);
7190    split_di (operands+2, 1, operands+2, operands+5);")
7191
7192 (define_insn "subdi3_carry_rex64"
7193   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7194           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7195             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7196                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7199   "sbb{q}\t{%2, %0|%0, %2}"
7200   [(set_attr "type" "alu")
7201    (set_attr "pent_pair" "pu")
7202    (set_attr "mode" "DI")])
7203
7204 (define_insn "*subdi_1_rex64"
7205   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7206         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7207                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7208    (clobber (reg:CC FLAGS_REG))]
7209   "TARGET_64BIT && 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_2_rex64"
7215   [(set (reg FLAGS_REG)
7216         (compare
7217           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7218                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7219           (const_int 0)))
7220    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7221         (minus:DI (match_dup 1) (match_dup 2)))]
7222   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7223    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7224   "sub{q}\t{%2, %0|%0, %2}"
7225   [(set_attr "type" "alu")
7226    (set_attr "mode" "DI")])
7227
7228 (define_insn "*subdi_3_rex63"
7229   [(set (reg FLAGS_REG)
7230         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7231                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7232    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7233         (minus:DI (match_dup 1) (match_dup 2)))]
7234   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7235    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7236   "sub{q}\t{%2, %0|%0, %2}"
7237   [(set_attr "type" "alu")
7238    (set_attr "mode" "DI")])
7239
7240 (define_insn "subqi3_carry"
7241   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7242           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7243             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7244                (match_operand:QI 2 "general_operand" "qi,qm"))))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7247   "sbb{b}\t{%2, %0|%0, %2}"
7248   [(set_attr "type" "alu")
7249    (set_attr "pent_pair" "pu")
7250    (set_attr "mode" "QI")])
7251
7252 (define_insn "subhi3_carry"
7253   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7254           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7255             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7256                (match_operand:HI 2 "general_operand" "ri,rm"))))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7259   "sbb{w}\t{%2, %0|%0, %2}"
7260   [(set_attr "type" "alu")
7261    (set_attr "pent_pair" "pu")
7262    (set_attr "mode" "HI")])
7263
7264 (define_insn "subsi3_carry"
7265   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7266           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7267             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7268                (match_operand:SI 2 "general_operand" "ri,rm"))))
7269    (clobber (reg:CC FLAGS_REG))]
7270   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7271   "sbb{l}\t{%2, %0|%0, %2}"
7272   [(set_attr "type" "alu")
7273    (set_attr "pent_pair" "pu")
7274    (set_attr "mode" "SI")])
7275
7276 (define_insn "subsi3_carry_zext"
7277   [(set (match_operand:DI 0 "register_operand" "=r")
7278           (zero_extend:DI
7279             (minus:SI (match_operand:SI 1 "register_operand" "0")
7280               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7281                  (match_operand:SI 2 "general_operand" "g")))))
7282    (clobber (reg:CC FLAGS_REG))]
7283   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7284   "sbb{l}\t{%2, %k0|%k0, %2}"
7285   [(set_attr "type" "alu")
7286    (set_attr "pent_pair" "pu")
7287    (set_attr "mode" "SI")])
7288
7289 (define_expand "subsi3"
7290   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7291                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7292                              (match_operand:SI 2 "general_operand" "")))
7293               (clobber (reg:CC FLAGS_REG))])]
7294   ""
7295   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7296
7297 (define_insn "*subsi_1"
7298   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7299         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7300                   (match_operand:SI 2 "general_operand" "ri,rm")))
7301    (clobber (reg:CC FLAGS_REG))]
7302   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7303   "sub{l}\t{%2, %0|%0, %2}"
7304   [(set_attr "type" "alu")
7305    (set_attr "mode" "SI")])
7306
7307 (define_insn "*subsi_1_zext"
7308   [(set (match_operand:DI 0 "register_operand" "=r")
7309         (zero_extend:DI
7310           (minus:SI (match_operand:SI 1 "register_operand" "0")
7311                     (match_operand:SI 2 "general_operand" "g"))))
7312    (clobber (reg:CC FLAGS_REG))]
7313   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7314   "sub{l}\t{%2, %k0|%k0, %2}"
7315   [(set_attr "type" "alu")
7316    (set_attr "mode" "SI")])
7317
7318 (define_insn "*subsi_2"
7319   [(set (reg FLAGS_REG)
7320         (compare
7321           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7322                     (match_operand:SI 2 "general_operand" "ri,rm"))
7323           (const_int 0)))
7324    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7325         (minus:SI (match_dup 1) (match_dup 2)))]
7326   "ix86_match_ccmode (insn, CCGOCmode)
7327    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7328   "sub{l}\t{%2, %0|%0, %2}"
7329   [(set_attr "type" "alu")
7330    (set_attr "mode" "SI")])
7331
7332 (define_insn "*subsi_2_zext"
7333   [(set (reg FLAGS_REG)
7334         (compare
7335           (minus:SI (match_operand:SI 1 "register_operand" "0")
7336                     (match_operand:SI 2 "general_operand" "g"))
7337           (const_int 0)))
7338    (set (match_operand:DI 0 "register_operand" "=r")
7339         (zero_extend:DI
7340           (minus:SI (match_dup 1)
7341                     (match_dup 2))))]
7342   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7343    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7344   "sub{l}\t{%2, %k0|%k0, %2}"
7345   [(set_attr "type" "alu")
7346    (set_attr "mode" "SI")])
7347
7348 (define_insn "*subsi_3"
7349   [(set (reg FLAGS_REG)
7350         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7351                  (match_operand:SI 2 "general_operand" "ri,rm")))
7352    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7353         (minus:SI (match_dup 1) (match_dup 2)))]
7354   "ix86_match_ccmode (insn, CCmode)
7355    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7356   "sub{l}\t{%2, %0|%0, %2}"
7357   [(set_attr "type" "alu")
7358    (set_attr "mode" "SI")])
7359
7360 (define_insn "*subsi_3_zext"
7361   [(set (reg FLAGS_REG)
7362         (compare (match_operand:SI 1 "register_operand" "0")
7363                  (match_operand:SI 2 "general_operand" "g")))
7364    (set (match_operand:DI 0 "register_operand" "=r")
7365         (zero_extend:DI
7366           (minus:SI (match_dup 1)
7367                     (match_dup 2))))]
7368   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7369    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7370   "sub{l}\t{%2, %1|%1, %2}"
7371   [(set_attr "type" "alu")
7372    (set_attr "mode" "DI")])
7373
7374 (define_expand "subhi3"
7375   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7376                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7377                              (match_operand:HI 2 "general_operand" "")))
7378               (clobber (reg:CC FLAGS_REG))])]
7379   "TARGET_HIMODE_MATH"
7380   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7381
7382 (define_insn "*subhi_1"
7383   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7384         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7385                   (match_operand:HI 2 "general_operand" "ri,rm")))
7386    (clobber (reg:CC FLAGS_REG))]
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_2"
7393   [(set (reg FLAGS_REG)
7394         (compare
7395           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396                     (match_operand:HI 2 "general_operand" "ri,rm"))
7397           (const_int 0)))
7398    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7399         (minus:HI (match_dup 1) (match_dup 2)))]
7400   "ix86_match_ccmode (insn, CCGOCmode)
7401    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7402   "sub{w}\t{%2, %0|%0, %2}"
7403   [(set_attr "type" "alu")
7404    (set_attr "mode" "HI")])
7405
7406 (define_insn "*subhi_3"
7407   [(set (reg FLAGS_REG)
7408         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7409                  (match_operand:HI 2 "general_operand" "ri,rm")))
7410    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7411         (minus:HI (match_dup 1) (match_dup 2)))]
7412   "ix86_match_ccmode (insn, CCmode)
7413    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7414   "sub{w}\t{%2, %0|%0, %2}"
7415   [(set_attr "type" "alu")
7416    (set_attr "mode" "HI")])
7417
7418 (define_expand "subqi3"
7419   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7420                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7421                              (match_operand:QI 2 "general_operand" "")))
7422               (clobber (reg:CC FLAGS_REG))])]
7423   "TARGET_QIMODE_MATH"
7424   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7425
7426 (define_insn "*subqi_1"
7427   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7428         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7429                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7430    (clobber (reg:CC FLAGS_REG))]
7431   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7432   "sub{b}\t{%2, %0|%0, %2}"
7433   [(set_attr "type" "alu")
7434    (set_attr "mode" "QI")])
7435
7436 (define_insn "*subqi_1_slp"
7437   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7438         (minus:QI (match_dup 0)
7439                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7440    (clobber (reg:CC FLAGS_REG))]
7441   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443   "sub{b}\t{%1, %0|%0, %1}"
7444   [(set_attr "type" "alu1")
7445    (set_attr "mode" "QI")])
7446
7447 (define_insn "*subqi_2"
7448   [(set (reg FLAGS_REG)
7449         (compare
7450           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7451                     (match_operand:QI 2 "general_operand" "qi,qm"))
7452           (const_int 0)))
7453    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7454         (minus:HI (match_dup 1) (match_dup 2)))]
7455   "ix86_match_ccmode (insn, CCGOCmode)
7456    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7457   "sub{b}\t{%2, %0|%0, %2}"
7458   [(set_attr "type" "alu")
7459    (set_attr "mode" "QI")])
7460
7461 (define_insn "*subqi_3"
7462   [(set (reg FLAGS_REG)
7463         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7464                  (match_operand:QI 2 "general_operand" "qi,qm")))
7465    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7466         (minus:HI (match_dup 1) (match_dup 2)))]
7467   "ix86_match_ccmode (insn, CCmode)
7468    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7469   "sub{b}\t{%2, %0|%0, %2}"
7470   [(set_attr "type" "alu")
7471    (set_attr "mode" "QI")])
7472
7473 ;; The patterns that match these are at the end of this file.
7474
7475 (define_expand "subxf3"
7476   [(set (match_operand:XF 0 "register_operand" "")
7477         (minus:XF (match_operand:XF 1 "register_operand" "")
7478                   (match_operand:XF 2 "register_operand" "")))]
7479   "TARGET_80387"
7480   "")
7481
7482 (define_expand "sub<mode>3"
7483   [(set (match_operand:MODEF 0 "register_operand" "")
7484         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7485                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7486   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7487   "")
7488 \f
7489 ;; Multiply instructions
7490
7491 (define_expand "muldi3"
7492   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7493                    (mult:DI (match_operand:DI 1 "register_operand" "")
7494                             (match_operand:DI 2 "x86_64_general_operand" "")))
7495               (clobber (reg:CC FLAGS_REG))])]
7496   "TARGET_64BIT"
7497   "")
7498
7499 ;; On AMDFAM10
7500 ;; IMUL reg64, reg64, imm8      Direct
7501 ;; IMUL reg64, mem64, imm8      VectorPath
7502 ;; IMUL reg64, reg64, imm32     Direct
7503 ;; IMUL reg64, mem64, imm32     VectorPath
7504 ;; IMUL reg64, reg64            Direct
7505 ;; IMUL reg64, mem64            Direct
7506
7507 (define_insn "*muldi3_1_rex64"
7508   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7509         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7510                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7511    (clobber (reg:CC FLAGS_REG))]
7512   "TARGET_64BIT
7513    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7514   "@
7515    imul{q}\t{%2, %1, %0|%0, %1, %2}
7516    imul{q}\t{%2, %1, %0|%0, %1, %2}
7517    imul{q}\t{%2, %0|%0, %2}"
7518   [(set_attr "type" "imul")
7519    (set_attr "prefix_0f" "0,0,1")
7520    (set (attr "athlon_decode")
7521         (cond [(eq_attr "cpu" "athlon")
7522                   (const_string "vector")
7523                (eq_attr "alternative" "1")
7524                   (const_string "vector")
7525                (and (eq_attr "alternative" "2")
7526                     (match_operand 1 "memory_operand" ""))
7527                   (const_string "vector")]
7528               (const_string "direct")))
7529    (set (attr "amdfam10_decode")
7530         (cond [(and (eq_attr "alternative" "0,1")
7531                     (match_operand 1 "memory_operand" ""))
7532                   (const_string "vector")]
7533               (const_string "direct")))
7534    (set_attr "mode" "DI")])
7535
7536 (define_expand "mulsi3"
7537   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7538                    (mult:SI (match_operand:SI 1 "register_operand" "")
7539                             (match_operand:SI 2 "general_operand" "")))
7540               (clobber (reg:CC FLAGS_REG))])]
7541   ""
7542   "")
7543
7544 ;; On AMDFAM10
7545 ;; IMUL reg32, reg32, imm8      Direct
7546 ;; IMUL reg32, mem32, imm8      VectorPath
7547 ;; IMUL reg32, reg32, imm32     Direct
7548 ;; IMUL reg32, mem32, imm32     VectorPath
7549 ;; IMUL reg32, reg32            Direct
7550 ;; IMUL reg32, mem32            Direct
7551
7552 (define_insn "*mulsi3_1"
7553   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7554         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7555                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7556    (clobber (reg:CC FLAGS_REG))]
7557   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7558   "@
7559    imul{l}\t{%2, %1, %0|%0, %1, %2}
7560    imul{l}\t{%2, %1, %0|%0, %1, %2}
7561    imul{l}\t{%2, %0|%0, %2}"
7562   [(set_attr "type" "imul")
7563    (set_attr "prefix_0f" "0,0,1")
7564    (set (attr "athlon_decode")
7565         (cond [(eq_attr "cpu" "athlon")
7566                   (const_string "vector")
7567                (eq_attr "alternative" "1")
7568                   (const_string "vector")
7569                (and (eq_attr "alternative" "2")
7570                     (match_operand 1 "memory_operand" ""))
7571                   (const_string "vector")]
7572               (const_string "direct")))
7573    (set (attr "amdfam10_decode")
7574         (cond [(and (eq_attr "alternative" "0,1")
7575                     (match_operand 1 "memory_operand" ""))
7576                   (const_string "vector")]
7577               (const_string "direct")))
7578    (set_attr "mode" "SI")])
7579
7580 (define_insn "*mulsi3_1_zext"
7581   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7582         (zero_extend:DI
7583           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7584                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7585    (clobber (reg:CC FLAGS_REG))]
7586   "TARGET_64BIT
7587    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588   "@
7589    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7590    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7591    imul{l}\t{%2, %k0|%k0, %2}"
7592   [(set_attr "type" "imul")
7593    (set_attr "prefix_0f" "0,0,1")
7594    (set (attr "athlon_decode")
7595         (cond [(eq_attr "cpu" "athlon")
7596                   (const_string "vector")
7597                (eq_attr "alternative" "1")
7598                   (const_string "vector")
7599                (and (eq_attr "alternative" "2")
7600                     (match_operand 1 "memory_operand" ""))
7601                   (const_string "vector")]
7602               (const_string "direct")))
7603    (set (attr "amdfam10_decode")
7604         (cond [(and (eq_attr "alternative" "0,1")
7605                     (match_operand 1 "memory_operand" ""))
7606                   (const_string "vector")]
7607               (const_string "direct")))
7608    (set_attr "mode" "SI")])
7609
7610 (define_expand "mulhi3"
7611   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7612                    (mult:HI (match_operand:HI 1 "register_operand" "")
7613                             (match_operand:HI 2 "general_operand" "")))
7614               (clobber (reg:CC FLAGS_REG))])]
7615   "TARGET_HIMODE_MATH"
7616   "")
7617
7618 ;; On AMDFAM10
7619 ;; IMUL reg16, reg16, imm8      VectorPath
7620 ;; IMUL reg16, mem16, imm8      VectorPath
7621 ;; IMUL reg16, reg16, imm16     VectorPath
7622 ;; IMUL reg16, mem16, imm16     VectorPath
7623 ;; IMUL reg16, reg16            Direct
7624 ;; IMUL reg16, mem16            Direct
7625 (define_insn "*mulhi3_1"
7626   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7627         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7628                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7629    (clobber (reg:CC FLAGS_REG))]
7630   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7631   "@
7632    imul{w}\t{%2, %1, %0|%0, %1, %2}
7633    imul{w}\t{%2, %1, %0|%0, %1, %2}
7634    imul{w}\t{%2, %0|%0, %2}"
7635   [(set_attr "type" "imul")
7636    (set_attr "prefix_0f" "0,0,1")
7637    (set (attr "athlon_decode")
7638         (cond [(eq_attr "cpu" "athlon")
7639                   (const_string "vector")
7640                (eq_attr "alternative" "1,2")
7641                   (const_string "vector")]
7642               (const_string "direct")))
7643    (set (attr "amdfam10_decode")
7644         (cond [(eq_attr "alternative" "0,1")
7645                   (const_string "vector")]
7646               (const_string "direct")))
7647    (set_attr "mode" "HI")])
7648
7649 (define_expand "mulqi3"
7650   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7651                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7652                             (match_operand:QI 2 "register_operand" "")))
7653               (clobber (reg:CC FLAGS_REG))])]
7654   "TARGET_QIMODE_MATH"
7655   "")
7656
7657 ;;On AMDFAM10
7658 ;; MUL reg8     Direct
7659 ;; MUL mem8     Direct
7660
7661 (define_insn "*mulqi3_1"
7662   [(set (match_operand:QI 0 "register_operand" "=a")
7663         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7664                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7665    (clobber (reg:CC FLAGS_REG))]
7666   "TARGET_QIMODE_MATH
7667    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668   "mul{b}\t%2"
7669   [(set_attr "type" "imul")
7670    (set_attr "length_immediate" "0")
7671    (set (attr "athlon_decode")
7672      (if_then_else (eq_attr "cpu" "athlon")
7673         (const_string "vector")
7674         (const_string "direct")))
7675    (set_attr "amdfam10_decode" "direct")
7676    (set_attr "mode" "QI")])
7677
7678 (define_expand "umulqihi3"
7679   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7680                    (mult:HI (zero_extend:HI
7681                               (match_operand:QI 1 "nonimmediate_operand" ""))
7682                             (zero_extend:HI
7683                               (match_operand:QI 2 "register_operand" ""))))
7684               (clobber (reg:CC FLAGS_REG))])]
7685   "TARGET_QIMODE_MATH"
7686   "")
7687
7688 (define_insn "*umulqihi3_1"
7689   [(set (match_operand:HI 0 "register_operand" "=a")
7690         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7691                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7692    (clobber (reg:CC FLAGS_REG))]
7693   "TARGET_QIMODE_MATH
7694    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7695   "mul{b}\t%2"
7696   [(set_attr "type" "imul")
7697    (set_attr "length_immediate" "0")
7698    (set (attr "athlon_decode")
7699      (if_then_else (eq_attr "cpu" "athlon")
7700         (const_string "vector")
7701         (const_string "direct")))
7702    (set_attr "amdfam10_decode" "direct")
7703    (set_attr "mode" "QI")])
7704
7705 (define_expand "mulqihi3"
7706   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7707                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7708                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7709               (clobber (reg:CC FLAGS_REG))])]
7710   "TARGET_QIMODE_MATH"
7711   "")
7712
7713 (define_insn "*mulqihi3_insn"
7714   [(set (match_operand:HI 0 "register_operand" "=a")
7715         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7716                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7717    (clobber (reg:CC FLAGS_REG))]
7718   "TARGET_QIMODE_MATH
7719    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7720   "imul{b}\t%2"
7721   [(set_attr "type" "imul")
7722    (set_attr "length_immediate" "0")
7723    (set (attr "athlon_decode")
7724      (if_then_else (eq_attr "cpu" "athlon")
7725         (const_string "vector")
7726         (const_string "direct")))
7727    (set_attr "amdfam10_decode" "direct")
7728    (set_attr "mode" "QI")])
7729
7730 (define_expand "umulditi3"
7731   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7732                    (mult:TI (zero_extend:TI
7733                               (match_operand:DI 1 "nonimmediate_operand" ""))
7734                             (zero_extend:TI
7735                               (match_operand:DI 2 "register_operand" ""))))
7736               (clobber (reg:CC FLAGS_REG))])]
7737   "TARGET_64BIT"
7738   "")
7739
7740 (define_insn "*umulditi3_insn"
7741   [(set (match_operand:TI 0 "register_operand" "=A")
7742         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7743                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7744    (clobber (reg:CC FLAGS_REG))]
7745   "TARGET_64BIT
7746    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7747   "mul{q}\t%2"
7748   [(set_attr "type" "imul")
7749    (set_attr "length_immediate" "0")
7750    (set (attr "athlon_decode")
7751      (if_then_else (eq_attr "cpu" "athlon")
7752         (const_string "vector")
7753         (const_string "double")))
7754    (set_attr "amdfam10_decode" "double")
7755    (set_attr "mode" "DI")])
7756
7757 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7758 (define_expand "umulsidi3"
7759   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7760                    (mult:DI (zero_extend:DI
7761                               (match_operand:SI 1 "nonimmediate_operand" ""))
7762                             (zero_extend:DI
7763                               (match_operand:SI 2 "register_operand" ""))))
7764               (clobber (reg:CC FLAGS_REG))])]
7765   "!TARGET_64BIT"
7766   "")
7767
7768 (define_insn "*umulsidi3_insn"
7769   [(set (match_operand:DI 0 "register_operand" "=A")
7770         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7771                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "!TARGET_64BIT
7774    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775   "mul{l}\t%2"
7776   [(set_attr "type" "imul")
7777    (set_attr "length_immediate" "0")
7778    (set (attr "athlon_decode")
7779      (if_then_else (eq_attr "cpu" "athlon")
7780         (const_string "vector")
7781         (const_string "double")))
7782    (set_attr "amdfam10_decode" "double")
7783    (set_attr "mode" "SI")])
7784
7785 (define_expand "mulditi3"
7786   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7787                    (mult:TI (sign_extend:TI
7788                               (match_operand:DI 1 "nonimmediate_operand" ""))
7789                             (sign_extend:TI
7790                               (match_operand:DI 2 "register_operand" ""))))
7791               (clobber (reg:CC FLAGS_REG))])]
7792   "TARGET_64BIT"
7793   "")
7794
7795 (define_insn "*mulditi3_insn"
7796   [(set (match_operand:TI 0 "register_operand" "=A")
7797         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7798                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT
7801    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7802   "imul{q}\t%2"
7803   [(set_attr "type" "imul")
7804    (set_attr "length_immediate" "0")
7805    (set (attr "athlon_decode")
7806      (if_then_else (eq_attr "cpu" "athlon")
7807         (const_string "vector")
7808         (const_string "double")))
7809    (set_attr "amdfam10_decode" "double")
7810    (set_attr "mode" "DI")])
7811
7812 (define_expand "mulsidi3"
7813   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7814                    (mult:DI (sign_extend:DI
7815                               (match_operand:SI 1 "nonimmediate_operand" ""))
7816                             (sign_extend:DI
7817                               (match_operand:SI 2 "register_operand" ""))))
7818               (clobber (reg:CC FLAGS_REG))])]
7819   "!TARGET_64BIT"
7820   "")
7821
7822 (define_insn "*mulsidi3_insn"
7823   [(set (match_operand:DI 0 "register_operand" "=A")
7824         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7825                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "!TARGET_64BIT
7828    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7829   "imul{l}\t%2"
7830   [(set_attr "type" "imul")
7831    (set_attr "length_immediate" "0")
7832    (set (attr "athlon_decode")
7833      (if_then_else (eq_attr "cpu" "athlon")
7834         (const_string "vector")
7835         (const_string "double")))
7836    (set_attr "amdfam10_decode" "double")
7837    (set_attr "mode" "SI")])
7838
7839 (define_expand "umuldi3_highpart"
7840   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7841                    (truncate:DI
7842                      (lshiftrt:TI
7843                        (mult:TI (zero_extend:TI
7844                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7845                                 (zero_extend:TI
7846                                   (match_operand:DI 2 "register_operand" "")))
7847                        (const_int 64))))
7848               (clobber (match_scratch:DI 3 ""))
7849               (clobber (reg:CC FLAGS_REG))])]
7850   "TARGET_64BIT"
7851   "")
7852
7853 (define_insn "*umuldi3_highpart_rex64"
7854   [(set (match_operand:DI 0 "register_operand" "=d")
7855         (truncate:DI
7856           (lshiftrt:TI
7857             (mult:TI (zero_extend:TI
7858                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7859                      (zero_extend:TI
7860                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7861             (const_int 64))))
7862    (clobber (match_scratch:DI 3 "=1"))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "TARGET_64BIT
7865    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7866   "mul{q}\t%2"
7867   [(set_attr "type" "imul")
7868    (set_attr "length_immediate" "0")
7869    (set (attr "athlon_decode")
7870      (if_then_else (eq_attr "cpu" "athlon")
7871         (const_string "vector")
7872         (const_string "double")))
7873    (set_attr "amdfam10_decode" "double")
7874    (set_attr "mode" "DI")])
7875
7876 (define_expand "umulsi3_highpart"
7877   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7878                    (truncate:SI
7879                      (lshiftrt:DI
7880                        (mult:DI (zero_extend:DI
7881                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7882                                 (zero_extend:DI
7883                                   (match_operand:SI 2 "register_operand" "")))
7884                        (const_int 32))))
7885               (clobber (match_scratch:SI 3 ""))
7886               (clobber (reg:CC FLAGS_REG))])]
7887   ""
7888   "")
7889
7890 (define_insn "*umulsi3_highpart_insn"
7891   [(set (match_operand:SI 0 "register_operand" "=d")
7892         (truncate:SI
7893           (lshiftrt:DI
7894             (mult:DI (zero_extend:DI
7895                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7896                      (zero_extend:DI
7897                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7898             (const_int 32))))
7899    (clobber (match_scratch:SI 3 "=1"))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7902   "mul{l}\t%2"
7903   [(set_attr "type" "imul")
7904    (set_attr "length_immediate" "0")
7905    (set (attr "athlon_decode")
7906      (if_then_else (eq_attr "cpu" "athlon")
7907         (const_string "vector")
7908         (const_string "double")))
7909    (set_attr "amdfam10_decode" "double")
7910    (set_attr "mode" "SI")])
7911
7912 (define_insn "*umulsi3_highpart_zext"
7913   [(set (match_operand:DI 0 "register_operand" "=d")
7914         (zero_extend:DI (truncate:SI
7915           (lshiftrt:DI
7916             (mult:DI (zero_extend:DI
7917                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7918                      (zero_extend:DI
7919                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7920             (const_int 32)))))
7921    (clobber (match_scratch:SI 3 "=1"))
7922    (clobber (reg:CC FLAGS_REG))]
7923   "TARGET_64BIT
7924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925   "mul{l}\t%2"
7926   [(set_attr "type" "imul")
7927    (set_attr "length_immediate" "0")
7928    (set (attr "athlon_decode")
7929      (if_then_else (eq_attr "cpu" "athlon")
7930         (const_string "vector")
7931         (const_string "double")))
7932    (set_attr "amdfam10_decode" "double")
7933    (set_attr "mode" "SI")])
7934
7935 (define_expand "smuldi3_highpart"
7936   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7937                    (truncate:DI
7938                      (lshiftrt:TI
7939                        (mult:TI (sign_extend:TI
7940                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7941                                 (sign_extend:TI
7942                                   (match_operand:DI 2 "register_operand" "")))
7943                        (const_int 64))))
7944               (clobber (match_scratch:DI 3 ""))
7945               (clobber (reg:CC FLAGS_REG))])]
7946   "TARGET_64BIT"
7947   "")
7948
7949 (define_insn "*smuldi3_highpart_rex64"
7950   [(set (match_operand:DI 0 "register_operand" "=d")
7951         (truncate:DI
7952           (lshiftrt:TI
7953             (mult:TI (sign_extend:TI
7954                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7955                      (sign_extend:TI
7956                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7957             (const_int 64))))
7958    (clobber (match_scratch:DI 3 "=1"))
7959    (clobber (reg:CC FLAGS_REG))]
7960   "TARGET_64BIT
7961    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7962   "imul{q}\t%2"
7963   [(set_attr "type" "imul")
7964    (set (attr "athlon_decode")
7965      (if_then_else (eq_attr "cpu" "athlon")
7966         (const_string "vector")
7967         (const_string "double")))
7968    (set_attr "amdfam10_decode" "double")
7969    (set_attr "mode" "DI")])
7970
7971 (define_expand "smulsi3_highpart"
7972   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7973                    (truncate:SI
7974                      (lshiftrt:DI
7975                        (mult:DI (sign_extend:DI
7976                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7977                                 (sign_extend:DI
7978                                   (match_operand:SI 2 "register_operand" "")))
7979                        (const_int 32))))
7980               (clobber (match_scratch:SI 3 ""))
7981               (clobber (reg:CC FLAGS_REG))])]
7982   ""
7983   "")
7984
7985 (define_insn "*smulsi3_highpart_insn"
7986   [(set (match_operand:SI 0 "register_operand" "=d")
7987         (truncate:SI
7988           (lshiftrt:DI
7989             (mult:DI (sign_extend:DI
7990                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7991                      (sign_extend:DI
7992                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7993             (const_int 32))))
7994    (clobber (match_scratch:SI 3 "=1"))
7995    (clobber (reg:CC FLAGS_REG))]
7996   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7997   "imul{l}\t%2"
7998   [(set_attr "type" "imul")
7999    (set (attr "athlon_decode")
8000      (if_then_else (eq_attr "cpu" "athlon")
8001         (const_string "vector")
8002         (const_string "double")))
8003    (set_attr "amdfam10_decode" "double")
8004    (set_attr "mode" "SI")])
8005
8006 (define_insn "*smulsi3_highpart_zext"
8007   [(set (match_operand:DI 0 "register_operand" "=d")
8008         (zero_extend:DI (truncate:SI
8009           (lshiftrt:DI
8010             (mult:DI (sign_extend:DI
8011                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8012                      (sign_extend:DI
8013                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8014             (const_int 32)))))
8015    (clobber (match_scratch:SI 3 "=1"))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "TARGET_64BIT
8018    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8019   "imul{l}\t%2"
8020   [(set_attr "type" "imul")
8021    (set (attr "athlon_decode")
8022      (if_then_else (eq_attr "cpu" "athlon")
8023         (const_string "vector")
8024         (const_string "double")))
8025    (set_attr "amdfam10_decode" "double")
8026    (set_attr "mode" "SI")])
8027
8028 ;; The patterns that match these are at the end of this file.
8029
8030 (define_expand "mulxf3"
8031   [(set (match_operand:XF 0 "register_operand" "")
8032         (mult:XF (match_operand:XF 1 "register_operand" "")
8033                  (match_operand:XF 2 "register_operand" "")))]
8034   "TARGET_80387"
8035   "")
8036
8037 (define_expand "mul<mode>3"
8038   [(set (match_operand:MODEF 0 "register_operand" "")
8039         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8040                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8041   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8042   "")
8043
8044 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8045
8046 \f
8047 ;; Divide instructions
8048
8049 (define_insn "divqi3"
8050   [(set (match_operand:QI 0 "register_operand" "=a")
8051         (div:QI (match_operand:HI 1 "register_operand" "0")
8052                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8053    (clobber (reg:CC FLAGS_REG))]
8054   "TARGET_QIMODE_MATH"
8055   "idiv{b}\t%2"
8056   [(set_attr "type" "idiv")
8057    (set_attr "mode" "QI")])
8058
8059 (define_insn "udivqi3"
8060   [(set (match_operand:QI 0 "register_operand" "=a")
8061         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8062                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_QIMODE_MATH"
8065   "div{b}\t%2"
8066   [(set_attr "type" "idiv")
8067    (set_attr "mode" "QI")])
8068
8069 ;; The patterns that match these are at the end of this file.
8070
8071 (define_expand "divxf3"
8072   [(set (match_operand:XF 0 "register_operand" "")
8073         (div:XF (match_operand:XF 1 "register_operand" "")
8074                 (match_operand:XF 2 "register_operand" "")))]
8075   "TARGET_80387"
8076   "")
8077
8078 (define_expand "divdf3"
8079   [(set (match_operand:DF 0 "register_operand" "")
8080         (div:DF (match_operand:DF 1 "register_operand" "")
8081                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8082    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8083    "")
8084
8085 (define_expand "divsf3"
8086   [(set (match_operand:SF 0 "register_operand" "")
8087         (div:SF (match_operand:SF 1 "register_operand" "")
8088                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8089   "TARGET_80387 || TARGET_SSE_MATH"
8090 {
8091   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8092       && flag_finite_math_only && !flag_trapping_math
8093       && flag_unsafe_math_optimizations)
8094     {
8095       ix86_emit_swdivsf (operands[0], operands[1],
8096                          operands[2], SFmode);
8097       DONE;
8098     }
8099 })
8100 \f
8101 ;; Remainder instructions.
8102
8103 (define_expand "divmoddi4"
8104   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8105                    (div:DI (match_operand:DI 1 "register_operand" "")
8106                            (match_operand:DI 2 "nonimmediate_operand" "")))
8107               (set (match_operand:DI 3 "register_operand" "")
8108                    (mod:DI (match_dup 1) (match_dup 2)))
8109               (clobber (reg:CC FLAGS_REG))])]
8110   "TARGET_64BIT"
8111   "")
8112
8113 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8114 ;; Penalize eax case slightly because it results in worse scheduling
8115 ;; of code.
8116 (define_insn "*divmoddi4_nocltd_rex64"
8117   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8118         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8119                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8120    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8121         (mod:DI (match_dup 2) (match_dup 3)))
8122    (clobber (reg:CC FLAGS_REG))]
8123   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8124   "#"
8125   [(set_attr "type" "multi")])
8126
8127 (define_insn "*divmoddi4_cltd_rex64"
8128   [(set (match_operand:DI 0 "register_operand" "=a")
8129         (div:DI (match_operand:DI 2 "register_operand" "a")
8130                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8131    (set (match_operand:DI 1 "register_operand" "=&d")
8132         (mod:DI (match_dup 2) (match_dup 3)))
8133    (clobber (reg:CC FLAGS_REG))]
8134   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8135   "#"
8136   [(set_attr "type" "multi")])
8137
8138 (define_insn "*divmoddi_noext_rex64"
8139   [(set (match_operand:DI 0 "register_operand" "=a")
8140         (div:DI (match_operand:DI 1 "register_operand" "0")
8141                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8142    (set (match_operand:DI 3 "register_operand" "=d")
8143         (mod:DI (match_dup 1) (match_dup 2)))
8144    (use (match_operand:DI 4 "register_operand" "3"))
8145    (clobber (reg:CC FLAGS_REG))]
8146   "TARGET_64BIT"
8147   "idiv{q}\t%2"
8148   [(set_attr "type" "idiv")
8149    (set_attr "mode" "DI")])
8150
8151 (define_split
8152   [(set (match_operand:DI 0 "register_operand" "")
8153         (div:DI (match_operand:DI 1 "register_operand" "")
8154                 (match_operand:DI 2 "nonimmediate_operand" "")))
8155    (set (match_operand:DI 3 "register_operand" "")
8156         (mod:DI (match_dup 1) (match_dup 2)))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "TARGET_64BIT && reload_completed"
8159   [(parallel [(set (match_dup 3)
8160                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8161               (clobber (reg:CC FLAGS_REG))])
8162    (parallel [(set (match_dup 0)
8163                    (div:DI (reg:DI 0) (match_dup 2)))
8164               (set (match_dup 3)
8165                    (mod:DI (reg:DI 0) (match_dup 2)))
8166               (use (match_dup 3))
8167               (clobber (reg:CC FLAGS_REG))])]
8168 {
8169   /* Avoid use of cltd in favor of a mov+shift.  */
8170   if (!TARGET_USE_CLTD && !optimize_size)
8171     {
8172       if (true_regnum (operands[1]))
8173         emit_move_insn (operands[0], operands[1]);
8174       else
8175         emit_move_insn (operands[3], operands[1]);
8176       operands[4] = operands[3];
8177     }
8178   else
8179     {
8180       gcc_assert (!true_regnum (operands[1]));
8181       operands[4] = operands[1];
8182     }
8183 })
8184
8185
8186 (define_expand "divmodsi4"
8187   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8188                    (div:SI (match_operand:SI 1 "register_operand" "")
8189                            (match_operand:SI 2 "nonimmediate_operand" "")))
8190               (set (match_operand:SI 3 "register_operand" "")
8191                    (mod:SI (match_dup 1) (match_dup 2)))
8192               (clobber (reg:CC FLAGS_REG))])]
8193   ""
8194   "")
8195
8196 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8197 ;; Penalize eax case slightly because it results in worse scheduling
8198 ;; of code.
8199 (define_insn "*divmodsi4_nocltd"
8200   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8201         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8202                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8203    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8204         (mod:SI (match_dup 2) (match_dup 3)))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "!optimize_size && !TARGET_USE_CLTD"
8207   "#"
8208   [(set_attr "type" "multi")])
8209
8210 (define_insn "*divmodsi4_cltd"
8211   [(set (match_operand:SI 0 "register_operand" "=a")
8212         (div:SI (match_operand:SI 2 "register_operand" "a")
8213                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8214    (set (match_operand:SI 1 "register_operand" "=&d")
8215         (mod:SI (match_dup 2) (match_dup 3)))
8216    (clobber (reg:CC FLAGS_REG))]
8217   "optimize_size || TARGET_USE_CLTD"
8218   "#"
8219   [(set_attr "type" "multi")])
8220
8221 (define_insn "*divmodsi_noext"
8222   [(set (match_operand:SI 0 "register_operand" "=a")
8223         (div:SI (match_operand:SI 1 "register_operand" "0")
8224                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8225    (set (match_operand:SI 3 "register_operand" "=d")
8226         (mod:SI (match_dup 1) (match_dup 2)))
8227    (use (match_operand:SI 4 "register_operand" "3"))
8228    (clobber (reg:CC FLAGS_REG))]
8229   ""
8230   "idiv{l}\t%2"
8231   [(set_attr "type" "idiv")
8232    (set_attr "mode" "SI")])
8233
8234 (define_split
8235   [(set (match_operand:SI 0 "register_operand" "")
8236         (div:SI (match_operand:SI 1 "register_operand" "")
8237                 (match_operand:SI 2 "nonimmediate_operand" "")))
8238    (set (match_operand:SI 3 "register_operand" "")
8239         (mod:SI (match_dup 1) (match_dup 2)))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "reload_completed"
8242   [(parallel [(set (match_dup 3)
8243                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8244               (clobber (reg:CC FLAGS_REG))])
8245    (parallel [(set (match_dup 0)
8246                    (div:SI (reg:SI 0) (match_dup 2)))
8247               (set (match_dup 3)
8248                    (mod:SI (reg:SI 0) (match_dup 2)))
8249               (use (match_dup 3))
8250               (clobber (reg:CC FLAGS_REG))])]
8251 {
8252   /* Avoid use of cltd in favor of a mov+shift.  */
8253   if (!TARGET_USE_CLTD && !optimize_size)
8254     {
8255       if (true_regnum (operands[1]))
8256         emit_move_insn (operands[0], operands[1]);
8257       else
8258         emit_move_insn (operands[3], operands[1]);
8259       operands[4] = operands[3];
8260     }
8261   else
8262     {
8263       gcc_assert (!true_regnum (operands[1]));
8264       operands[4] = operands[1];
8265     }
8266 })
8267 ;; %%% Split me.
8268 (define_insn "divmodhi4"
8269   [(set (match_operand:HI 0 "register_operand" "=a")
8270         (div:HI (match_operand:HI 1 "register_operand" "0")
8271                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8272    (set (match_operand:HI 3 "register_operand" "=&d")
8273         (mod:HI (match_dup 1) (match_dup 2)))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_HIMODE_MATH"
8276   "cwtd\;idiv{w}\t%2"
8277   [(set_attr "type" "multi")
8278    (set_attr "length_immediate" "0")
8279    (set_attr "mode" "SI")])
8280
8281 (define_insn "udivmoddi4"
8282   [(set (match_operand:DI 0 "register_operand" "=a")
8283         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8284                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8285    (set (match_operand:DI 3 "register_operand" "=&d")
8286         (umod:DI (match_dup 1) (match_dup 2)))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_64BIT"
8289   "xor{q}\t%3, %3\;div{q}\t%2"
8290   [(set_attr "type" "multi")
8291    (set_attr "length_immediate" "0")
8292    (set_attr "mode" "DI")])
8293
8294 (define_insn "*udivmoddi4_noext"
8295   [(set (match_operand:DI 0 "register_operand" "=a")
8296         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8297                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8298    (set (match_operand:DI 3 "register_operand" "=d")
8299         (umod:DI (match_dup 1) (match_dup 2)))
8300    (use (match_dup 3))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "TARGET_64BIT"
8303   "div{q}\t%2"
8304   [(set_attr "type" "idiv")
8305    (set_attr "mode" "DI")])
8306
8307 (define_split
8308   [(set (match_operand:DI 0 "register_operand" "")
8309         (udiv:DI (match_operand:DI 1 "register_operand" "")
8310                  (match_operand:DI 2 "nonimmediate_operand" "")))
8311    (set (match_operand:DI 3 "register_operand" "")
8312         (umod:DI (match_dup 1) (match_dup 2)))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "TARGET_64BIT && reload_completed"
8315   [(set (match_dup 3) (const_int 0))
8316    (parallel [(set (match_dup 0)
8317                    (udiv:DI (match_dup 1) (match_dup 2)))
8318               (set (match_dup 3)
8319                    (umod:DI (match_dup 1) (match_dup 2)))
8320               (use (match_dup 3))
8321               (clobber (reg:CC FLAGS_REG))])]
8322   "")
8323
8324 (define_insn "udivmodsi4"
8325   [(set (match_operand:SI 0 "register_operand" "=a")
8326         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8327                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8328    (set (match_operand:SI 3 "register_operand" "=&d")
8329         (umod:SI (match_dup 1) (match_dup 2)))
8330    (clobber (reg:CC FLAGS_REG))]
8331   ""
8332   "xor{l}\t%3, %3\;div{l}\t%2"
8333   [(set_attr "type" "multi")
8334    (set_attr "length_immediate" "0")
8335    (set_attr "mode" "SI")])
8336
8337 (define_insn "*udivmodsi4_noext"
8338   [(set (match_operand:SI 0 "register_operand" "=a")
8339         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8340                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8341    (set (match_operand:SI 3 "register_operand" "=d")
8342         (umod:SI (match_dup 1) (match_dup 2)))
8343    (use (match_dup 3))
8344    (clobber (reg:CC FLAGS_REG))]
8345   ""
8346   "div{l}\t%2"
8347   [(set_attr "type" "idiv")
8348    (set_attr "mode" "SI")])
8349
8350 (define_split
8351   [(set (match_operand:SI 0 "register_operand" "")
8352         (udiv:SI (match_operand:SI 1 "register_operand" "")
8353                  (match_operand:SI 2 "nonimmediate_operand" "")))
8354    (set (match_operand:SI 3 "register_operand" "")
8355         (umod:SI (match_dup 1) (match_dup 2)))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "reload_completed"
8358   [(set (match_dup 3) (const_int 0))
8359    (parallel [(set (match_dup 0)
8360                    (udiv:SI (match_dup 1) (match_dup 2)))
8361               (set (match_dup 3)
8362                    (umod:SI (match_dup 1) (match_dup 2)))
8363               (use (match_dup 3))
8364               (clobber (reg:CC FLAGS_REG))])]
8365   "")
8366
8367 (define_expand "udivmodhi4"
8368   [(set (match_dup 4) (const_int 0))
8369    (parallel [(set (match_operand:HI 0 "register_operand" "")
8370                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8371                             (match_operand:HI 2 "nonimmediate_operand" "")))
8372               (set (match_operand:HI 3 "register_operand" "")
8373                    (umod:HI (match_dup 1) (match_dup 2)))
8374               (use (match_dup 4))
8375               (clobber (reg:CC FLAGS_REG))])]
8376   "TARGET_HIMODE_MATH"
8377   "operands[4] = gen_reg_rtx (HImode);")
8378
8379 (define_insn "*udivmodhi_noext"
8380   [(set (match_operand:HI 0 "register_operand" "=a")
8381         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8382                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8383    (set (match_operand:HI 3 "register_operand" "=d")
8384         (umod:HI (match_dup 1) (match_dup 2)))
8385    (use (match_operand:HI 4 "register_operand" "3"))
8386    (clobber (reg:CC FLAGS_REG))]
8387   ""
8388   "div{w}\t%2"
8389   [(set_attr "type" "idiv")
8390    (set_attr "mode" "HI")])
8391
8392 ;; We cannot use div/idiv for double division, because it causes
8393 ;; "division by zero" on the overflow and that's not what we expect
8394 ;; from truncate.  Because true (non truncating) double division is
8395 ;; never generated, we can't create this insn anyway.
8396 ;
8397 ;(define_insn ""
8398 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8399 ;       (truncate:SI
8400 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8401 ;                  (zero_extend:DI
8402 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8403 ;   (set (match_operand:SI 3 "register_operand" "=d")
8404 ;       (truncate:SI
8405 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8406 ;   (clobber (reg:CC FLAGS_REG))]
8407 ;  ""
8408 ;  "div{l}\t{%2, %0|%0, %2}"
8409 ;  [(set_attr "type" "idiv")])
8410 \f
8411 ;;- Logical AND instructions
8412
8413 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8414 ;; Note that this excludes ah.
8415
8416 (define_insn "*testdi_1_rex64"
8417   [(set (reg FLAGS_REG)
8418         (compare
8419           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8420                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8421           (const_int 0)))]
8422   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8423    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8424   "@
8425    test{l}\t{%k1, %k0|%k0, %k1}
8426    test{l}\t{%k1, %k0|%k0, %k1}
8427    test{q}\t{%1, %0|%0, %1}
8428    test{q}\t{%1, %0|%0, %1}
8429    test{q}\t{%1, %0|%0, %1}"
8430   [(set_attr "type" "test")
8431    (set_attr "modrm" "0,1,0,1,1")
8432    (set_attr "mode" "SI,SI,DI,DI,DI")
8433    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8434
8435 (define_insn "testsi_1"
8436   [(set (reg FLAGS_REG)
8437         (compare
8438           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8439                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8440           (const_int 0)))]
8441   "ix86_match_ccmode (insn, CCNOmode)
8442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8443   "test{l}\t{%1, %0|%0, %1}"
8444   [(set_attr "type" "test")
8445    (set_attr "modrm" "0,1,1")
8446    (set_attr "mode" "SI")
8447    (set_attr "pent_pair" "uv,np,uv")])
8448
8449 (define_expand "testsi_ccno_1"
8450   [(set (reg:CCNO FLAGS_REG)
8451         (compare:CCNO
8452           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8453                   (match_operand:SI 1 "nonmemory_operand" ""))
8454           (const_int 0)))]
8455   ""
8456   "")
8457
8458 (define_insn "*testhi_1"
8459   [(set (reg FLAGS_REG)
8460         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8461                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8462                  (const_int 0)))]
8463   "ix86_match_ccmode (insn, CCNOmode)
8464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8465   "test{w}\t{%1, %0|%0, %1}"
8466   [(set_attr "type" "test")
8467    (set_attr "modrm" "0,1,1")
8468    (set_attr "mode" "HI")
8469    (set_attr "pent_pair" "uv,np,uv")])
8470
8471 (define_expand "testqi_ccz_1"
8472   [(set (reg:CCZ FLAGS_REG)
8473         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8474                              (match_operand:QI 1 "nonmemory_operand" ""))
8475                  (const_int 0)))]
8476   ""
8477   "")
8478
8479 (define_insn "*testqi_1_maybe_si"
8480   [(set (reg FLAGS_REG)
8481         (compare
8482           (and:QI
8483             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8484             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8485           (const_int 0)))]
8486    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8487     && ix86_match_ccmode (insn,
8488                          CONST_INT_P (operands[1])
8489                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8490 {
8491   if (which_alternative == 3)
8492     {
8493       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8494         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8495       return "test{l}\t{%1, %k0|%k0, %1}";
8496     }
8497   return "test{b}\t{%1, %0|%0, %1}";
8498 }
8499   [(set_attr "type" "test")
8500    (set_attr "modrm" "0,1,1,1")
8501    (set_attr "mode" "QI,QI,QI,SI")
8502    (set_attr "pent_pair" "uv,np,uv,np")])
8503
8504 (define_insn "*testqi_1"
8505   [(set (reg FLAGS_REG)
8506         (compare
8507           (and:QI
8508             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8509             (match_operand:QI 1 "general_operand" "n,n,qn"))
8510           (const_int 0)))]
8511   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8512    && ix86_match_ccmode (insn, CCNOmode)"
8513   "test{b}\t{%1, %0|%0, %1}"
8514   [(set_attr "type" "test")
8515    (set_attr "modrm" "0,1,1")
8516    (set_attr "mode" "QI")
8517    (set_attr "pent_pair" "uv,np,uv")])
8518
8519 (define_expand "testqi_ext_ccno_0"
8520   [(set (reg:CCNO FLAGS_REG)
8521         (compare:CCNO
8522           (and:SI
8523             (zero_extract:SI
8524               (match_operand 0 "ext_register_operand" "")
8525               (const_int 8)
8526               (const_int 8))
8527             (match_operand 1 "const_int_operand" ""))
8528           (const_int 0)))]
8529   ""
8530   "")
8531
8532 (define_insn "*testqi_ext_0"
8533   [(set (reg FLAGS_REG)
8534         (compare
8535           (and:SI
8536             (zero_extract:SI
8537               (match_operand 0 "ext_register_operand" "Q")
8538               (const_int 8)
8539               (const_int 8))
8540             (match_operand 1 "const_int_operand" "n"))
8541           (const_int 0)))]
8542   "ix86_match_ccmode (insn, CCNOmode)"
8543   "test{b}\t{%1, %h0|%h0, %1}"
8544   [(set_attr "type" "test")
8545    (set_attr "mode" "QI")
8546    (set_attr "length_immediate" "1")
8547    (set_attr "pent_pair" "np")])
8548
8549 (define_insn "*testqi_ext_1"
8550   [(set (reg FLAGS_REG)
8551         (compare
8552           (and:SI
8553             (zero_extract:SI
8554               (match_operand 0 "ext_register_operand" "Q")
8555               (const_int 8)
8556               (const_int 8))
8557             (zero_extend:SI
8558               (match_operand:QI 1 "general_operand" "Qm")))
8559           (const_int 0)))]
8560   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8561    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562   "test{b}\t{%1, %h0|%h0, %1}"
8563   [(set_attr "type" "test")
8564    (set_attr "mode" "QI")])
8565
8566 (define_insn "*testqi_ext_1_rex64"
8567   [(set (reg FLAGS_REG)
8568         (compare
8569           (and:SI
8570             (zero_extract:SI
8571               (match_operand 0 "ext_register_operand" "Q")
8572               (const_int 8)
8573               (const_int 8))
8574             (zero_extend:SI
8575               (match_operand:QI 1 "register_operand" "Q")))
8576           (const_int 0)))]
8577   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8578   "test{b}\t{%1, %h0|%h0, %1}"
8579   [(set_attr "type" "test")
8580    (set_attr "mode" "QI")])
8581
8582 (define_insn "*testqi_ext_2"
8583   [(set (reg FLAGS_REG)
8584         (compare
8585           (and:SI
8586             (zero_extract:SI
8587               (match_operand 0 "ext_register_operand" "Q")
8588               (const_int 8)
8589               (const_int 8))
8590             (zero_extract:SI
8591               (match_operand 1 "ext_register_operand" "Q")
8592               (const_int 8)
8593               (const_int 8)))
8594           (const_int 0)))]
8595   "ix86_match_ccmode (insn, CCNOmode)"
8596   "test{b}\t{%h1, %h0|%h0, %h1}"
8597   [(set_attr "type" "test")
8598    (set_attr "mode" "QI")])
8599
8600 ;; Combine likes to form bit extractions for some tests.  Humor it.
8601 (define_insn "*testqi_ext_3"
8602   [(set (reg FLAGS_REG)
8603         (compare (zero_extract:SI
8604                    (match_operand 0 "nonimmediate_operand" "rm")
8605                    (match_operand:SI 1 "const_int_operand" "")
8606                    (match_operand:SI 2 "const_int_operand" ""))
8607                  (const_int 0)))]
8608   "ix86_match_ccmode (insn, CCNOmode)
8609    && INTVAL (operands[1]) > 0
8610    && INTVAL (operands[2]) >= 0
8611    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8612    && (GET_MODE (operands[0]) == SImode
8613        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8614        || GET_MODE (operands[0]) == HImode
8615        || GET_MODE (operands[0]) == QImode)"
8616   "#")
8617
8618 (define_insn "*testqi_ext_3_rex64"
8619   [(set (reg FLAGS_REG)
8620         (compare (zero_extract:DI
8621                    (match_operand 0 "nonimmediate_operand" "rm")
8622                    (match_operand:DI 1 "const_int_operand" "")
8623                    (match_operand:DI 2 "const_int_operand" ""))
8624                  (const_int 0)))]
8625   "TARGET_64BIT
8626    && ix86_match_ccmode (insn, CCNOmode)
8627    && INTVAL (operands[1]) > 0
8628    && INTVAL (operands[2]) >= 0
8629    /* Ensure that resulting mask is zero or sign extended operand.  */
8630    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8631        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8632            && INTVAL (operands[1]) > 32))
8633    && (GET_MODE (operands[0]) == SImode
8634        || GET_MODE (operands[0]) == DImode
8635        || GET_MODE (operands[0]) == HImode
8636        || GET_MODE (operands[0]) == QImode)"
8637   "#")
8638
8639 (define_split
8640   [(set (match_operand 0 "flags_reg_operand" "")
8641         (match_operator 1 "compare_operator"
8642           [(zero_extract
8643              (match_operand 2 "nonimmediate_operand" "")
8644              (match_operand 3 "const_int_operand" "")
8645              (match_operand 4 "const_int_operand" ""))
8646            (const_int 0)]))]
8647   "ix86_match_ccmode (insn, CCNOmode)"
8648   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8649 {
8650   rtx val = operands[2];
8651   HOST_WIDE_INT len = INTVAL (operands[3]);
8652   HOST_WIDE_INT pos = INTVAL (operands[4]);
8653   HOST_WIDE_INT mask;
8654   enum machine_mode mode, submode;
8655
8656   mode = GET_MODE (val);
8657   if (MEM_P (val))
8658     {
8659       /* ??? Combine likes to put non-volatile mem extractions in QImode
8660          no matter the size of the test.  So find a mode that works.  */
8661       if (! MEM_VOLATILE_P (val))
8662         {
8663           mode = smallest_mode_for_size (pos + len, MODE_INT);
8664           val = adjust_address (val, mode, 0);
8665         }
8666     }
8667   else if (GET_CODE (val) == SUBREG
8668            && (submode = GET_MODE (SUBREG_REG (val)),
8669                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8670            && pos + len <= GET_MODE_BITSIZE (submode))
8671     {
8672       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8673       mode = submode;
8674       val = SUBREG_REG (val);
8675     }
8676   else if (mode == HImode && pos + len <= 8)
8677     {
8678       /* Small HImode tests can be converted to QImode.  */
8679       mode = QImode;
8680       val = gen_lowpart (QImode, val);
8681     }
8682
8683   if (len == HOST_BITS_PER_WIDE_INT)
8684     mask = -1;
8685   else
8686     mask = ((HOST_WIDE_INT)1 << len) - 1;
8687   mask <<= pos;
8688
8689   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8690 })
8691
8692 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8693 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8694 ;; this is relatively important trick.
8695 ;; Do the conversion only post-reload to avoid limiting of the register class
8696 ;; to QI regs.
8697 (define_split
8698   [(set (match_operand 0 "flags_reg_operand" "")
8699         (match_operator 1 "compare_operator"
8700           [(and (match_operand 2 "register_operand" "")
8701                 (match_operand 3 "const_int_operand" ""))
8702            (const_int 0)]))]
8703    "reload_completed
8704     && QI_REG_P (operands[2])
8705     && GET_MODE (operands[2]) != QImode
8706     && ((ix86_match_ccmode (insn, CCZmode)
8707          && !(INTVAL (operands[3]) & ~(255 << 8)))
8708         || (ix86_match_ccmode (insn, CCNOmode)
8709             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8710   [(set (match_dup 0)
8711         (match_op_dup 1
8712           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8713                    (match_dup 3))
8714            (const_int 0)]))]
8715   "operands[2] = gen_lowpart (SImode, operands[2]);
8716    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8717
8718 (define_split
8719   [(set (match_operand 0 "flags_reg_operand" "")
8720         (match_operator 1 "compare_operator"
8721           [(and (match_operand 2 "nonimmediate_operand" "")
8722                 (match_operand 3 "const_int_operand" ""))
8723            (const_int 0)]))]
8724    "reload_completed
8725     && GET_MODE (operands[2]) != QImode
8726     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8727     && ((ix86_match_ccmode (insn, CCZmode)
8728          && !(INTVAL (operands[3]) & ~255))
8729         || (ix86_match_ccmode (insn, CCNOmode)
8730             && !(INTVAL (operands[3]) & ~127)))"
8731   [(set (match_dup 0)
8732         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8733                          (const_int 0)]))]
8734   "operands[2] = gen_lowpart (QImode, operands[2]);
8735    operands[3] = gen_lowpart (QImode, operands[3]);")
8736
8737
8738 ;; %%% This used to optimize known byte-wide and operations to memory,
8739 ;; and sometimes to QImode registers.  If this is considered useful,
8740 ;; it should be done with splitters.
8741
8742 (define_expand "anddi3"
8743   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8744         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8745                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8746    (clobber (reg:CC FLAGS_REG))]
8747   "TARGET_64BIT"
8748   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8749
8750 (define_insn "*anddi_1_rex64"
8751   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8752         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8753                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8754    (clobber (reg:CC FLAGS_REG))]
8755   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8756 {
8757   switch (get_attr_type (insn))
8758     {
8759     case TYPE_IMOVX:
8760       {
8761         enum machine_mode mode;
8762
8763         gcc_assert (CONST_INT_P (operands[2]));
8764         if (INTVAL (operands[2]) == 0xff)
8765           mode = QImode;
8766         else
8767           {
8768             gcc_assert (INTVAL (operands[2]) == 0xffff);
8769             mode = HImode;
8770           }
8771
8772         operands[1] = gen_lowpart (mode, operands[1]);
8773         if (mode == QImode)
8774           return "movz{bq|x}\t{%1,%0|%0, %1}";
8775         else
8776           return "movz{wq|x}\t{%1,%0|%0, %1}";
8777       }
8778
8779     default:
8780       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8781       if (get_attr_mode (insn) == MODE_SI)
8782         return "and{l}\t{%k2, %k0|%k0, %k2}";
8783       else
8784         return "and{q}\t{%2, %0|%0, %2}";
8785     }
8786 }
8787   [(set_attr "type" "alu,alu,alu,imovx")
8788    (set_attr "length_immediate" "*,*,*,0")
8789    (set_attr "mode" "SI,DI,DI,DI")])
8790
8791 (define_insn "*anddi_2"
8792   [(set (reg FLAGS_REG)
8793         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8794                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8795                  (const_int 0)))
8796    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8797         (and:DI (match_dup 1) (match_dup 2)))]
8798   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8799    && ix86_binary_operator_ok (AND, DImode, operands)"
8800   "@
8801    and{l}\t{%k2, %k0|%k0, %k2}
8802    and{q}\t{%2, %0|%0, %2}
8803    and{q}\t{%2, %0|%0, %2}"
8804   [(set_attr "type" "alu")
8805    (set_attr "mode" "SI,DI,DI")])
8806
8807 (define_expand "andsi3"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8809         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8810                 (match_operand:SI 2 "general_operand" "")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   ""
8813   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8814
8815 (define_insn "*andsi_1"
8816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8817         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8818                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8819    (clobber (reg:CC FLAGS_REG))]
8820   "ix86_binary_operator_ok (AND, SImode, operands)"
8821 {
8822   switch (get_attr_type (insn))
8823     {
8824     case TYPE_IMOVX:
8825       {
8826         enum machine_mode mode;
8827
8828         gcc_assert (CONST_INT_P (operands[2]));
8829         if (INTVAL (operands[2]) == 0xff)
8830           mode = QImode;
8831         else
8832           {
8833             gcc_assert (INTVAL (operands[2]) == 0xffff);
8834             mode = HImode;
8835           }
8836
8837         operands[1] = gen_lowpart (mode, operands[1]);
8838         if (mode == QImode)
8839           return "movz{bl|x}\t{%1,%0|%0, %1}";
8840         else
8841           return "movz{wl|x}\t{%1,%0|%0, %1}";
8842       }
8843
8844     default:
8845       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8846       return "and{l}\t{%2, %0|%0, %2}";
8847     }
8848 }
8849   [(set_attr "type" "alu,alu,imovx")
8850    (set_attr "length_immediate" "*,*,0")
8851    (set_attr "mode" "SI")])
8852
8853 (define_split
8854   [(set (match_operand 0 "register_operand" "")
8855         (and (match_dup 0)
8856              (const_int -65536)))
8857    (clobber (reg:CC FLAGS_REG))]
8858   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8859   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8860   "operands[1] = gen_lowpart (HImode, operands[0]);")
8861
8862 (define_split
8863   [(set (match_operand 0 "ext_register_operand" "")
8864         (and (match_dup 0)
8865              (const_int -256)))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8868   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8869   "operands[1] = gen_lowpart (QImode, operands[0]);")
8870
8871 (define_split
8872   [(set (match_operand 0 "ext_register_operand" "")
8873         (and (match_dup 0)
8874              (const_int -65281)))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8877   [(parallel [(set (zero_extract:SI (match_dup 0)
8878                                     (const_int 8)
8879                                     (const_int 8))
8880                    (xor:SI
8881                      (zero_extract:SI (match_dup 0)
8882                                       (const_int 8)
8883                                       (const_int 8))
8884                      (zero_extract:SI (match_dup 0)
8885                                       (const_int 8)
8886                                       (const_int 8))))
8887               (clobber (reg:CC FLAGS_REG))])]
8888   "operands[0] = gen_lowpart (SImode, operands[0]);")
8889
8890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8891 (define_insn "*andsi_1_zext"
8892   [(set (match_operand:DI 0 "register_operand" "=r")
8893         (zero_extend:DI
8894           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8895                   (match_operand:SI 2 "general_operand" "g"))))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8898   "and{l}\t{%2, %k0|%k0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "mode" "SI")])
8901
8902 (define_insn "*andsi_2"
8903   [(set (reg FLAGS_REG)
8904         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8905                          (match_operand:SI 2 "general_operand" "g,ri"))
8906                  (const_int 0)))
8907    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8908         (and:SI (match_dup 1) (match_dup 2)))]
8909   "ix86_match_ccmode (insn, CCNOmode)
8910    && ix86_binary_operator_ok (AND, SImode, operands)"
8911   "and{l}\t{%2, %0|%0, %2}"
8912   [(set_attr "type" "alu")
8913    (set_attr "mode" "SI")])
8914
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 (define_insn "*andsi_2_zext"
8917   [(set (reg FLAGS_REG)
8918         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8919                          (match_operand:SI 2 "general_operand" "g"))
8920                  (const_int 0)))
8921    (set (match_operand:DI 0 "register_operand" "=r")
8922         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8923   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8924    && ix86_binary_operator_ok (AND, SImode, operands)"
8925   "and{l}\t{%2, %k0|%k0, %2}"
8926   [(set_attr "type" "alu")
8927    (set_attr "mode" "SI")])
8928
8929 (define_expand "andhi3"
8930   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8931         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8932                 (match_operand:HI 2 "general_operand" "")))
8933    (clobber (reg:CC FLAGS_REG))]
8934   "TARGET_HIMODE_MATH"
8935   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8936
8937 (define_insn "*andhi_1"
8938   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8939         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8940                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "ix86_binary_operator_ok (AND, HImode, operands)"
8943 {
8944   switch (get_attr_type (insn))
8945     {
8946     case TYPE_IMOVX:
8947       gcc_assert (CONST_INT_P (operands[2]));
8948       gcc_assert (INTVAL (operands[2]) == 0xff);
8949       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8950
8951     default:
8952       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8953
8954       return "and{w}\t{%2, %0|%0, %2}";
8955     }
8956 }
8957   [(set_attr "type" "alu,alu,imovx")
8958    (set_attr "length_immediate" "*,*,0")
8959    (set_attr "mode" "HI,HI,SI")])
8960
8961 (define_insn "*andhi_2"
8962   [(set (reg FLAGS_REG)
8963         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8964                          (match_operand:HI 2 "general_operand" "g,ri"))
8965                  (const_int 0)))
8966    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8967         (and:HI (match_dup 1) (match_dup 2)))]
8968   "ix86_match_ccmode (insn, CCNOmode)
8969    && ix86_binary_operator_ok (AND, HImode, operands)"
8970   "and{w}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "HI")])
8973
8974 (define_expand "andqi3"
8975   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8976         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8977                 (match_operand:QI 2 "general_operand" "")))
8978    (clobber (reg:CC FLAGS_REG))]
8979   "TARGET_QIMODE_MATH"
8980   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8981
8982 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8983 (define_insn "*andqi_1"
8984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8985         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8986                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8987    (clobber (reg:CC FLAGS_REG))]
8988   "ix86_binary_operator_ok (AND, QImode, operands)"
8989   "@
8990    and{b}\t{%2, %0|%0, %2}
8991    and{b}\t{%2, %0|%0, %2}
8992    and{l}\t{%k2, %k0|%k0, %k2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "QI,QI,SI")])
8995
8996 (define_insn "*andqi_1_slp"
8997   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8998         (and:QI (match_dup 0)
8999                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9002    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9003   "and{b}\t{%1, %0|%0, %1}"
9004   [(set_attr "type" "alu1")
9005    (set_attr "mode" "QI")])
9006
9007 (define_insn "*andqi_2_maybe_si"
9008   [(set (reg FLAGS_REG)
9009         (compare (and:QI
9010                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9011                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9012                  (const_int 0)))
9013    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9014         (and:QI (match_dup 1) (match_dup 2)))]
9015   "ix86_binary_operator_ok (AND, QImode, operands)
9016    && ix86_match_ccmode (insn,
9017                          CONST_INT_P (operands[2])
9018                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9019 {
9020   if (which_alternative == 2)
9021     {
9022       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9023         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9024       return "and{l}\t{%2, %k0|%k0, %2}";
9025     }
9026   return "and{b}\t{%2, %0|%0, %2}";
9027 }
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "QI,QI,SI")])
9030
9031 (define_insn "*andqi_2"
9032   [(set (reg FLAGS_REG)
9033         (compare (and:QI
9034                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9035                    (match_operand:QI 2 "general_operand" "qim,qi"))
9036                  (const_int 0)))
9037    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9038         (and:QI (match_dup 1) (match_dup 2)))]
9039   "ix86_match_ccmode (insn, CCNOmode)
9040    && ix86_binary_operator_ok (AND, QImode, operands)"
9041   "and{b}\t{%2, %0|%0, %2}"
9042   [(set_attr "type" "alu")
9043    (set_attr "mode" "QI")])
9044
9045 (define_insn "*andqi_2_slp"
9046   [(set (reg FLAGS_REG)
9047         (compare (and:QI
9048                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9049                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9050                  (const_int 0)))
9051    (set (strict_low_part (match_dup 0))
9052         (and:QI (match_dup 0) (match_dup 1)))]
9053   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9054    && ix86_match_ccmode (insn, CCNOmode)
9055    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9056   "and{b}\t{%1, %0|%0, %1}"
9057   [(set_attr "type" "alu1")
9058    (set_attr "mode" "QI")])
9059
9060 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9061 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9062 ;; for a QImode operand, which of course failed.
9063
9064 (define_insn "andqi_ext_0"
9065   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9066                          (const_int 8)
9067                          (const_int 8))
9068         (and:SI
9069           (zero_extract:SI
9070             (match_operand 1 "ext_register_operand" "0")
9071             (const_int 8)
9072             (const_int 8))
9073           (match_operand 2 "const_int_operand" "n")))
9074    (clobber (reg:CC FLAGS_REG))]
9075   ""
9076   "and{b}\t{%2, %h0|%h0, %2}"
9077   [(set_attr "type" "alu")
9078    (set_attr "length_immediate" "1")
9079    (set_attr "mode" "QI")])
9080
9081 ;; Generated by peephole translating test to and.  This shows up
9082 ;; often in fp comparisons.
9083
9084 (define_insn "*andqi_ext_0_cc"
9085   [(set (reg FLAGS_REG)
9086         (compare
9087           (and:SI
9088             (zero_extract:SI
9089               (match_operand 1 "ext_register_operand" "0")
9090               (const_int 8)
9091               (const_int 8))
9092             (match_operand 2 "const_int_operand" "n"))
9093           (const_int 0)))
9094    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9095                          (const_int 8)
9096                          (const_int 8))
9097         (and:SI
9098           (zero_extract:SI
9099             (match_dup 1)
9100             (const_int 8)
9101             (const_int 8))
9102           (match_dup 2)))]
9103   "ix86_match_ccmode (insn, CCNOmode)"
9104   "and{b}\t{%2, %h0|%h0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "length_immediate" "1")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "*andqi_ext_1"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (and:SI
9114           (zero_extract:SI
9115             (match_operand 1 "ext_register_operand" "0")
9116             (const_int 8)
9117             (const_int 8))
9118           (zero_extend:SI
9119             (match_operand:QI 2 "general_operand" "Qm"))))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "!TARGET_64BIT"
9122   "and{b}\t{%2, %h0|%h0, %2}"
9123   [(set_attr "type" "alu")
9124    (set_attr "length_immediate" "0")
9125    (set_attr "mode" "QI")])
9126
9127 (define_insn "*andqi_ext_1_rex64"
9128   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129                          (const_int 8)
9130                          (const_int 8))
9131         (and:SI
9132           (zero_extract:SI
9133             (match_operand 1 "ext_register_operand" "0")
9134             (const_int 8)
9135             (const_int 8))
9136           (zero_extend:SI
9137             (match_operand 2 "ext_register_operand" "Q"))))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "TARGET_64BIT"
9140   "and{b}\t{%2, %h0|%h0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9144
9145 (define_insn "*andqi_ext_2"
9146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147                          (const_int 8)
9148                          (const_int 8))
9149         (and:SI
9150           (zero_extract:SI
9151             (match_operand 1 "ext_register_operand" "%0")
9152             (const_int 8)
9153             (const_int 8))
9154           (zero_extract:SI
9155             (match_operand 2 "ext_register_operand" "Q")
9156             (const_int 8)
9157             (const_int 8))))
9158    (clobber (reg:CC FLAGS_REG))]
9159   ""
9160   "and{b}\t{%h2, %h0|%h0, %h2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "length_immediate" "0")
9163    (set_attr "mode" "QI")])
9164
9165 ;; Convert wide AND instructions with immediate operand to shorter QImode
9166 ;; equivalents when possible.
9167 ;; Don't do the splitting with memory operands, since it introduces risk
9168 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9169 ;; for size, but that can (should?) be handled by generic code instead.
9170 (define_split
9171   [(set (match_operand 0 "register_operand" "")
9172         (and (match_operand 1 "register_operand" "")
9173              (match_operand 2 "const_int_operand" "")))
9174    (clobber (reg:CC FLAGS_REG))]
9175    "reload_completed
9176     && QI_REG_P (operands[0])
9177     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9178     && !(~INTVAL (operands[2]) & ~(255 << 8))
9179     && GET_MODE (operands[0]) != QImode"
9180   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9181                    (and:SI (zero_extract:SI (match_dup 1)
9182                                             (const_int 8) (const_int 8))
9183                            (match_dup 2)))
9184               (clobber (reg:CC FLAGS_REG))])]
9185   "operands[0] = gen_lowpart (SImode, operands[0]);
9186    operands[1] = gen_lowpart (SImode, operands[1]);
9187    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9188
9189 ;; Since AND can be encoded with sign extended immediate, this is only
9190 ;; profitable when 7th bit is not set.
9191 (define_split
9192   [(set (match_operand 0 "register_operand" "")
9193         (and (match_operand 1 "general_operand" "")
9194              (match_operand 2 "const_int_operand" "")))
9195    (clobber (reg:CC FLAGS_REG))]
9196    "reload_completed
9197     && ANY_QI_REG_P (operands[0])
9198     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9199     && !(~INTVAL (operands[2]) & ~255)
9200     && !(INTVAL (operands[2]) & 128)
9201     && GET_MODE (operands[0]) != QImode"
9202   [(parallel [(set (strict_low_part (match_dup 0))
9203                    (and:QI (match_dup 1)
9204                            (match_dup 2)))
9205               (clobber (reg:CC FLAGS_REG))])]
9206   "operands[0] = gen_lowpart (QImode, operands[0]);
9207    operands[1] = gen_lowpart (QImode, operands[1]);
9208    operands[2] = gen_lowpart (QImode, operands[2]);")
9209 \f
9210 ;; Logical inclusive OR instructions
9211
9212 ;; %%% This used to optimize known byte-wide and operations to memory.
9213 ;; If this is considered useful, it should be done with splitters.
9214
9215 (define_expand "iordi3"
9216   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9217         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9218                 (match_operand:DI 2 "x86_64_general_operand" "")))
9219    (clobber (reg:CC FLAGS_REG))]
9220   "TARGET_64BIT"
9221   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9222
9223 (define_insn "*iordi_1_rex64"
9224   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9225         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9226                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "TARGET_64BIT
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_2_rex64"
9235   [(set (reg FLAGS_REG)
9236         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9237                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9238                  (const_int 0)))
9239    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9240         (ior:DI (match_dup 1) (match_dup 2)))]
9241   "TARGET_64BIT
9242    && ix86_match_ccmode (insn, CCNOmode)
9243    && ix86_binary_operator_ok (IOR, DImode, operands)"
9244   "or{q}\t{%2, %0|%0, %2}"
9245   [(set_attr "type" "alu")
9246    (set_attr "mode" "DI")])
9247
9248 (define_insn "*iordi_3_rex64"
9249   [(set (reg FLAGS_REG)
9250         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9251                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9252                  (const_int 0)))
9253    (clobber (match_scratch:DI 0 "=r"))]
9254   "TARGET_64BIT
9255    && ix86_match_ccmode (insn, CCNOmode)
9256    && ix86_binary_operator_ok (IOR, DImode, operands)"
9257   "or{q}\t{%2, %0|%0, %2}"
9258   [(set_attr "type" "alu")
9259    (set_attr "mode" "DI")])
9260
9261
9262 (define_expand "iorsi3"
9263   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9264         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9265                 (match_operand:SI 2 "general_operand" "")))
9266    (clobber (reg:CC FLAGS_REG))]
9267   ""
9268   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9269
9270 (define_insn "*iorsi_1"
9271   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9272         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9273                 (match_operand:SI 2 "general_operand" "ri,g")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "ix86_binary_operator_ok (IOR, SImode, operands)"
9276   "or{l}\t{%2, %0|%0, %2}"
9277   [(set_attr "type" "alu")
9278    (set_attr "mode" "SI")])
9279
9280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9281 (define_insn "*iorsi_1_zext"
9282   [(set (match_operand:DI 0 "register_operand" "=r")
9283         (zero_extend:DI
9284           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9285                   (match_operand:SI 2 "general_operand" "g"))))
9286    (clobber (reg:CC FLAGS_REG))]
9287   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9288   "or{l}\t{%2, %k0|%k0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "SI")])
9291
9292 (define_insn "*iorsi_1_zext_imm"
9293   [(set (match_operand:DI 0 "register_operand" "=r")
9294         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9295                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9296    (clobber (reg:CC FLAGS_REG))]
9297   "TARGET_64BIT"
9298   "or{l}\t{%2, %k0|%k0, %2}"
9299   [(set_attr "type" "alu")
9300    (set_attr "mode" "SI")])
9301
9302 (define_insn "*iorsi_2"
9303   [(set (reg FLAGS_REG)
9304         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305                          (match_operand:SI 2 "general_operand" "g,ri"))
9306                  (const_int 0)))
9307    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9308         (ior:SI (match_dup 1) (match_dup 2)))]
9309   "ix86_match_ccmode (insn, CCNOmode)
9310    && ix86_binary_operator_ok (IOR, SImode, operands)"
9311   "or{l}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "SI")])
9314
9315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9316 ;; ??? Special case for immediate operand is missing - it is tricky.
9317 (define_insn "*iorsi_2_zext"
9318   [(set (reg FLAGS_REG)
9319         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9320                          (match_operand:SI 2 "general_operand" "g"))
9321                  (const_int 0)))
9322    (set (match_operand:DI 0 "register_operand" "=r")
9323         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9324   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9325    && ix86_binary_operator_ok (IOR, SImode, operands)"
9326   "or{l}\t{%2, %k0|%k0, %2}"
9327   [(set_attr "type" "alu")
9328    (set_attr "mode" "SI")])
9329
9330 (define_insn "*iorsi_2_zext_imm"
9331   [(set (reg FLAGS_REG)
9332         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9333                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9334                  (const_int 0)))
9335    (set (match_operand:DI 0 "register_operand" "=r")
9336         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9337   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9338    && ix86_binary_operator_ok (IOR, SImode, operands)"
9339   "or{l}\t{%2, %k0|%k0, %2}"
9340   [(set_attr "type" "alu")
9341    (set_attr "mode" "SI")])
9342
9343 (define_insn "*iorsi_3"
9344   [(set (reg FLAGS_REG)
9345         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9346                          (match_operand:SI 2 "general_operand" "g"))
9347                  (const_int 0)))
9348    (clobber (match_scratch:SI 0 "=r"))]
9349   "ix86_match_ccmode (insn, CCNOmode)
9350    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9351   "or{l}\t{%2, %0|%0, %2}"
9352   [(set_attr "type" "alu")
9353    (set_attr "mode" "SI")])
9354
9355 (define_expand "iorhi3"
9356   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9357         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9358                 (match_operand:HI 2 "general_operand" "")))
9359    (clobber (reg:CC FLAGS_REG))]
9360   "TARGET_HIMODE_MATH"
9361   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9362
9363 (define_insn "*iorhi_1"
9364   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9365         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9366                 (match_operand:HI 2 "general_operand" "g,ri")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "ix86_binary_operator_ok (IOR, HImode, operands)"
9369   "or{w}\t{%2, %0|%0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "HI")])
9372
9373 (define_insn "*iorhi_2"
9374   [(set (reg FLAGS_REG)
9375         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9376                          (match_operand:HI 2 "general_operand" "g,ri"))
9377                  (const_int 0)))
9378    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9379         (ior:HI (match_dup 1) (match_dup 2)))]
9380   "ix86_match_ccmode (insn, CCNOmode)
9381    && ix86_binary_operator_ok (IOR, HImode, operands)"
9382   "or{w}\t{%2, %0|%0, %2}"
9383   [(set_attr "type" "alu")
9384    (set_attr "mode" "HI")])
9385
9386 (define_insn "*iorhi_3"
9387   [(set (reg FLAGS_REG)
9388         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9389                          (match_operand:HI 2 "general_operand" "g"))
9390                  (const_int 0)))
9391    (clobber (match_scratch:HI 0 "=r"))]
9392   "ix86_match_ccmode (insn, CCNOmode)
9393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394   "or{w}\t{%2, %0|%0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "HI")])
9397
9398 (define_expand "iorqi3"
9399   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9400         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9401                 (match_operand:QI 2 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_QIMODE_MATH"
9404   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9405
9406 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9407 (define_insn "*iorqi_1"
9408   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9409         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9410                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "ix86_binary_operator_ok (IOR, QImode, operands)"
9413   "@
9414    or{b}\t{%2, %0|%0, %2}
9415    or{b}\t{%2, %0|%0, %2}
9416    or{l}\t{%k2, %k0|%k0, %k2}"
9417   [(set_attr "type" "alu")
9418    (set_attr "mode" "QI,QI,SI")])
9419
9420 (define_insn "*iorqi_1_slp"
9421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9422         (ior:QI (match_dup 0)
9423                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9426    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9427   "or{b}\t{%1, %0|%0, %1}"
9428   [(set_attr "type" "alu1")
9429    (set_attr "mode" "QI")])
9430
9431 (define_insn "*iorqi_2"
9432   [(set (reg FLAGS_REG)
9433         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9434                          (match_operand:QI 2 "general_operand" "qim,qi"))
9435                  (const_int 0)))
9436    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9437         (ior:QI (match_dup 1) (match_dup 2)))]
9438   "ix86_match_ccmode (insn, CCNOmode)
9439    && ix86_binary_operator_ok (IOR, QImode, operands)"
9440   "or{b}\t{%2, %0|%0, %2}"
9441   [(set_attr "type" "alu")
9442    (set_attr "mode" "QI")])
9443
9444 (define_insn "*iorqi_2_slp"
9445   [(set (reg FLAGS_REG)
9446         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9447                          (match_operand:QI 1 "general_operand" "qim,qi"))
9448                  (const_int 0)))
9449    (set (strict_low_part (match_dup 0))
9450         (ior:QI (match_dup 0) (match_dup 1)))]
9451   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9452    && ix86_match_ccmode (insn, CCNOmode)
9453    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9454   "or{b}\t{%1, %0|%0, %1}"
9455   [(set_attr "type" "alu1")
9456    (set_attr "mode" "QI")])
9457
9458 (define_insn "*iorqi_3"
9459   [(set (reg FLAGS_REG)
9460         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9461                          (match_operand:QI 2 "general_operand" "qim"))
9462                  (const_int 0)))
9463    (clobber (match_scratch:QI 0 "=q"))]
9464   "ix86_match_ccmode (insn, CCNOmode)
9465    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9466   "or{b}\t{%2, %0|%0, %2}"
9467   [(set_attr "type" "alu")
9468    (set_attr "mode" "QI")])
9469
9470 (define_insn "iorqi_ext_0"
9471   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9472                          (const_int 8)
9473                          (const_int 8))
9474         (ior:SI
9475           (zero_extract:SI
9476             (match_operand 1 "ext_register_operand" "0")
9477             (const_int 8)
9478             (const_int 8))
9479           (match_operand 2 "const_int_operand" "n")))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9482   "or{b}\t{%2, %h0|%h0, %2}"
9483   [(set_attr "type" "alu")
9484    (set_attr "length_immediate" "1")
9485    (set_attr "mode" "QI")])
9486
9487 (define_insn "*iorqi_ext_1"
9488   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489                          (const_int 8)
9490                          (const_int 8))
9491         (ior:SI
9492           (zero_extract:SI
9493             (match_operand 1 "ext_register_operand" "0")
9494             (const_int 8)
9495             (const_int 8))
9496           (zero_extend:SI
9497             (match_operand:QI 2 "general_operand" "Qm"))))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "!TARGET_64BIT
9500    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9501   "or{b}\t{%2, %h0|%h0, %2}"
9502   [(set_attr "type" "alu")
9503    (set_attr "length_immediate" "0")
9504    (set_attr "mode" "QI")])
9505
9506 (define_insn "*iorqi_ext_1_rex64"
9507   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9508                          (const_int 8)
9509                          (const_int 8))
9510         (ior:SI
9511           (zero_extract:SI
9512             (match_operand 1 "ext_register_operand" "0")
9513             (const_int 8)
9514             (const_int 8))
9515           (zero_extend:SI
9516             (match_operand 2 "ext_register_operand" "Q"))))
9517    (clobber (reg:CC FLAGS_REG))]
9518   "TARGET_64BIT
9519    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9520   "or{b}\t{%2, %h0|%h0, %2}"
9521   [(set_attr "type" "alu")
9522    (set_attr "length_immediate" "0")
9523    (set_attr "mode" "QI")])
9524
9525 (define_insn "*iorqi_ext_2"
9526   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9527                          (const_int 8)
9528                          (const_int 8))
9529         (ior:SI
9530           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9531                            (const_int 8)
9532                            (const_int 8))
9533           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9534                            (const_int 8)
9535                            (const_int 8))))
9536    (clobber (reg:CC FLAGS_REG))]
9537   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9538   "ior{b}\t{%h2, %h0|%h0, %h2}"
9539   [(set_attr "type" "alu")
9540    (set_attr "length_immediate" "0")
9541    (set_attr "mode" "QI")])
9542
9543 (define_split
9544   [(set (match_operand 0 "register_operand" "")
9545         (ior (match_operand 1 "register_operand" "")
9546              (match_operand 2 "const_int_operand" "")))
9547    (clobber (reg:CC FLAGS_REG))]
9548    "reload_completed
9549     && QI_REG_P (operands[0])
9550     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9551     && !(INTVAL (operands[2]) & ~(255 << 8))
9552     && GET_MODE (operands[0]) != QImode"
9553   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9554                    (ior:SI (zero_extract:SI (match_dup 1)
9555                                             (const_int 8) (const_int 8))
9556                            (match_dup 2)))
9557               (clobber (reg:CC FLAGS_REG))])]
9558   "operands[0] = gen_lowpart (SImode, operands[0]);
9559    operands[1] = gen_lowpart (SImode, operands[1]);
9560    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9561
9562 ;; Since OR can be encoded with sign extended immediate, this is only
9563 ;; profitable when 7th bit is set.
9564 (define_split
9565   [(set (match_operand 0 "register_operand" "")
9566         (ior (match_operand 1 "general_operand" "")
9567              (match_operand 2 "const_int_operand" "")))
9568    (clobber (reg:CC FLAGS_REG))]
9569    "reload_completed
9570     && ANY_QI_REG_P (operands[0])
9571     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9572     && !(INTVAL (operands[2]) & ~255)
9573     && (INTVAL (operands[2]) & 128)
9574     && GET_MODE (operands[0]) != QImode"
9575   [(parallel [(set (strict_low_part (match_dup 0))
9576                    (ior:QI (match_dup 1)
9577                            (match_dup 2)))
9578               (clobber (reg:CC FLAGS_REG))])]
9579   "operands[0] = gen_lowpart (QImode, operands[0]);
9580    operands[1] = gen_lowpart (QImode, operands[1]);
9581    operands[2] = gen_lowpart (QImode, operands[2]);")
9582 \f
9583 ;; Logical XOR instructions
9584
9585 ;; %%% This used to optimize known byte-wide and operations to memory.
9586 ;; If this is considered useful, it should be done with splitters.
9587
9588 (define_expand "xordi3"
9589   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9590         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9591                 (match_operand:DI 2 "x86_64_general_operand" "")))
9592    (clobber (reg:CC FLAGS_REG))]
9593   "TARGET_64BIT"
9594   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9595
9596 (define_insn "*xordi_1_rex64"
9597   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9598         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9599                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "TARGET_64BIT
9602    && ix86_binary_operator_ok (XOR, DImode, operands)"
9603   "@
9604    xor{q}\t{%2, %0|%0, %2}
9605    xor{q}\t{%2, %0|%0, %2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "DI,DI")])
9608
9609 (define_insn "*xordi_2_rex64"
9610   [(set (reg FLAGS_REG)
9611         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9612                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9613                  (const_int 0)))
9614    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9615         (xor:DI (match_dup 1) (match_dup 2)))]
9616   "TARGET_64BIT
9617    && ix86_match_ccmode (insn, CCNOmode)
9618    && ix86_binary_operator_ok (XOR, DImode, operands)"
9619   "@
9620    xor{q}\t{%2, %0|%0, %2}
9621    xor{q}\t{%2, %0|%0, %2}"
9622   [(set_attr "type" "alu")
9623    (set_attr "mode" "DI,DI")])
9624
9625 (define_insn "*xordi_3_rex64"
9626   [(set (reg FLAGS_REG)
9627         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9628                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9629                  (const_int 0)))
9630    (clobber (match_scratch:DI 0 "=r"))]
9631   "TARGET_64BIT
9632    && ix86_match_ccmode (insn, CCNOmode)
9633    && ix86_binary_operator_ok (XOR, DImode, operands)"
9634   "xor{q}\t{%2, %0|%0, %2}"
9635   [(set_attr "type" "alu")
9636    (set_attr "mode" "DI")])
9637
9638 (define_expand "xorsi3"
9639   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9640         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9641                 (match_operand:SI 2 "general_operand" "")))
9642    (clobber (reg:CC FLAGS_REG))]
9643   ""
9644   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9645
9646 (define_insn "*xorsi_1"
9647   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9648         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9649                 (match_operand:SI 2 "general_operand" "ri,rm")))
9650    (clobber (reg:CC FLAGS_REG))]
9651   "ix86_binary_operator_ok (XOR, SImode, operands)"
9652   "xor{l}\t{%2, %0|%0, %2}"
9653   [(set_attr "type" "alu")
9654    (set_attr "mode" "SI")])
9655
9656 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9657 ;; Add speccase for immediates
9658 (define_insn "*xorsi_1_zext"
9659   [(set (match_operand:DI 0 "register_operand" "=r")
9660         (zero_extend:DI
9661           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9662                   (match_operand:SI 2 "general_operand" "g"))))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9665   "xor{l}\t{%2, %k0|%k0, %2}"
9666   [(set_attr "type" "alu")
9667    (set_attr "mode" "SI")])
9668
9669 (define_insn "*xorsi_1_zext_imm"
9670   [(set (match_operand:DI 0 "register_operand" "=r")
9671         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9672                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9675   "xor{l}\t{%2, %k0|%k0, %2}"
9676   [(set_attr "type" "alu")
9677    (set_attr "mode" "SI")])
9678
9679 (define_insn "*xorsi_2"
9680   [(set (reg FLAGS_REG)
9681         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9682                          (match_operand:SI 2 "general_operand" "g,ri"))
9683                  (const_int 0)))
9684    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9685         (xor:SI (match_dup 1) (match_dup 2)))]
9686   "ix86_match_ccmode (insn, CCNOmode)
9687    && ix86_binary_operator_ok (XOR, SImode, operands)"
9688   "xor{l}\t{%2, %0|%0, %2}"
9689   [(set_attr "type" "alu")
9690    (set_attr "mode" "SI")])
9691
9692 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9693 ;; ??? Special case for immediate operand is missing - it is tricky.
9694 (define_insn "*xorsi_2_zext"
9695   [(set (reg FLAGS_REG)
9696         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697                          (match_operand:SI 2 "general_operand" "g"))
9698                  (const_int 0)))
9699    (set (match_operand:DI 0 "register_operand" "=r")
9700         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9701   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702    && ix86_binary_operator_ok (XOR, SImode, operands)"
9703   "xor{l}\t{%2, %k0|%k0, %2}"
9704   [(set_attr "type" "alu")
9705    (set_attr "mode" "SI")])
9706
9707 (define_insn "*xorsi_2_zext_imm"
9708   [(set (reg FLAGS_REG)
9709         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9711                  (const_int 0)))
9712    (set (match_operand:DI 0 "register_operand" "=r")
9713         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9714   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9715    && ix86_binary_operator_ok (XOR, SImode, operands)"
9716   "xor{l}\t{%2, %k0|%k0, %2}"
9717   [(set_attr "type" "alu")
9718    (set_attr "mode" "SI")])
9719
9720 (define_insn "*xorsi_3"
9721   [(set (reg FLAGS_REG)
9722         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723                          (match_operand:SI 2 "general_operand" "g"))
9724                  (const_int 0)))
9725    (clobber (match_scratch:SI 0 "=r"))]
9726   "ix86_match_ccmode (insn, CCNOmode)
9727    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9728   "xor{l}\t{%2, %0|%0, %2}"
9729   [(set_attr "type" "alu")
9730    (set_attr "mode" "SI")])
9731
9732 (define_expand "xorhi3"
9733   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9734         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9735                 (match_operand:HI 2 "general_operand" "")))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_HIMODE_MATH"
9738   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9739
9740 (define_insn "*xorhi_1"
9741   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9742         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9743                 (match_operand:HI 2 "general_operand" "g,ri")))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "ix86_binary_operator_ok (XOR, HImode, operands)"
9746   "xor{w}\t{%2, %0|%0, %2}"
9747   [(set_attr "type" "alu")
9748    (set_attr "mode" "HI")])
9749
9750 (define_insn "*xorhi_2"
9751   [(set (reg FLAGS_REG)
9752         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9753                          (match_operand:HI 2 "general_operand" "g,ri"))
9754                  (const_int 0)))
9755    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9756         (xor:HI (match_dup 1) (match_dup 2)))]
9757   "ix86_match_ccmode (insn, CCNOmode)
9758    && ix86_binary_operator_ok (XOR, HImode, operands)"
9759   "xor{w}\t{%2, %0|%0, %2}"
9760   [(set_attr "type" "alu")
9761    (set_attr "mode" "HI")])
9762
9763 (define_insn "*xorhi_3"
9764   [(set (reg FLAGS_REG)
9765         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9766                          (match_operand:HI 2 "general_operand" "g"))
9767                  (const_int 0)))
9768    (clobber (match_scratch:HI 0 "=r"))]
9769   "ix86_match_ccmode (insn, CCNOmode)
9770    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9771   "xor{w}\t{%2, %0|%0, %2}"
9772   [(set_attr "type" "alu")
9773    (set_attr "mode" "HI")])
9774
9775 (define_expand "xorqi3"
9776   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9777         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9778                 (match_operand:QI 2 "general_operand" "")))
9779    (clobber (reg:CC FLAGS_REG))]
9780   "TARGET_QIMODE_MATH"
9781   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9782
9783 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9784 (define_insn "*xorqi_1"
9785   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9786         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9787                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9788    (clobber (reg:CC FLAGS_REG))]
9789   "ix86_binary_operator_ok (XOR, QImode, operands)"
9790   "@
9791    xor{b}\t{%2, %0|%0, %2}
9792    xor{b}\t{%2, %0|%0, %2}
9793    xor{l}\t{%k2, %k0|%k0, %k2}"
9794   [(set_attr "type" "alu")
9795    (set_attr "mode" "QI,QI,SI")])
9796
9797 (define_insn "*xorqi_1_slp"
9798   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9799         (xor:QI (match_dup 0)
9800                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9803    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9804   "xor{b}\t{%1, %0|%0, %1}"
9805   [(set_attr "type" "alu1")
9806    (set_attr "mode" "QI")])
9807
9808 (define_insn "xorqi_ext_0"
9809   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9810                          (const_int 8)
9811                          (const_int 8))
9812         (xor:SI
9813           (zero_extract:SI
9814             (match_operand 1 "ext_register_operand" "0")
9815             (const_int 8)
9816             (const_int 8))
9817           (match_operand 2 "const_int_operand" "n")))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9820   "xor{b}\t{%2, %h0|%h0, %2}"
9821   [(set_attr "type" "alu")
9822    (set_attr "length_immediate" "1")
9823    (set_attr "mode" "QI")])
9824
9825 (define_insn "*xorqi_ext_1"
9826   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9827                          (const_int 8)
9828                          (const_int 8))
9829         (xor:SI
9830           (zero_extract:SI
9831             (match_operand 1 "ext_register_operand" "0")
9832             (const_int 8)
9833             (const_int 8))
9834           (zero_extend:SI
9835             (match_operand:QI 2 "general_operand" "Qm"))))
9836    (clobber (reg:CC FLAGS_REG))]
9837   "!TARGET_64BIT
9838    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9839   "xor{b}\t{%2, %h0|%h0, %2}"
9840   [(set_attr "type" "alu")
9841    (set_attr "length_immediate" "0")
9842    (set_attr "mode" "QI")])
9843
9844 (define_insn "*xorqi_ext_1_rex64"
9845   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9846                          (const_int 8)
9847                          (const_int 8))
9848         (xor:SI
9849           (zero_extract:SI
9850             (match_operand 1 "ext_register_operand" "0")
9851             (const_int 8)
9852             (const_int 8))
9853           (zero_extend:SI
9854             (match_operand 2 "ext_register_operand" "Q"))))
9855    (clobber (reg:CC FLAGS_REG))]
9856   "TARGET_64BIT
9857    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9858   "xor{b}\t{%2, %h0|%h0, %2}"
9859   [(set_attr "type" "alu")
9860    (set_attr "length_immediate" "0")
9861    (set_attr "mode" "QI")])
9862
9863 (define_insn "*xorqi_ext_2"
9864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9865                          (const_int 8)
9866                          (const_int 8))
9867         (xor:SI
9868           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9869                            (const_int 8)
9870                            (const_int 8))
9871           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9872                            (const_int 8)
9873                            (const_int 8))))
9874    (clobber (reg:CC FLAGS_REG))]
9875   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9876   "xor{b}\t{%h2, %h0|%h0, %h2}"
9877   [(set_attr "type" "alu")
9878    (set_attr "length_immediate" "0")
9879    (set_attr "mode" "QI")])
9880
9881 (define_insn "*xorqi_cc_1"
9882   [(set (reg FLAGS_REG)
9883         (compare
9884           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9885                   (match_operand:QI 2 "general_operand" "qim,qi"))
9886           (const_int 0)))
9887    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9888         (xor:QI (match_dup 1) (match_dup 2)))]
9889   "ix86_match_ccmode (insn, CCNOmode)
9890    && ix86_binary_operator_ok (XOR, QImode, operands)"
9891   "xor{b}\t{%2, %0|%0, %2}"
9892   [(set_attr "type" "alu")
9893    (set_attr "mode" "QI")])
9894
9895 (define_insn "*xorqi_2_slp"
9896   [(set (reg FLAGS_REG)
9897         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9898                          (match_operand:QI 1 "general_operand" "qim,qi"))
9899                  (const_int 0)))
9900    (set (strict_low_part (match_dup 0))
9901         (xor:QI (match_dup 0) (match_dup 1)))]
9902   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9903    && ix86_match_ccmode (insn, CCNOmode)
9904    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9905   "xor{b}\t{%1, %0|%0, %1}"
9906   [(set_attr "type" "alu1")
9907    (set_attr "mode" "QI")])
9908
9909 (define_insn "*xorqi_cc_2"
9910   [(set (reg FLAGS_REG)
9911         (compare
9912           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9913                   (match_operand:QI 2 "general_operand" "qim"))
9914           (const_int 0)))
9915    (clobber (match_scratch:QI 0 "=q"))]
9916   "ix86_match_ccmode (insn, CCNOmode)
9917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9918   "xor{b}\t{%2, %0|%0, %2}"
9919   [(set_attr "type" "alu")
9920    (set_attr "mode" "QI")])
9921
9922 (define_insn "*xorqi_cc_ext_1"
9923   [(set (reg FLAGS_REG)
9924         (compare
9925           (xor:SI
9926             (zero_extract:SI
9927               (match_operand 1 "ext_register_operand" "0")
9928               (const_int 8)
9929               (const_int 8))
9930             (match_operand:QI 2 "general_operand" "qmn"))
9931           (const_int 0)))
9932    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9933                          (const_int 8)
9934                          (const_int 8))
9935         (xor:SI
9936           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9937           (match_dup 2)))]
9938   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9939   "xor{b}\t{%2, %h0|%h0, %2}"
9940   [(set_attr "type" "alu")
9941    (set_attr "mode" "QI")])
9942
9943 (define_insn "*xorqi_cc_ext_1_rex64"
9944   [(set (reg FLAGS_REG)
9945         (compare
9946           (xor:SI
9947             (zero_extract:SI
9948               (match_operand 1 "ext_register_operand" "0")
9949               (const_int 8)
9950               (const_int 8))
9951             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9952           (const_int 0)))
9953    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9954                          (const_int 8)
9955                          (const_int 8))
9956         (xor:SI
9957           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9958           (match_dup 2)))]
9959   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9960   "xor{b}\t{%2, %h0|%h0, %2}"
9961   [(set_attr "type" "alu")
9962    (set_attr "mode" "QI")])
9963
9964 (define_expand "xorqi_cc_ext_1"
9965   [(parallel [
9966      (set (reg:CCNO FLAGS_REG)
9967           (compare:CCNO
9968             (xor:SI
9969               (zero_extract:SI
9970                 (match_operand 1 "ext_register_operand" "")
9971                 (const_int 8)
9972                 (const_int 8))
9973               (match_operand:QI 2 "general_operand" ""))
9974             (const_int 0)))
9975      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9976                            (const_int 8)
9977                            (const_int 8))
9978           (xor:SI
9979             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9980             (match_dup 2)))])]
9981   ""
9982   "")
9983
9984 (define_split
9985   [(set (match_operand 0 "register_operand" "")
9986         (xor (match_operand 1 "register_operand" "")
9987              (match_operand 2 "const_int_operand" "")))
9988    (clobber (reg:CC FLAGS_REG))]
9989    "reload_completed
9990     && QI_REG_P (operands[0])
9991     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9992     && !(INTVAL (operands[2]) & ~(255 << 8))
9993     && GET_MODE (operands[0]) != QImode"
9994   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9995                    (xor:SI (zero_extract:SI (match_dup 1)
9996                                             (const_int 8) (const_int 8))
9997                            (match_dup 2)))
9998               (clobber (reg:CC FLAGS_REG))])]
9999   "operands[0] = gen_lowpart (SImode, operands[0]);
10000    operands[1] = gen_lowpart (SImode, operands[1]);
10001    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10002
10003 ;; Since XOR can be encoded with sign extended immediate, this is only
10004 ;; profitable when 7th bit is set.
10005 (define_split
10006   [(set (match_operand 0 "register_operand" "")
10007         (xor (match_operand 1 "general_operand" "")
10008              (match_operand 2 "const_int_operand" "")))
10009    (clobber (reg:CC FLAGS_REG))]
10010    "reload_completed
10011     && ANY_QI_REG_P (operands[0])
10012     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10013     && !(INTVAL (operands[2]) & ~255)
10014     && (INTVAL (operands[2]) & 128)
10015     && GET_MODE (operands[0]) != QImode"
10016   [(parallel [(set (strict_low_part (match_dup 0))
10017                    (xor:QI (match_dup 1)
10018                            (match_dup 2)))
10019               (clobber (reg:CC FLAGS_REG))])]
10020   "operands[0] = gen_lowpart (QImode, operands[0]);
10021    operands[1] = gen_lowpart (QImode, operands[1]);
10022    operands[2] = gen_lowpart (QImode, operands[2]);")
10023 \f
10024 ;; Negation instructions
10025
10026 (define_expand "negti2"
10027   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10028                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10029               (clobber (reg:CC FLAGS_REG))])]
10030   "TARGET_64BIT"
10031   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10032
10033 (define_insn "*negti2_1"
10034   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10035         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10036    (clobber (reg:CC FLAGS_REG))]
10037   "TARGET_64BIT
10038    && ix86_unary_operator_ok (NEG, TImode, operands)"
10039   "#")
10040
10041 (define_split
10042   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10043         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10044    (clobber (reg:CC FLAGS_REG))]
10045   "TARGET_64BIT && reload_completed"
10046   [(parallel
10047     [(set (reg:CCZ FLAGS_REG)
10048           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10049      (set (match_dup 0) (neg:DI (match_dup 2)))])
10050    (parallel
10051     [(set (match_dup 1)
10052           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10053                             (match_dup 3))
10054                    (const_int 0)))
10055      (clobber (reg:CC FLAGS_REG))])
10056    (parallel
10057     [(set (match_dup 1)
10058           (neg:DI (match_dup 1)))
10059      (clobber (reg:CC FLAGS_REG))])]
10060   "split_ti (operands+1, 1, operands+2, operands+3);
10061    split_ti (operands+0, 1, operands+0, operands+1);")
10062
10063 (define_expand "negdi2"
10064   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10065                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10066               (clobber (reg:CC FLAGS_REG))])]
10067   ""
10068   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10069
10070 (define_insn "*negdi2_1"
10071   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10072         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10073    (clobber (reg:CC FLAGS_REG))]
10074   "!TARGET_64BIT
10075    && ix86_unary_operator_ok (NEG, DImode, operands)"
10076   "#")
10077
10078 (define_split
10079   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10080         (neg:DI (match_operand:DI 1 "general_operand" "")))
10081    (clobber (reg:CC FLAGS_REG))]
10082   "!TARGET_64BIT && reload_completed"
10083   [(parallel
10084     [(set (reg:CCZ FLAGS_REG)
10085           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10086      (set (match_dup 0) (neg:SI (match_dup 2)))])
10087    (parallel
10088     [(set (match_dup 1)
10089           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10090                             (match_dup 3))
10091                    (const_int 0)))
10092      (clobber (reg:CC FLAGS_REG))])
10093    (parallel
10094     [(set (match_dup 1)
10095           (neg:SI (match_dup 1)))
10096      (clobber (reg:CC FLAGS_REG))])]
10097   "split_di (operands+1, 1, operands+2, operands+3);
10098    split_di (operands+0, 1, operands+0, operands+1);")
10099
10100 (define_insn "*negdi2_1_rex64"
10101   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10102         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10103    (clobber (reg:CC FLAGS_REG))]
10104   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10105   "neg{q}\t%0"
10106   [(set_attr "type" "negnot")
10107    (set_attr "mode" "DI")])
10108
10109 ;; The problem with neg is that it does not perform (compare x 0),
10110 ;; it really performs (compare 0 x), which leaves us with the zero
10111 ;; flag being the only useful item.
10112
10113 (define_insn "*negdi2_cmpz_rex64"
10114   [(set (reg:CCZ FLAGS_REG)
10115         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10116                      (const_int 0)))
10117    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10118         (neg:DI (match_dup 1)))]
10119   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10120   "neg{q}\t%0"
10121   [(set_attr "type" "negnot")
10122    (set_attr "mode" "DI")])
10123
10124
10125 (define_expand "negsi2"
10126   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10127                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10128               (clobber (reg:CC FLAGS_REG))])]
10129   ""
10130   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10131
10132 (define_insn "*negsi2_1"
10133   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10135    (clobber (reg:CC FLAGS_REG))]
10136   "ix86_unary_operator_ok (NEG, SImode, operands)"
10137   "neg{l}\t%0"
10138   [(set_attr "type" "negnot")
10139    (set_attr "mode" "SI")])
10140
10141 ;; Combine is quite creative about this pattern.
10142 (define_insn "*negsi2_1_zext"
10143   [(set (match_operand:DI 0 "register_operand" "=r")
10144         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10145                                         (const_int 32)))
10146                      (const_int 32)))
10147    (clobber (reg:CC FLAGS_REG))]
10148   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10149   "neg{l}\t%k0"
10150   [(set_attr "type" "negnot")
10151    (set_attr "mode" "SI")])
10152
10153 ;; The problem with neg is that it does not perform (compare x 0),
10154 ;; it really performs (compare 0 x), which leaves us with the zero
10155 ;; flag being the only useful item.
10156
10157 (define_insn "*negsi2_cmpz"
10158   [(set (reg:CCZ FLAGS_REG)
10159         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10160                      (const_int 0)))
10161    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10162         (neg:SI (match_dup 1)))]
10163   "ix86_unary_operator_ok (NEG, SImode, operands)"
10164   "neg{l}\t%0"
10165   [(set_attr "type" "negnot")
10166    (set_attr "mode" "SI")])
10167
10168 (define_insn "*negsi2_cmpz_zext"
10169   [(set (reg:CCZ FLAGS_REG)
10170         (compare:CCZ (lshiftrt:DI
10171                        (neg:DI (ashift:DI
10172                                  (match_operand:DI 1 "register_operand" "0")
10173                                  (const_int 32)))
10174                        (const_int 32))
10175                      (const_int 0)))
10176    (set (match_operand:DI 0 "register_operand" "=r")
10177         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10178                                         (const_int 32)))
10179                      (const_int 32)))]
10180   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10181   "neg{l}\t%k0"
10182   [(set_attr "type" "negnot")
10183    (set_attr "mode" "SI")])
10184
10185 (define_expand "neghi2"
10186   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10188               (clobber (reg:CC FLAGS_REG))])]
10189   "TARGET_HIMODE_MATH"
10190   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10191
10192 (define_insn "*neghi2_1"
10193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10194         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "ix86_unary_operator_ok (NEG, HImode, operands)"
10197   "neg{w}\t%0"
10198   [(set_attr "type" "negnot")
10199    (set_attr "mode" "HI")])
10200
10201 (define_insn "*neghi2_cmpz"
10202   [(set (reg:CCZ FLAGS_REG)
10203         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10204                      (const_int 0)))
10205    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10206         (neg:HI (match_dup 1)))]
10207   "ix86_unary_operator_ok (NEG, HImode, operands)"
10208   "neg{w}\t%0"
10209   [(set_attr "type" "negnot")
10210    (set_attr "mode" "HI")])
10211
10212 (define_expand "negqi2"
10213   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10214                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10215               (clobber (reg:CC FLAGS_REG))])]
10216   "TARGET_QIMODE_MATH"
10217   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10218
10219 (define_insn "*negqi2_1"
10220   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10221         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10222    (clobber (reg:CC FLAGS_REG))]
10223   "ix86_unary_operator_ok (NEG, QImode, operands)"
10224   "neg{b}\t%0"
10225   [(set_attr "type" "negnot")
10226    (set_attr "mode" "QI")])
10227
10228 (define_insn "*negqi2_cmpz"
10229   [(set (reg:CCZ FLAGS_REG)
10230         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10231                      (const_int 0)))
10232    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10233         (neg:QI (match_dup 1)))]
10234   "ix86_unary_operator_ok (NEG, QImode, operands)"
10235   "neg{b}\t%0"
10236   [(set_attr "type" "negnot")
10237    (set_attr "mode" "QI")])
10238
10239 ;; Changing of sign for FP values is doable using integer unit too.
10240
10241 (define_expand "neg<mode>2"
10242   [(set (match_operand:X87MODEF 0 "register_operand" "")
10243         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10244   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10245   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10246
10247 (define_expand "abs<mode>2"
10248   [(set (match_operand:X87MODEF 0 "register_operand" "")
10249         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10250   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10251   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10252
10253 (define_insn "*absneg<mode>2_mixed"
10254   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10255         (match_operator:MODEF 3 "absneg_operator"
10256           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10257    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10258    (clobber (reg:CC FLAGS_REG))]
10259   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10260   "#")
10261
10262 (define_insn "*absneg<mode>2_sse"
10263   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10264         (match_operator:MODEF 3 "absneg_operator"
10265           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10266    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10267    (clobber (reg:CC FLAGS_REG))]
10268   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10269   "#")
10270
10271 (define_insn "*absneg<mode>2_i387"
10272   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10273         (match_operator:X87MODEF 3 "absneg_operator"
10274           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10275    (use (match_operand 2 "" ""))
10276    (clobber (reg:CC FLAGS_REG))]
10277   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10278   "#")
10279
10280 (define_expand "negtf2"
10281   [(set (match_operand:TF 0 "register_operand" "")
10282         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10283   "TARGET_64BIT"
10284   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10285
10286 (define_expand "abstf2"
10287   [(set (match_operand:TF 0 "register_operand" "")
10288         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10289   "TARGET_64BIT"
10290   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10291
10292 (define_insn "*absnegtf2_sse"
10293   [(set (match_operand:TF 0 "register_operand" "=x,x")
10294         (match_operator:TF 3 "absneg_operator"
10295           [(match_operand:TF 1 "register_operand" "0,x")]))
10296    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10297    (clobber (reg:CC FLAGS_REG))]
10298   "TARGET_64BIT"
10299   "#")
10300
10301 ;; Splitters for fp abs and neg.
10302
10303 (define_split
10304   [(set (match_operand 0 "fp_register_operand" "")
10305         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10306    (use (match_operand 2 "" ""))
10307    (clobber (reg:CC FLAGS_REG))]
10308   "reload_completed"
10309   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10310
10311 (define_split
10312   [(set (match_operand 0 "register_operand" "")
10313         (match_operator 3 "absneg_operator"
10314           [(match_operand 1 "register_operand" "")]))
10315    (use (match_operand 2 "nonimmediate_operand" ""))
10316    (clobber (reg:CC FLAGS_REG))]
10317   "reload_completed && SSE_REG_P (operands[0])"
10318   [(set (match_dup 0) (match_dup 3))]
10319 {
10320   enum machine_mode mode = GET_MODE (operands[0]);
10321   enum machine_mode vmode = GET_MODE (operands[2]);
10322   rtx tmp;
10323
10324   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10325   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10326   if (operands_match_p (operands[0], operands[2]))
10327     {
10328       tmp = operands[1];
10329       operands[1] = operands[2];
10330       operands[2] = tmp;
10331     }
10332   if (GET_CODE (operands[3]) == ABS)
10333     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10334   else
10335     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10336   operands[3] = tmp;
10337 })
10338
10339 (define_split
10340   [(set (match_operand:SF 0 "register_operand" "")
10341         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10342    (use (match_operand:V4SF 2 "" ""))
10343    (clobber (reg:CC FLAGS_REG))]
10344   "reload_completed"
10345   [(parallel [(set (match_dup 0) (match_dup 1))
10346               (clobber (reg:CC FLAGS_REG))])]
10347 {
10348   rtx tmp;
10349   operands[0] = gen_lowpart (SImode, operands[0]);
10350   if (GET_CODE (operands[1]) == ABS)
10351     {
10352       tmp = gen_int_mode (0x7fffffff, SImode);
10353       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10354     }
10355   else
10356     {
10357       tmp = gen_int_mode (0x80000000, SImode);
10358       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10359     }
10360   operands[1] = tmp;
10361 })
10362
10363 (define_split
10364   [(set (match_operand:DF 0 "register_operand" "")
10365         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10366    (use (match_operand 2 "" ""))
10367    (clobber (reg:CC FLAGS_REG))]
10368   "reload_completed"
10369   [(parallel [(set (match_dup 0) (match_dup 1))
10370               (clobber (reg:CC FLAGS_REG))])]
10371 {
10372   rtx tmp;
10373   if (TARGET_64BIT)
10374     {
10375       tmp = gen_lowpart (DImode, operands[0]);
10376       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10377       operands[0] = tmp;
10378
10379       if (GET_CODE (operands[1]) == ABS)
10380         tmp = const0_rtx;
10381       else
10382         tmp = gen_rtx_NOT (DImode, tmp);
10383     }
10384   else
10385     {
10386       operands[0] = gen_highpart (SImode, operands[0]);
10387       if (GET_CODE (operands[1]) == ABS)
10388         {
10389           tmp = gen_int_mode (0x7fffffff, SImode);
10390           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10391         }
10392       else
10393         {
10394           tmp = gen_int_mode (0x80000000, SImode);
10395           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10396         }
10397     }
10398   operands[1] = tmp;
10399 })
10400
10401 (define_split
10402   [(set (match_operand:XF 0 "register_operand" "")
10403         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10404    (use (match_operand 2 "" ""))
10405    (clobber (reg:CC FLAGS_REG))]
10406   "reload_completed"
10407   [(parallel [(set (match_dup 0) (match_dup 1))
10408               (clobber (reg:CC FLAGS_REG))])]
10409 {
10410   rtx tmp;
10411   operands[0] = gen_rtx_REG (SImode,
10412                              true_regnum (operands[0])
10413                              + (TARGET_64BIT ? 1 : 2));
10414   if (GET_CODE (operands[1]) == ABS)
10415     {
10416       tmp = GEN_INT (0x7fff);
10417       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10418     }
10419   else
10420     {
10421       tmp = GEN_INT (0x8000);
10422       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10423     }
10424   operands[1] = tmp;
10425 })
10426
10427 ;; Conditionalize these after reload. If they match before reload, we
10428 ;; lose the clobber and ability to use integer instructions.
10429
10430 (define_insn "*neg<mode>2_1"
10431   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10432         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10433   "TARGET_80387
10434    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10435   "fchs"
10436   [(set_attr "type" "fsgn")
10437    (set_attr "mode" "<MODE>")])
10438
10439 (define_insn "*abs<mode>2_1"
10440   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10441         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10442   "TARGET_80387
10443    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10444   "fabs"
10445   [(set_attr "type" "fsgn")
10446    (set_attr "mode" "<MODE>")])
10447
10448 (define_insn "*negextendsfdf2"
10449   [(set (match_operand:DF 0 "register_operand" "=f")
10450         (neg:DF (float_extend:DF
10451                   (match_operand:SF 1 "register_operand" "0"))))]
10452   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10453   "fchs"
10454   [(set_attr "type" "fsgn")
10455    (set_attr "mode" "DF")])
10456
10457 (define_insn "*negextenddfxf2"
10458   [(set (match_operand:XF 0 "register_operand" "=f")
10459         (neg:XF (float_extend:XF
10460                   (match_operand:DF 1 "register_operand" "0"))))]
10461   "TARGET_80387"
10462   "fchs"
10463   [(set_attr "type" "fsgn")
10464    (set_attr "mode" "XF")])
10465
10466 (define_insn "*negextendsfxf2"
10467   [(set (match_operand:XF 0 "register_operand" "=f")
10468         (neg:XF (float_extend:XF
10469                   (match_operand:SF 1 "register_operand" "0"))))]
10470   "TARGET_80387"
10471   "fchs"
10472   [(set_attr "type" "fsgn")
10473    (set_attr "mode" "XF")])
10474
10475 (define_insn "*absextendsfdf2"
10476   [(set (match_operand:DF 0 "register_operand" "=f")
10477         (abs:DF (float_extend:DF
10478                   (match_operand:SF 1 "register_operand" "0"))))]
10479   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10480   "fabs"
10481   [(set_attr "type" "fsgn")
10482    (set_attr "mode" "DF")])
10483
10484 (define_insn "*absextenddfxf2"
10485   [(set (match_operand:XF 0 "register_operand" "=f")
10486         (abs:XF (float_extend:XF
10487           (match_operand:DF 1 "register_operand" "0"))))]
10488   "TARGET_80387"
10489   "fabs"
10490   [(set_attr "type" "fsgn")
10491    (set_attr "mode" "XF")])
10492
10493 (define_insn "*absextendsfxf2"
10494   [(set (match_operand:XF 0 "register_operand" "=f")
10495         (abs:XF (float_extend:XF
10496           (match_operand:SF 1 "register_operand" "0"))))]
10497   "TARGET_80387"
10498   "fabs"
10499   [(set_attr "type" "fsgn")
10500    (set_attr "mode" "XF")])
10501
10502 ;; Copysign instructions
10503
10504 (define_mode_iterator CSGNMODE [SF DF TF])
10505 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10506
10507 (define_expand "copysign<mode>3"
10508   [(match_operand:CSGNMODE 0 "register_operand" "")
10509    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10510    (match_operand:CSGNMODE 2 "register_operand" "")]
10511   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10512    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10513 {
10514   ix86_expand_copysign (operands);
10515   DONE;
10516 })
10517
10518 (define_insn_and_split "copysign<mode>3_const"
10519   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10520         (unspec:CSGNMODE
10521           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10522            (match_operand:CSGNMODE 2 "register_operand" "0")
10523            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10524           UNSPEC_COPYSIGN))]
10525   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10526    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10527   "#"
10528   "&& reload_completed"
10529   [(const_int 0)]
10530 {
10531   ix86_split_copysign_const (operands);
10532   DONE;
10533 })
10534
10535 (define_insn "copysign<mode>3_var"
10536   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10537         (unspec:CSGNMODE
10538           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10539            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10540            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10541            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10542           UNSPEC_COPYSIGN))
10543    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10544   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10545    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10546   "#")
10547
10548 (define_split
10549   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10550         (unspec:CSGNMODE
10551           [(match_operand:CSGNMODE 2 "register_operand" "")
10552            (match_operand:CSGNMODE 3 "register_operand" "")
10553            (match_operand:<CSGNVMODE> 4 "" "")
10554            (match_operand:<CSGNVMODE> 5 "" "")]
10555           UNSPEC_COPYSIGN))
10556    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10557   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10558     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10559    && reload_completed"
10560   [(const_int 0)]
10561 {
10562   ix86_split_copysign_var (operands);
10563   DONE;
10564 })
10565 \f
10566 ;; One complement instructions
10567
10568 (define_expand "one_cmpldi2"
10569   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10570         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10571   "TARGET_64BIT"
10572   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10573
10574 (define_insn "*one_cmpldi2_1_rex64"
10575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10576         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10577   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10578   "not{q}\t%0"
10579   [(set_attr "type" "negnot")
10580    (set_attr "mode" "DI")])
10581
10582 (define_insn "*one_cmpldi2_2_rex64"
10583   [(set (reg FLAGS_REG)
10584         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10585                  (const_int 0)))
10586    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10587         (not:DI (match_dup 1)))]
10588   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10589    && ix86_unary_operator_ok (NOT, DImode, operands)"
10590   "#"
10591   [(set_attr "type" "alu1")
10592    (set_attr "mode" "DI")])
10593
10594 (define_split
10595   [(set (match_operand 0 "flags_reg_operand" "")
10596         (match_operator 2 "compare_operator"
10597           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10598            (const_int 0)]))
10599    (set (match_operand:DI 1 "nonimmediate_operand" "")
10600         (not:DI (match_dup 3)))]
10601   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10602   [(parallel [(set (match_dup 0)
10603                    (match_op_dup 2
10604                      [(xor:DI (match_dup 3) (const_int -1))
10605                       (const_int 0)]))
10606               (set (match_dup 1)
10607                    (xor:DI (match_dup 3) (const_int -1)))])]
10608   "")
10609
10610 (define_expand "one_cmplsi2"
10611   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10612         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10613   ""
10614   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10615
10616 (define_insn "*one_cmplsi2_1"
10617   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10618         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10619   "ix86_unary_operator_ok (NOT, SImode, operands)"
10620   "not{l}\t%0"
10621   [(set_attr "type" "negnot")
10622    (set_attr "mode" "SI")])
10623
10624 ;; ??? Currently never generated - xor is used instead.
10625 (define_insn "*one_cmplsi2_1_zext"
10626   [(set (match_operand:DI 0 "register_operand" "=r")
10627         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10628   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10629   "not{l}\t%k0"
10630   [(set_attr "type" "negnot")
10631    (set_attr "mode" "SI")])
10632
10633 (define_insn "*one_cmplsi2_2"
10634   [(set (reg FLAGS_REG)
10635         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10636                  (const_int 0)))
10637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10638         (not:SI (match_dup 1)))]
10639   "ix86_match_ccmode (insn, CCNOmode)
10640    && ix86_unary_operator_ok (NOT, SImode, operands)"
10641   "#"
10642   [(set_attr "type" "alu1")
10643    (set_attr "mode" "SI")])
10644
10645 (define_split
10646   [(set (match_operand 0 "flags_reg_operand" "")
10647         (match_operator 2 "compare_operator"
10648           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10649            (const_int 0)]))
10650    (set (match_operand:SI 1 "nonimmediate_operand" "")
10651         (not:SI (match_dup 3)))]
10652   "ix86_match_ccmode (insn, CCNOmode)"
10653   [(parallel [(set (match_dup 0)
10654                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10655                                     (const_int 0)]))
10656               (set (match_dup 1)
10657                    (xor:SI (match_dup 3) (const_int -1)))])]
10658   "")
10659
10660 ;; ??? Currently never generated - xor is used instead.
10661 (define_insn "*one_cmplsi2_2_zext"
10662   [(set (reg FLAGS_REG)
10663         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10664                  (const_int 0)))
10665    (set (match_operand:DI 0 "register_operand" "=r")
10666         (zero_extend:DI (not:SI (match_dup 1))))]
10667   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10668    && ix86_unary_operator_ok (NOT, SImode, operands)"
10669   "#"
10670   [(set_attr "type" "alu1")
10671    (set_attr "mode" "SI")])
10672
10673 (define_split
10674   [(set (match_operand 0 "flags_reg_operand" "")
10675         (match_operator 2 "compare_operator"
10676           [(not:SI (match_operand:SI 3 "register_operand" ""))
10677            (const_int 0)]))
10678    (set (match_operand:DI 1 "register_operand" "")
10679         (zero_extend:DI (not:SI (match_dup 3))))]
10680   "ix86_match_ccmode (insn, CCNOmode)"
10681   [(parallel [(set (match_dup 0)
10682                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10683                                     (const_int 0)]))
10684               (set (match_dup 1)
10685                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10686   "")
10687
10688 (define_expand "one_cmplhi2"
10689   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10690         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10691   "TARGET_HIMODE_MATH"
10692   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10693
10694 (define_insn "*one_cmplhi2_1"
10695   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10696         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10697   "ix86_unary_operator_ok (NOT, HImode, operands)"
10698   "not{w}\t%0"
10699   [(set_attr "type" "negnot")
10700    (set_attr "mode" "HI")])
10701
10702 (define_insn "*one_cmplhi2_2"
10703   [(set (reg FLAGS_REG)
10704         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10705                  (const_int 0)))
10706    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10707         (not:HI (match_dup 1)))]
10708   "ix86_match_ccmode (insn, CCNOmode)
10709    && ix86_unary_operator_ok (NEG, HImode, operands)"
10710   "#"
10711   [(set_attr "type" "alu1")
10712    (set_attr "mode" "HI")])
10713
10714 (define_split
10715   [(set (match_operand 0 "flags_reg_operand" "")
10716         (match_operator 2 "compare_operator"
10717           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10718            (const_int 0)]))
10719    (set (match_operand:HI 1 "nonimmediate_operand" "")
10720         (not:HI (match_dup 3)))]
10721   "ix86_match_ccmode (insn, CCNOmode)"
10722   [(parallel [(set (match_dup 0)
10723                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10724                                     (const_int 0)]))
10725               (set (match_dup 1)
10726                    (xor:HI (match_dup 3) (const_int -1)))])]
10727   "")
10728
10729 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10730 (define_expand "one_cmplqi2"
10731   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10732         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10733   "TARGET_QIMODE_MATH"
10734   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10735
10736 (define_insn "*one_cmplqi2_1"
10737   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10738         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10739   "ix86_unary_operator_ok (NOT, QImode, operands)"
10740   "@
10741    not{b}\t%0
10742    not{l}\t%k0"
10743   [(set_attr "type" "negnot")
10744    (set_attr "mode" "QI,SI")])
10745
10746 (define_insn "*one_cmplqi2_2"
10747   [(set (reg FLAGS_REG)
10748         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10749                  (const_int 0)))
10750    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10751         (not:QI (match_dup 1)))]
10752   "ix86_match_ccmode (insn, CCNOmode)
10753    && ix86_unary_operator_ok (NOT, QImode, operands)"
10754   "#"
10755   [(set_attr "type" "alu1")
10756    (set_attr "mode" "QI")])
10757
10758 (define_split
10759   [(set (match_operand 0 "flags_reg_operand" "")
10760         (match_operator 2 "compare_operator"
10761           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10762            (const_int 0)]))
10763    (set (match_operand:QI 1 "nonimmediate_operand" "")
10764         (not:QI (match_dup 3)))]
10765   "ix86_match_ccmode (insn, CCNOmode)"
10766   [(parallel [(set (match_dup 0)
10767                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10768                                     (const_int 0)]))
10769               (set (match_dup 1)
10770                    (xor:QI (match_dup 3) (const_int -1)))])]
10771   "")
10772 \f
10773 ;; Arithmetic shift instructions
10774
10775 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10776 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10777 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10778 ;; from the assembler input.
10779 ;;
10780 ;; This instruction shifts the target reg/mem as usual, but instead of
10781 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10782 ;; is a left shift double, bits are taken from the high order bits of
10783 ;; reg, else if the insn is a shift right double, bits are taken from the
10784 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10785 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10786 ;;
10787 ;; Since sh[lr]d does not change the `reg' operand, that is done
10788 ;; separately, making all shifts emit pairs of shift double and normal
10789 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10790 ;; support a 63 bit shift, each shift where the count is in a reg expands
10791 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10792 ;;
10793 ;; If the shift count is a constant, we need never emit more than one
10794 ;; shift pair, instead using moves and sign extension for counts greater
10795 ;; than 31.
10796
10797 (define_expand "ashlti3"
10798   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10799                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10800                               (match_operand:QI 2 "nonmemory_operand" "")))
10801               (clobber (reg:CC FLAGS_REG))])]
10802   "TARGET_64BIT"
10803 {
10804   if (! immediate_operand (operands[2], QImode))
10805     {
10806       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10807       DONE;
10808     }
10809   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10810   DONE;
10811 })
10812
10813 (define_insn "ashlti3_1"
10814   [(set (match_operand:TI 0 "register_operand" "=r")
10815         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10816                    (match_operand:QI 2 "register_operand" "c")))
10817    (clobber (match_scratch:DI 3 "=&r"))
10818    (clobber (reg:CC FLAGS_REG))]
10819   "TARGET_64BIT"
10820   "#"
10821   [(set_attr "type" "multi")])
10822
10823 ;; This pattern must be defined before *ashlti3_2 to prevent
10824 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10825
10826 (define_insn "sse2_ashlti3"
10827   [(set (match_operand:TI 0 "register_operand" "=x")
10828         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10829                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10830   "TARGET_SSE2"
10831 {
10832   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10833   return "pslldq\t{%2, %0|%0, %2}";
10834 }
10835   [(set_attr "type" "sseishft")
10836    (set_attr "prefix_data16" "1")
10837    (set_attr "mode" "TI")])
10838
10839 (define_insn "*ashlti3_2"
10840   [(set (match_operand:TI 0 "register_operand" "=r")
10841         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10842                    (match_operand:QI 2 "immediate_operand" "O")))
10843    (clobber (reg:CC FLAGS_REG))]
10844   "TARGET_64BIT"
10845   "#"
10846   [(set_attr "type" "multi")])
10847
10848 (define_split
10849   [(set (match_operand:TI 0 "register_operand" "")
10850         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10851                    (match_operand:QI 2 "register_operand" "")))
10852    (clobber (match_scratch:DI 3 ""))
10853    (clobber (reg:CC FLAGS_REG))]
10854   "TARGET_64BIT && reload_completed"
10855   [(const_int 0)]
10856   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10857
10858 (define_split
10859   [(set (match_operand:TI 0 "register_operand" "")
10860         (ashift:TI (match_operand:TI 1 "register_operand" "")
10861                    (match_operand:QI 2 "immediate_operand" "")))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "TARGET_64BIT && reload_completed"
10864   [(const_int 0)]
10865   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10866
10867 (define_insn "x86_64_shld"
10868   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10869         (ior:DI (ashift:DI (match_dup 0)
10870                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10871                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10872                   (minus:QI (const_int 64) (match_dup 2)))))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "TARGET_64BIT"
10875   "@
10876    shld{q}\t{%2, %1, %0|%0, %1, %2}
10877    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10878   [(set_attr "type" "ishift")
10879    (set_attr "prefix_0f" "1")
10880    (set_attr "mode" "DI")
10881    (set_attr "athlon_decode" "vector")
10882    (set_attr "amdfam10_decode" "vector")])
10883
10884 (define_expand "x86_64_shift_adj"
10885   [(set (reg:CCZ FLAGS_REG)
10886         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10887                              (const_int 64))
10888                      (const_int 0)))
10889    (set (match_operand:DI 0 "register_operand" "")
10890         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10891                          (match_operand:DI 1 "register_operand" "")
10892                          (match_dup 0)))
10893    (set (match_dup 1)
10894         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10895                          (match_operand:DI 3 "register_operand" "r")
10896                          (match_dup 1)))]
10897   "TARGET_64BIT"
10898   "")
10899
10900 (define_expand "ashldi3"
10901   [(set (match_operand:DI 0 "shiftdi_operand" "")
10902         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10903                    (match_operand:QI 2 "nonmemory_operand" "")))]
10904   ""
10905   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10906
10907 (define_insn "*ashldi3_1_rex64"
10908   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10909         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10910                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10913 {
10914   switch (get_attr_type (insn))
10915     {
10916     case TYPE_ALU:
10917       gcc_assert (operands[2] == const1_rtx);
10918       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10919       return "add{q}\t%0, %0";
10920
10921     case TYPE_LEA:
10922       gcc_assert (CONST_INT_P (operands[2]));
10923       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10924       operands[1] = gen_rtx_MULT (DImode, operands[1],
10925                                   GEN_INT (1 << INTVAL (operands[2])));
10926       return "lea{q}\t{%a1, %0|%0, %a1}";
10927
10928     default:
10929       if (REG_P (operands[2]))
10930         return "sal{q}\t{%b2, %0|%0, %b2}";
10931       else if (operands[2] == const1_rtx
10932                && (TARGET_SHIFT1 || optimize_size))
10933         return "sal{q}\t%0";
10934       else
10935         return "sal{q}\t{%2, %0|%0, %2}";
10936     }
10937 }
10938   [(set (attr "type")
10939      (cond [(eq_attr "alternative" "1")
10940               (const_string "lea")
10941             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10942                           (const_int 0))
10943                       (match_operand 0 "register_operand" ""))
10944                  (match_operand 2 "const1_operand" ""))
10945               (const_string "alu")
10946            ]
10947            (const_string "ishift")))
10948    (set_attr "mode" "DI")])
10949
10950 ;; Convert lea to the lea pattern to avoid flags dependency.
10951 (define_split
10952   [(set (match_operand:DI 0 "register_operand" "")
10953         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10954                    (match_operand:QI 2 "immediate_operand" "")))
10955    (clobber (reg:CC FLAGS_REG))]
10956   "TARGET_64BIT && reload_completed
10957    && true_regnum (operands[0]) != true_regnum (operands[1])"
10958   [(set (match_dup 0)
10959         (mult:DI (match_dup 1)
10960                  (match_dup 2)))]
10961   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10962
10963 ;; This pattern can't accept a variable shift count, since shifts by
10964 ;; zero don't affect the flags.  We assume that shifts by constant
10965 ;; zero are optimized away.
10966 (define_insn "*ashldi3_cmp_rex64"
10967   [(set (reg FLAGS_REG)
10968         (compare
10969           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10970                      (match_operand:QI 2 "immediate_operand" "e"))
10971           (const_int 0)))
10972    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10973         (ashift:DI (match_dup 1) (match_dup 2)))]
10974   "TARGET_64BIT
10975    && (optimize_size
10976        || !TARGET_PARTIAL_FLAG_REG_STALL
10977        || (operands[2] == const1_rtx
10978            && (TARGET_SHIFT1
10979                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10980    && ix86_match_ccmode (insn, CCGOCmode)
10981    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10982 {
10983   switch (get_attr_type (insn))
10984     {
10985     case TYPE_ALU:
10986       gcc_assert (operands[2] == const1_rtx);
10987       return "add{q}\t%0, %0";
10988
10989     default:
10990       if (REG_P (operands[2]))
10991         return "sal{q}\t{%b2, %0|%0, %b2}";
10992       else if (operands[2] == const1_rtx
10993                && (TARGET_SHIFT1 || optimize_size))
10994         return "sal{q}\t%0";
10995       else
10996         return "sal{q}\t{%2, %0|%0, %2}";
10997     }
10998 }
10999   [(set (attr "type")
11000      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11001                           (const_int 0))
11002                       (match_operand 0 "register_operand" ""))
11003                  (match_operand 2 "const1_operand" ""))
11004               (const_string "alu")
11005            ]
11006            (const_string "ishift")))
11007    (set_attr "mode" "DI")])
11008
11009 (define_insn "*ashldi3_cconly_rex64"
11010   [(set (reg FLAGS_REG)
11011         (compare
11012           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11013                      (match_operand:QI 2 "immediate_operand" "e"))
11014           (const_int 0)))
11015    (clobber (match_scratch:DI 0 "=r"))]
11016   "TARGET_64BIT
11017    && (optimize_size
11018        || !TARGET_PARTIAL_FLAG_REG_STALL
11019        || (operands[2] == const1_rtx
11020            && (TARGET_SHIFT1
11021                || TARGET_DOUBLE_WITH_ADD)))
11022    && ix86_match_ccmode (insn, CCGOCmode)
11023    && 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       return "add{q}\t%0, %0";
11030
11031     default:
11032       if (REG_P (operands[2]))
11033         return "sal{q}\t{%b2, %0|%0, %b2}";
11034       else if (operands[2] == const1_rtx
11035                && (TARGET_SHIFT1 || optimize_size))
11036         return "sal{q}\t%0";
11037       else
11038         return "sal{q}\t{%2, %0|%0, %2}";
11039     }
11040 }
11041   [(set (attr "type")
11042      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11043                           (const_int 0))
11044                       (match_operand 0 "register_operand" ""))
11045                  (match_operand 2 "const1_operand" ""))
11046               (const_string "alu")
11047            ]
11048            (const_string "ishift")))
11049    (set_attr "mode" "DI")])
11050
11051 (define_insn "*ashldi3_1"
11052   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11053         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11054                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "!TARGET_64BIT"
11057   "#"
11058   [(set_attr "type" "multi")])
11059
11060 ;; By default we don't ask for a scratch register, because when DImode
11061 ;; values are manipulated, registers are already at a premium.  But if
11062 ;; we have one handy, we won't turn it away.
11063 (define_peephole2
11064   [(match_scratch:SI 3 "r")
11065    (parallel [(set (match_operand:DI 0 "register_operand" "")
11066                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11067                               (match_operand:QI 2 "nonmemory_operand" "")))
11068               (clobber (reg:CC FLAGS_REG))])
11069    (match_dup 3)]
11070   "!TARGET_64BIT && TARGET_CMOVE"
11071   [(const_int 0)]
11072   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11073
11074 (define_split
11075   [(set (match_operand:DI 0 "register_operand" "")
11076         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11077                    (match_operand:QI 2 "nonmemory_operand" "")))
11078    (clobber (reg:CC FLAGS_REG))]
11079   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11080                      ? epilogue_completed : reload_completed)"
11081   [(const_int 0)]
11082   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11083
11084 (define_insn "x86_shld_1"
11085   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11086         (ior:SI (ashift:SI (match_dup 0)
11087                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11088                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11089                   (minus:QI (const_int 32) (match_dup 2)))))
11090    (clobber (reg:CC FLAGS_REG))]
11091   ""
11092   "@
11093    shld{l}\t{%2, %1, %0|%0, %1, %2}
11094    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11095   [(set_attr "type" "ishift")
11096    (set_attr "prefix_0f" "1")
11097    (set_attr "mode" "SI")
11098    (set_attr "pent_pair" "np")
11099    (set_attr "athlon_decode" "vector")
11100    (set_attr "amdfam10_decode" "vector")])
11101
11102 (define_expand "x86_shift_adj_1"
11103   [(set (reg:CCZ FLAGS_REG)
11104         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11105                              (const_int 32))
11106                      (const_int 0)))
11107    (set (match_operand:SI 0 "register_operand" "")
11108         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11109                          (match_operand:SI 1 "register_operand" "")
11110                          (match_dup 0)))
11111    (set (match_dup 1)
11112         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11113                          (match_operand:SI 3 "register_operand" "r")
11114                          (match_dup 1)))]
11115   "TARGET_CMOVE"
11116   "")
11117
11118 (define_expand "x86_shift_adj_2"
11119   [(use (match_operand:SI 0 "register_operand" ""))
11120    (use (match_operand:SI 1 "register_operand" ""))
11121    (use (match_operand:QI 2 "register_operand" ""))]
11122   ""
11123 {
11124   rtx label = gen_label_rtx ();
11125   rtx tmp;
11126
11127   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11128
11129   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11130   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11131   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11132                               gen_rtx_LABEL_REF (VOIDmode, label),
11133                               pc_rtx);
11134   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11135   JUMP_LABEL (tmp) = label;
11136
11137   emit_move_insn (operands[0], operands[1]);
11138   ix86_expand_clear (operands[1]);
11139
11140   emit_label (label);
11141   LABEL_NUSES (label) = 1;
11142
11143   DONE;
11144 })
11145
11146 (define_expand "ashlsi3"
11147   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11148         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11149                    (match_operand:QI 2 "nonmemory_operand" "")))
11150    (clobber (reg:CC FLAGS_REG))]
11151   ""
11152   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11153
11154 (define_insn "*ashlsi3_1"
11155   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11156         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11157                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11158    (clobber (reg:CC FLAGS_REG))]
11159   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11160 {
11161   switch (get_attr_type (insn))
11162     {
11163     case TYPE_ALU:
11164       gcc_assert (operands[2] == const1_rtx);
11165       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11166       return "add{l}\t%0, %0";
11167
11168     case TYPE_LEA:
11169       return "#";
11170
11171     default:
11172       if (REG_P (operands[2]))
11173         return "sal{l}\t{%b2, %0|%0, %b2}";
11174       else if (operands[2] == const1_rtx
11175                && (TARGET_SHIFT1 || optimize_size))
11176         return "sal{l}\t%0";
11177       else
11178         return "sal{l}\t{%2, %0|%0, %2}";
11179     }
11180 }
11181   [(set (attr "type")
11182      (cond [(eq_attr "alternative" "1")
11183               (const_string "lea")
11184             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11185                           (const_int 0))
11186                       (match_operand 0 "register_operand" ""))
11187                  (match_operand 2 "const1_operand" ""))
11188               (const_string "alu")
11189            ]
11190            (const_string "ishift")))
11191    (set_attr "mode" "SI")])
11192
11193 ;; Convert lea to the lea pattern to avoid flags dependency.
11194 (define_split
11195   [(set (match_operand 0 "register_operand" "")
11196         (ashift (match_operand 1 "index_register_operand" "")
11197                 (match_operand:QI 2 "const_int_operand" "")))
11198    (clobber (reg:CC FLAGS_REG))]
11199   "reload_completed
11200    && true_regnum (operands[0]) != true_regnum (operands[1])
11201    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11202   [(const_int 0)]
11203 {
11204   rtx pat;
11205   enum machine_mode mode = GET_MODE (operands[0]);
11206
11207   if (GET_MODE_SIZE (mode) < 4)
11208     operands[0] = gen_lowpart (SImode, operands[0]);
11209   if (mode != Pmode)
11210     operands[1] = gen_lowpart (Pmode, operands[1]);
11211   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11212
11213   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11214   if (Pmode != SImode)
11215     pat = gen_rtx_SUBREG (SImode, pat, 0);
11216   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11217   DONE;
11218 })
11219
11220 ;; Rare case of shifting RSP is handled by generating move and shift
11221 (define_split
11222   [(set (match_operand 0 "register_operand" "")
11223         (ashift (match_operand 1 "register_operand" "")
11224                 (match_operand:QI 2 "const_int_operand" "")))
11225    (clobber (reg:CC FLAGS_REG))]
11226   "reload_completed
11227    && true_regnum (operands[0]) != true_regnum (operands[1])"
11228   [(const_int 0)]
11229 {
11230   rtx pat, clob;
11231   emit_move_insn (operands[0], operands[1]);
11232   pat = gen_rtx_SET (VOIDmode, operands[0],
11233                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11234                                      operands[0], operands[2]));
11235   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11236   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11237   DONE;
11238 })
11239
11240 (define_insn "*ashlsi3_1_zext"
11241   [(set (match_operand:DI 0 "register_operand" "=r,r")
11242         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11243                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11246 {
11247   switch (get_attr_type (insn))
11248     {
11249     case TYPE_ALU:
11250       gcc_assert (operands[2] == const1_rtx);
11251       return "add{l}\t%k0, %k0";
11252
11253     case TYPE_LEA:
11254       return "#";
11255
11256     default:
11257       if (REG_P (operands[2]))
11258         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11259       else if (operands[2] == const1_rtx
11260                && (TARGET_SHIFT1 || optimize_size))
11261         return "sal{l}\t%k0";
11262       else
11263         return "sal{l}\t{%2, %k0|%k0, %2}";
11264     }
11265 }
11266   [(set (attr "type")
11267      (cond [(eq_attr "alternative" "1")
11268               (const_string "lea")
11269             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11270                      (const_int 0))
11271                  (match_operand 2 "const1_operand" ""))
11272               (const_string "alu")
11273            ]
11274            (const_string "ishift")))
11275    (set_attr "mode" "SI")])
11276
11277 ;; Convert lea to the lea pattern to avoid flags dependency.
11278 (define_split
11279   [(set (match_operand:DI 0 "register_operand" "")
11280         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11281                                 (match_operand:QI 2 "const_int_operand" ""))))
11282    (clobber (reg:CC FLAGS_REG))]
11283   "TARGET_64BIT && reload_completed
11284    && true_regnum (operands[0]) != true_regnum (operands[1])"
11285   [(set (match_dup 0) (zero_extend:DI
11286                         (subreg:SI (mult:SI (match_dup 1)
11287                                             (match_dup 2)) 0)))]
11288 {
11289   operands[1] = gen_lowpart (Pmode, operands[1]);
11290   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11291 })
11292
11293 ;; This pattern can't accept a variable shift count, since shifts by
11294 ;; zero don't affect the flags.  We assume that shifts by constant
11295 ;; zero are optimized away.
11296 (define_insn "*ashlsi3_cmp"
11297   [(set (reg FLAGS_REG)
11298         (compare
11299           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11300                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11301           (const_int 0)))
11302    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11303         (ashift:SI (match_dup 1) (match_dup 2)))]
11304    "(optimize_size
11305      || !TARGET_PARTIAL_FLAG_REG_STALL
11306      || (operands[2] == const1_rtx
11307          && (TARGET_SHIFT1
11308              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11309    && ix86_match_ccmode (insn, CCGOCmode)
11310    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11311 {
11312   switch (get_attr_type (insn))
11313     {
11314     case TYPE_ALU:
11315       gcc_assert (operands[2] == const1_rtx);
11316       return "add{l}\t%0, %0";
11317
11318     default:
11319       if (REG_P (operands[2]))
11320         return "sal{l}\t{%b2, %0|%0, %b2}";
11321       else if (operands[2] == const1_rtx
11322                && (TARGET_SHIFT1 || optimize_size))
11323         return "sal{l}\t%0";
11324       else
11325         return "sal{l}\t{%2, %0|%0, %2}";
11326     }
11327 }
11328   [(set (attr "type")
11329      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11330                           (const_int 0))
11331                       (match_operand 0 "register_operand" ""))
11332                  (match_operand 2 "const1_operand" ""))
11333               (const_string "alu")
11334            ]
11335            (const_string "ishift")))
11336    (set_attr "mode" "SI")])
11337
11338 (define_insn "*ashlsi3_cconly"
11339   [(set (reg FLAGS_REG)
11340         (compare
11341           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11342                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11343           (const_int 0)))
11344    (clobber (match_scratch:SI 0 "=r"))]
11345   "(optimize_size
11346     || !TARGET_PARTIAL_FLAG_REG_STALL
11347     || (operands[2] == const1_rtx
11348         && (TARGET_SHIFT1
11349             || TARGET_DOUBLE_WITH_ADD)))
11350    && ix86_match_ccmode (insn, CCGOCmode)
11351    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11352 {
11353   switch (get_attr_type (insn))
11354     {
11355     case TYPE_ALU:
11356       gcc_assert (operands[2] == const1_rtx);
11357       return "add{l}\t%0, %0";
11358
11359     default:
11360       if (REG_P (operands[2]))
11361         return "sal{l}\t{%b2, %0|%0, %b2}";
11362       else if (operands[2] == const1_rtx
11363                && (TARGET_SHIFT1 || optimize_size))
11364         return "sal{l}\t%0";
11365       else
11366         return "sal{l}\t{%2, %0|%0, %2}";
11367     }
11368 }
11369   [(set (attr "type")
11370      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11371                           (const_int 0))
11372                       (match_operand 0 "register_operand" ""))
11373                  (match_operand 2 "const1_operand" ""))
11374               (const_string "alu")
11375            ]
11376            (const_string "ishift")))
11377    (set_attr "mode" "SI")])
11378
11379 (define_insn "*ashlsi3_cmp_zext"
11380   [(set (reg FLAGS_REG)
11381         (compare
11382           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11383                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11384           (const_int 0)))
11385    (set (match_operand:DI 0 "register_operand" "=r")
11386         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11387   "TARGET_64BIT
11388    && (optimize_size
11389        || !TARGET_PARTIAL_FLAG_REG_STALL
11390        || (operands[2] == const1_rtx
11391            && (TARGET_SHIFT1
11392                || TARGET_DOUBLE_WITH_ADD)))
11393    && ix86_match_ccmode (insn, CCGOCmode)
11394    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11395 {
11396   switch (get_attr_type (insn))
11397     {
11398     case TYPE_ALU:
11399       gcc_assert (operands[2] == const1_rtx);
11400       return "add{l}\t%k0, %k0";
11401
11402     default:
11403       if (REG_P (operands[2]))
11404         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11405       else if (operands[2] == const1_rtx
11406                && (TARGET_SHIFT1 || optimize_size))
11407         return "sal{l}\t%k0";
11408       else
11409         return "sal{l}\t{%2, %k0|%k0, %2}";
11410     }
11411 }
11412   [(set (attr "type")
11413      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11414                      (const_int 0))
11415                  (match_operand 2 "const1_operand" ""))
11416               (const_string "alu")
11417            ]
11418            (const_string "ishift")))
11419    (set_attr "mode" "SI")])
11420
11421 (define_expand "ashlhi3"
11422   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11423         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11424                    (match_operand:QI 2 "nonmemory_operand" "")))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "TARGET_HIMODE_MATH"
11427   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11428
11429 (define_insn "*ashlhi3_1_lea"
11430   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11431         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11432                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11433    (clobber (reg:CC FLAGS_REG))]
11434   "!TARGET_PARTIAL_REG_STALL
11435    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11436 {
11437   switch (get_attr_type (insn))
11438     {
11439     case TYPE_LEA:
11440       return "#";
11441     case TYPE_ALU:
11442       gcc_assert (operands[2] == const1_rtx);
11443       return "add{w}\t%0, %0";
11444
11445     default:
11446       if (REG_P (operands[2]))
11447         return "sal{w}\t{%b2, %0|%0, %b2}";
11448       else if (operands[2] == const1_rtx
11449                && (TARGET_SHIFT1 || optimize_size))
11450         return "sal{w}\t%0";
11451       else
11452         return "sal{w}\t{%2, %0|%0, %2}";
11453     }
11454 }
11455   [(set (attr "type")
11456      (cond [(eq_attr "alternative" "1")
11457               (const_string "lea")
11458             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11459                           (const_int 0))
11460                       (match_operand 0 "register_operand" ""))
11461                  (match_operand 2 "const1_operand" ""))
11462               (const_string "alu")
11463            ]
11464            (const_string "ishift")))
11465    (set_attr "mode" "HI,SI")])
11466
11467 (define_insn "*ashlhi3_1"
11468   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11469         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11470                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11471    (clobber (reg:CC FLAGS_REG))]
11472   "TARGET_PARTIAL_REG_STALL
11473    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11474 {
11475   switch (get_attr_type (insn))
11476     {
11477     case TYPE_ALU:
11478       gcc_assert (operands[2] == const1_rtx);
11479       return "add{w}\t%0, %0";
11480
11481     default:
11482       if (REG_P (operands[2]))
11483         return "sal{w}\t{%b2, %0|%0, %b2}";
11484       else if (operands[2] == const1_rtx
11485                && (TARGET_SHIFT1 || optimize_size))
11486         return "sal{w}\t%0";
11487       else
11488         return "sal{w}\t{%2, %0|%0, %2}";
11489     }
11490 }
11491   [(set (attr "type")
11492      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11493                           (const_int 0))
11494                       (match_operand 0 "register_operand" ""))
11495                  (match_operand 2 "const1_operand" ""))
11496               (const_string "alu")
11497            ]
11498            (const_string "ishift")))
11499    (set_attr "mode" "HI")])
11500
11501 ;; This pattern can't accept a variable shift count, since shifts by
11502 ;; zero don't affect the flags.  We assume that shifts by constant
11503 ;; zero are optimized away.
11504 (define_insn "*ashlhi3_cmp"
11505   [(set (reg FLAGS_REG)
11506         (compare
11507           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11508                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11509           (const_int 0)))
11510    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11511         (ashift:HI (match_dup 1) (match_dup 2)))]
11512   "(optimize_size
11513     || !TARGET_PARTIAL_FLAG_REG_STALL
11514     || (operands[2] == const1_rtx
11515         && (TARGET_SHIFT1
11516             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11517    && ix86_match_ccmode (insn, CCGOCmode)
11518    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11519 {
11520   switch (get_attr_type (insn))
11521     {
11522     case TYPE_ALU:
11523       gcc_assert (operands[2] == const1_rtx);
11524       return "add{w}\t%0, %0";
11525
11526     default:
11527       if (REG_P (operands[2]))
11528         return "sal{w}\t{%b2, %0|%0, %b2}";
11529       else if (operands[2] == const1_rtx
11530                && (TARGET_SHIFT1 || optimize_size))
11531         return "sal{w}\t%0";
11532       else
11533         return "sal{w}\t{%2, %0|%0, %2}";
11534     }
11535 }
11536   [(set (attr "type")
11537      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11538                           (const_int 0))
11539                       (match_operand 0 "register_operand" ""))
11540                  (match_operand 2 "const1_operand" ""))
11541               (const_string "alu")
11542            ]
11543            (const_string "ishift")))
11544    (set_attr "mode" "HI")])
11545
11546 (define_insn "*ashlhi3_cconly"
11547   [(set (reg FLAGS_REG)
11548         (compare
11549           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11550                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11551           (const_int 0)))
11552    (clobber (match_scratch:HI 0 "=r"))]
11553   "(optimize_size
11554     || !TARGET_PARTIAL_FLAG_REG_STALL
11555     || (operands[2] == const1_rtx
11556         && (TARGET_SHIFT1
11557             || TARGET_DOUBLE_WITH_ADD)))
11558    && ix86_match_ccmode (insn, CCGOCmode)
11559    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11560 {
11561   switch (get_attr_type (insn))
11562     {
11563     case TYPE_ALU:
11564       gcc_assert (operands[2] == const1_rtx);
11565       return "add{w}\t%0, %0";
11566
11567     default:
11568       if (REG_P (operands[2]))
11569         return "sal{w}\t{%b2, %0|%0, %b2}";
11570       else if (operands[2] == const1_rtx
11571                && (TARGET_SHIFT1 || optimize_size))
11572         return "sal{w}\t%0";
11573       else
11574         return "sal{w}\t{%2, %0|%0, %2}";
11575     }
11576 }
11577   [(set (attr "type")
11578      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11579                           (const_int 0))
11580                       (match_operand 0 "register_operand" ""))
11581                  (match_operand 2 "const1_operand" ""))
11582               (const_string "alu")
11583            ]
11584            (const_string "ishift")))
11585    (set_attr "mode" "HI")])
11586
11587 (define_expand "ashlqi3"
11588   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11589         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11590                    (match_operand:QI 2 "nonmemory_operand" "")))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_QIMODE_MATH"
11593   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11594
11595 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11596
11597 (define_insn "*ashlqi3_1_lea"
11598   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11599         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11600                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "!TARGET_PARTIAL_REG_STALL
11603    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11604 {
11605   switch (get_attr_type (insn))
11606     {
11607     case TYPE_LEA:
11608       return "#";
11609     case TYPE_ALU:
11610       gcc_assert (operands[2] == const1_rtx);
11611       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11612         return "add{l}\t%k0, %k0";
11613       else
11614         return "add{b}\t%0, %0";
11615
11616     default:
11617       if (REG_P (operands[2]))
11618         {
11619           if (get_attr_mode (insn) == MODE_SI)
11620             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11621           else
11622             return "sal{b}\t{%b2, %0|%0, %b2}";
11623         }
11624       else if (operands[2] == const1_rtx
11625                && (TARGET_SHIFT1 || optimize_size))
11626         {
11627           if (get_attr_mode (insn) == MODE_SI)
11628             return "sal{l}\t%0";
11629           else
11630             return "sal{b}\t%0";
11631         }
11632       else
11633         {
11634           if (get_attr_mode (insn) == MODE_SI)
11635             return "sal{l}\t{%2, %k0|%k0, %2}";
11636           else
11637             return "sal{b}\t{%2, %0|%0, %2}";
11638         }
11639     }
11640 }
11641   [(set (attr "type")
11642      (cond [(eq_attr "alternative" "2")
11643               (const_string "lea")
11644             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11645                           (const_int 0))
11646                       (match_operand 0 "register_operand" ""))
11647                  (match_operand 2 "const1_operand" ""))
11648               (const_string "alu")
11649            ]
11650            (const_string "ishift")))
11651    (set_attr "mode" "QI,SI,SI")])
11652
11653 (define_insn "*ashlqi3_1"
11654   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11655         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11656                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "TARGET_PARTIAL_REG_STALL
11659    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11660 {
11661   switch (get_attr_type (insn))
11662     {
11663     case TYPE_ALU:
11664       gcc_assert (operands[2] == const1_rtx);
11665       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11666         return "add{l}\t%k0, %k0";
11667       else
11668         return "add{b}\t%0, %0";
11669
11670     default:
11671       if (REG_P (operands[2]))
11672         {
11673           if (get_attr_mode (insn) == MODE_SI)
11674             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11675           else
11676             return "sal{b}\t{%b2, %0|%0, %b2}";
11677         }
11678       else if (operands[2] == const1_rtx
11679                && (TARGET_SHIFT1 || optimize_size))
11680         {
11681           if (get_attr_mode (insn) == MODE_SI)
11682             return "sal{l}\t%0";
11683           else
11684             return "sal{b}\t%0";
11685         }
11686       else
11687         {
11688           if (get_attr_mode (insn) == MODE_SI)
11689             return "sal{l}\t{%2, %k0|%k0, %2}";
11690           else
11691             return "sal{b}\t{%2, %0|%0, %2}";
11692         }
11693     }
11694 }
11695   [(set (attr "type")
11696      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11697                           (const_int 0))
11698                       (match_operand 0 "register_operand" ""))
11699                  (match_operand 2 "const1_operand" ""))
11700               (const_string "alu")
11701            ]
11702            (const_string "ishift")))
11703    (set_attr "mode" "QI,SI")])
11704
11705 ;; This pattern can't accept a variable shift count, since shifts by
11706 ;; zero don't affect the flags.  We assume that shifts by constant
11707 ;; zero are optimized away.
11708 (define_insn "*ashlqi3_cmp"
11709   [(set (reg FLAGS_REG)
11710         (compare
11711           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11712                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713           (const_int 0)))
11714    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11715         (ashift:QI (match_dup 1) (match_dup 2)))]
11716   "(optimize_size
11717     || !TARGET_PARTIAL_FLAG_REG_STALL
11718     || (operands[2] == const1_rtx
11719         && (TARGET_SHIFT1
11720             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11721    && ix86_match_ccmode (insn, CCGOCmode)
11722    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11723 {
11724   switch (get_attr_type (insn))
11725     {
11726     case TYPE_ALU:
11727       gcc_assert (operands[2] == const1_rtx);
11728       return "add{b}\t%0, %0";
11729
11730     default:
11731       if (REG_P (operands[2]))
11732         return "sal{b}\t{%b2, %0|%0, %b2}";
11733       else if (operands[2] == const1_rtx
11734                && (TARGET_SHIFT1 || optimize_size))
11735         return "sal{b}\t%0";
11736       else
11737         return "sal{b}\t{%2, %0|%0, %2}";
11738     }
11739 }
11740   [(set (attr "type")
11741      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11742                           (const_int 0))
11743                       (match_operand 0 "register_operand" ""))
11744                  (match_operand 2 "const1_operand" ""))
11745               (const_string "alu")
11746            ]
11747            (const_string "ishift")))
11748    (set_attr "mode" "QI")])
11749
11750 (define_insn "*ashlqi3_cconly"
11751   [(set (reg FLAGS_REG)
11752         (compare
11753           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11754                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11755           (const_int 0)))
11756    (clobber (match_scratch:QI 0 "=q"))]
11757   "(optimize_size
11758     || !TARGET_PARTIAL_FLAG_REG_STALL
11759     || (operands[2] == const1_rtx
11760         && (TARGET_SHIFT1
11761             || TARGET_DOUBLE_WITH_ADD)))
11762    && ix86_match_ccmode (insn, CCGOCmode)
11763    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11764 {
11765   switch (get_attr_type (insn))
11766     {
11767     case TYPE_ALU:
11768       gcc_assert (operands[2] == const1_rtx);
11769       return "add{b}\t%0, %0";
11770
11771     default:
11772       if (REG_P (operands[2]))
11773         return "sal{b}\t{%b2, %0|%0, %b2}";
11774       else if (operands[2] == const1_rtx
11775                && (TARGET_SHIFT1 || optimize_size))
11776         return "sal{b}\t%0";
11777       else
11778         return "sal{b}\t{%2, %0|%0, %2}";
11779     }
11780 }
11781   [(set (attr "type")
11782      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11783                           (const_int 0))
11784                       (match_operand 0 "register_operand" ""))
11785                  (match_operand 2 "const1_operand" ""))
11786               (const_string "alu")
11787            ]
11788            (const_string "ishift")))
11789    (set_attr "mode" "QI")])
11790
11791 ;; See comment above `ashldi3' about how this works.
11792
11793 (define_expand "ashrti3"
11794   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11795                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11796                                 (match_operand:QI 2 "nonmemory_operand" "")))
11797               (clobber (reg:CC FLAGS_REG))])]
11798   "TARGET_64BIT"
11799 {
11800   if (! immediate_operand (operands[2], QImode))
11801     {
11802       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11803       DONE;
11804     }
11805   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11806   DONE;
11807 })
11808
11809 (define_insn "ashrti3_1"
11810   [(set (match_operand:TI 0 "register_operand" "=r")
11811         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11812                      (match_operand:QI 2 "register_operand" "c")))
11813    (clobber (match_scratch:DI 3 "=&r"))
11814    (clobber (reg:CC FLAGS_REG))]
11815   "TARGET_64BIT"
11816   "#"
11817   [(set_attr "type" "multi")])
11818
11819 (define_insn "*ashrti3_2"
11820   [(set (match_operand:TI 0 "register_operand" "=r")
11821         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11822                      (match_operand:QI 2 "immediate_operand" "O")))
11823    (clobber (reg:CC FLAGS_REG))]
11824   "TARGET_64BIT"
11825   "#"
11826   [(set_attr "type" "multi")])
11827
11828 (define_split
11829   [(set (match_operand:TI 0 "register_operand" "")
11830         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11831                      (match_operand:QI 2 "register_operand" "")))
11832    (clobber (match_scratch:DI 3 ""))
11833    (clobber (reg:CC FLAGS_REG))]
11834   "TARGET_64BIT && reload_completed"
11835   [(const_int 0)]
11836   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11837
11838 (define_split
11839   [(set (match_operand:TI 0 "register_operand" "")
11840         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11841                      (match_operand:QI 2 "immediate_operand" "")))
11842    (clobber (reg:CC FLAGS_REG))]
11843   "TARGET_64BIT && reload_completed"
11844   [(const_int 0)]
11845   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11846
11847 (define_insn "x86_64_shrd"
11848   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11849         (ior:DI (ashiftrt:DI (match_dup 0)
11850                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11851                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11852                   (minus:QI (const_int 64) (match_dup 2)))))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "TARGET_64BIT"
11855   "@
11856    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11857    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11858   [(set_attr "type" "ishift")
11859    (set_attr "prefix_0f" "1")
11860    (set_attr "mode" "DI")
11861    (set_attr "athlon_decode" "vector")
11862    (set_attr "amdfam10_decode" "vector")])
11863
11864 (define_expand "ashrdi3"
11865   [(set (match_operand:DI 0 "shiftdi_operand" "")
11866         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11867                      (match_operand:QI 2 "nonmemory_operand" "")))]
11868   ""
11869   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11870
11871 (define_insn "*ashrdi3_63_rex64"
11872   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11873         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11874                      (match_operand:DI 2 "const_int_operand" "i,i")))
11875    (clobber (reg:CC FLAGS_REG))]
11876   "TARGET_64BIT && INTVAL (operands[2]) == 63
11877    && (TARGET_USE_CLTD || optimize_size)
11878    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11879   "@
11880    {cqto|cqo}
11881    sar{q}\t{%2, %0|%0, %2}"
11882   [(set_attr "type" "imovx,ishift")
11883    (set_attr "prefix_0f" "0,*")
11884    (set_attr "length_immediate" "0,*")
11885    (set_attr "modrm" "0,1")
11886    (set_attr "mode" "DI")])
11887
11888 (define_insn "*ashrdi3_1_one_bit_rex64"
11889   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11890         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11891                      (match_operand:QI 2 "const1_operand" "")))
11892    (clobber (reg:CC FLAGS_REG))]
11893   "TARGET_64BIT
11894    && (TARGET_SHIFT1 || optimize_size)
11895    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11896   "sar{q}\t%0"
11897   [(set_attr "type" "ishift")
11898    (set (attr "length")
11899      (if_then_else (match_operand:DI 0 "register_operand" "")
11900         (const_string "2")
11901         (const_string "*")))])
11902
11903 (define_insn "*ashrdi3_1_rex64"
11904   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11905         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11906                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11909   "@
11910    sar{q}\t{%2, %0|%0, %2}
11911    sar{q}\t{%b2, %0|%0, %b2}"
11912   [(set_attr "type" "ishift")
11913    (set_attr "mode" "DI")])
11914
11915 ;; This pattern can't accept a variable shift count, since shifts by
11916 ;; zero don't affect the flags.  We assume that shifts by constant
11917 ;; zero are optimized away.
11918 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11919   [(set (reg FLAGS_REG)
11920         (compare
11921           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11922                        (match_operand:QI 2 "const1_operand" ""))
11923           (const_int 0)))
11924    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11925         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11926   "TARGET_64BIT
11927    && (TARGET_SHIFT1 || optimize_size)
11928    && ix86_match_ccmode (insn, CCGOCmode)
11929    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11930   "sar{q}\t%0"
11931   [(set_attr "type" "ishift")
11932    (set (attr "length")
11933      (if_then_else (match_operand:DI 0 "register_operand" "")
11934         (const_string "2")
11935         (const_string "*")))])
11936
11937 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11938   [(set (reg FLAGS_REG)
11939         (compare
11940           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11941                        (match_operand:QI 2 "const1_operand" ""))
11942           (const_int 0)))
11943    (clobber (match_scratch:DI 0 "=r"))]
11944   "TARGET_64BIT
11945    && (TARGET_SHIFT1 || optimize_size)
11946    && ix86_match_ccmode (insn, CCGOCmode)
11947    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11948   "sar{q}\t%0"
11949   [(set_attr "type" "ishift")
11950    (set_attr "length" "2")])
11951
11952 ;; This pattern can't accept a variable shift count, since shifts by
11953 ;; zero don't affect the flags.  We assume that shifts by constant
11954 ;; zero are optimized away.
11955 (define_insn "*ashrdi3_cmp_rex64"
11956   [(set (reg FLAGS_REG)
11957         (compare
11958           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11959                        (match_operand:QI 2 "const_int_operand" "n"))
11960           (const_int 0)))
11961    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11962         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11963   "TARGET_64BIT
11964    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11965    && ix86_match_ccmode (insn, CCGOCmode)
11966    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11967   "sar{q}\t{%2, %0|%0, %2}"
11968   [(set_attr "type" "ishift")
11969    (set_attr "mode" "DI")])
11970
11971 (define_insn "*ashrdi3_cconly_rex64"
11972   [(set (reg FLAGS_REG)
11973         (compare
11974           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11975                        (match_operand:QI 2 "const_int_operand" "n"))
11976           (const_int 0)))
11977    (clobber (match_scratch:DI 0 "=r"))]
11978   "TARGET_64BIT
11979    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11980    && ix86_match_ccmode (insn, CCGOCmode)
11981    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11982   "sar{q}\t{%2, %0|%0, %2}"
11983   [(set_attr "type" "ishift")
11984    (set_attr "mode" "DI")])
11985
11986 (define_insn "*ashrdi3_1"
11987   [(set (match_operand:DI 0 "register_operand" "=r")
11988         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11989                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "!TARGET_64BIT"
11992   "#"
11993   [(set_attr "type" "multi")])
11994
11995 ;; By default we don't ask for a scratch register, because when DImode
11996 ;; values are manipulated, registers are already at a premium.  But if
11997 ;; we have one handy, we won't turn it away.
11998 (define_peephole2
11999   [(match_scratch:SI 3 "r")
12000    (parallel [(set (match_operand:DI 0 "register_operand" "")
12001                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12002                                 (match_operand:QI 2 "nonmemory_operand" "")))
12003               (clobber (reg:CC FLAGS_REG))])
12004    (match_dup 3)]
12005   "!TARGET_64BIT && TARGET_CMOVE"
12006   [(const_int 0)]
12007   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12008
12009 (define_split
12010   [(set (match_operand:DI 0 "register_operand" "")
12011         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12012                      (match_operand:QI 2 "nonmemory_operand" "")))
12013    (clobber (reg:CC FLAGS_REG))]
12014   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12015                      ? epilogue_completed : reload_completed)"
12016   [(const_int 0)]
12017   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12018
12019 (define_insn "x86_shrd_1"
12020   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12021         (ior:SI (ashiftrt:SI (match_dup 0)
12022                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12023                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12024                   (minus:QI (const_int 32) (match_dup 2)))))
12025    (clobber (reg:CC FLAGS_REG))]
12026   ""
12027   "@
12028    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12029    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12030   [(set_attr "type" "ishift")
12031    (set_attr "prefix_0f" "1")
12032    (set_attr "pent_pair" "np")
12033    (set_attr "mode" "SI")])
12034
12035 (define_expand "x86_shift_adj_3"
12036   [(use (match_operand:SI 0 "register_operand" ""))
12037    (use (match_operand:SI 1 "register_operand" ""))
12038    (use (match_operand:QI 2 "register_operand" ""))]
12039   ""
12040 {
12041   rtx label = gen_label_rtx ();
12042   rtx tmp;
12043
12044   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12045
12046   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12047   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12048   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12049                               gen_rtx_LABEL_REF (VOIDmode, label),
12050                               pc_rtx);
12051   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12052   JUMP_LABEL (tmp) = label;
12053
12054   emit_move_insn (operands[0], operands[1]);
12055   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12056
12057   emit_label (label);
12058   LABEL_NUSES (label) = 1;
12059
12060   DONE;
12061 })
12062
12063 (define_insn "ashrsi3_31"
12064   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12065         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12066                      (match_operand:SI 2 "const_int_operand" "i,i")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12069    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12070   "@
12071    {cltd|cdq}
12072    sar{l}\t{%2, %0|%0, %2}"
12073   [(set_attr "type" "imovx,ishift")
12074    (set_attr "prefix_0f" "0,*")
12075    (set_attr "length_immediate" "0,*")
12076    (set_attr "modrm" "0,1")
12077    (set_attr "mode" "SI")])
12078
12079 (define_insn "*ashrsi3_31_zext"
12080   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12081         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12082                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12085    && INTVAL (operands[2]) == 31
12086    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12087   "@
12088    {cltd|cdq}
12089    sar{l}\t{%2, %k0|%k0, %2}"
12090   [(set_attr "type" "imovx,ishift")
12091    (set_attr "prefix_0f" "0,*")
12092    (set_attr "length_immediate" "0,*")
12093    (set_attr "modrm" "0,1")
12094    (set_attr "mode" "SI")])
12095
12096 (define_expand "ashrsi3"
12097   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12098         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12099                      (match_operand:QI 2 "nonmemory_operand" "")))
12100    (clobber (reg:CC FLAGS_REG))]
12101   ""
12102   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12103
12104 (define_insn "*ashrsi3_1_one_bit"
12105   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12106         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12107                      (match_operand:QI 2 "const1_operand" "")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "(TARGET_SHIFT1 || optimize_size)
12110    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12111   "sar{l}\t%0"
12112   [(set_attr "type" "ishift")
12113    (set (attr "length")
12114      (if_then_else (match_operand:SI 0 "register_operand" "")
12115         (const_string "2")
12116         (const_string "*")))])
12117
12118 (define_insn "*ashrsi3_1_one_bit_zext"
12119   [(set (match_operand:DI 0 "register_operand" "=r")
12120         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12121                                      (match_operand:QI 2 "const1_operand" ""))))
12122    (clobber (reg:CC FLAGS_REG))]
12123   "TARGET_64BIT
12124    && (TARGET_SHIFT1 || optimize_size)
12125    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12126   "sar{l}\t%k0"
12127   [(set_attr "type" "ishift")
12128    (set_attr "length" "2")])
12129
12130 (define_insn "*ashrsi3_1"
12131   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12132         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12133                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134    (clobber (reg:CC FLAGS_REG))]
12135   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12136   "@
12137    sar{l}\t{%2, %0|%0, %2}
12138    sar{l}\t{%b2, %0|%0, %b2}"
12139   [(set_attr "type" "ishift")
12140    (set_attr "mode" "SI")])
12141
12142 (define_insn "*ashrsi3_1_zext"
12143   [(set (match_operand:DI 0 "register_operand" "=r,r")
12144         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12145                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12148   "@
12149    sar{l}\t{%2, %k0|%k0, %2}
12150    sar{l}\t{%b2, %k0|%k0, %b2}"
12151   [(set_attr "type" "ishift")
12152    (set_attr "mode" "SI")])
12153
12154 ;; This pattern can't accept a variable shift count, since shifts by
12155 ;; zero don't affect the flags.  We assume that shifts by constant
12156 ;; zero are optimized away.
12157 (define_insn "*ashrsi3_one_bit_cmp"
12158   [(set (reg FLAGS_REG)
12159         (compare
12160           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161                        (match_operand:QI 2 "const1_operand" ""))
12162           (const_int 0)))
12163    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12164         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12165   "(TARGET_SHIFT1 || optimize_size)
12166    && ix86_match_ccmode (insn, CCGOCmode)
12167    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12168   "sar{l}\t%0"
12169   [(set_attr "type" "ishift")
12170    (set (attr "length")
12171      (if_then_else (match_operand:SI 0 "register_operand" "")
12172         (const_string "2")
12173         (const_string "*")))])
12174
12175 (define_insn "*ashrsi3_one_bit_cconly"
12176   [(set (reg FLAGS_REG)
12177         (compare
12178           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12179                        (match_operand:QI 2 "const1_operand" ""))
12180           (const_int 0)))
12181    (clobber (match_scratch:SI 0 "=r"))]
12182   "(TARGET_SHIFT1 || optimize_size)
12183    && ix86_match_ccmode (insn, CCGOCmode)
12184    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12185   "sar{l}\t%0"
12186   [(set_attr "type" "ishift")
12187    (set_attr "length" "2")])
12188
12189 (define_insn "*ashrsi3_one_bit_cmp_zext"
12190   [(set (reg FLAGS_REG)
12191         (compare
12192           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12193                        (match_operand:QI 2 "const1_operand" ""))
12194           (const_int 0)))
12195    (set (match_operand:DI 0 "register_operand" "=r")
12196         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12197   "TARGET_64BIT
12198    && (TARGET_SHIFT1 || optimize_size)
12199    && ix86_match_ccmode (insn, CCmode)
12200    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12201   "sar{l}\t%k0"
12202   [(set_attr "type" "ishift")
12203    (set_attr "length" "2")])
12204
12205 ;; This pattern can't accept a variable shift count, since shifts by
12206 ;; zero don't affect the flags.  We assume that shifts by constant
12207 ;; zero are optimized away.
12208 (define_insn "*ashrsi3_cmp"
12209   [(set (reg FLAGS_REG)
12210         (compare
12211           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12213           (const_int 0)))
12214    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12215         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12216   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12217    && ix86_match_ccmode (insn, CCGOCmode)
12218    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12219   "sar{l}\t{%2, %0|%0, %2}"
12220   [(set_attr "type" "ishift")
12221    (set_attr "mode" "SI")])
12222
12223 (define_insn "*ashrsi3_cconly"
12224   [(set (reg FLAGS_REG)
12225         (compare
12226           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12228           (const_int 0)))
12229    (clobber (match_scratch:SI 0 "=r"))]
12230   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12231    && ix86_match_ccmode (insn, CCGOCmode)
12232    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12233   "sar{l}\t{%2, %0|%0, %2}"
12234   [(set_attr "type" "ishift")
12235    (set_attr "mode" "SI")])
12236
12237 (define_insn "*ashrsi3_cmp_zext"
12238   [(set (reg FLAGS_REG)
12239         (compare
12240           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12241                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12242           (const_int 0)))
12243    (set (match_operand:DI 0 "register_operand" "=r")
12244         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12245   "TARGET_64BIT
12246    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12247    && ix86_match_ccmode (insn, CCGOCmode)
12248    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12249   "sar{l}\t{%2, %k0|%k0, %2}"
12250   [(set_attr "type" "ishift")
12251    (set_attr "mode" "SI")])
12252
12253 (define_expand "ashrhi3"
12254   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12255         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12256                      (match_operand:QI 2 "nonmemory_operand" "")))
12257    (clobber (reg:CC FLAGS_REG))]
12258   "TARGET_HIMODE_MATH"
12259   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12260
12261 (define_insn "*ashrhi3_1_one_bit"
12262   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12263         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12264                      (match_operand:QI 2 "const1_operand" "")))
12265    (clobber (reg:CC FLAGS_REG))]
12266   "(TARGET_SHIFT1 || optimize_size)
12267    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12268   "sar{w}\t%0"
12269   [(set_attr "type" "ishift")
12270    (set (attr "length")
12271      (if_then_else (match_operand 0 "register_operand" "")
12272         (const_string "2")
12273         (const_string "*")))])
12274
12275 (define_insn "*ashrhi3_1"
12276   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12277         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12278                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12279    (clobber (reg:CC FLAGS_REG))]
12280   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12281   "@
12282    sar{w}\t{%2, %0|%0, %2}
12283    sar{w}\t{%b2, %0|%0, %b2}"
12284   [(set_attr "type" "ishift")
12285    (set_attr "mode" "HI")])
12286
12287 ;; This pattern can't accept a variable shift count, since shifts by
12288 ;; zero don't affect the flags.  We assume that shifts by constant
12289 ;; zero are optimized away.
12290 (define_insn "*ashrhi3_one_bit_cmp"
12291   [(set (reg FLAGS_REG)
12292         (compare
12293           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12294                        (match_operand:QI 2 "const1_operand" ""))
12295           (const_int 0)))
12296    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12297         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12298   "(TARGET_SHIFT1 || optimize_size)
12299    && ix86_match_ccmode (insn, CCGOCmode)
12300    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12301   "sar{w}\t%0"
12302   [(set_attr "type" "ishift")
12303    (set (attr "length")
12304      (if_then_else (match_operand 0 "register_operand" "")
12305         (const_string "2")
12306         (const_string "*")))])
12307
12308 (define_insn "*ashrhi3_one_bit_cconly"
12309   [(set (reg FLAGS_REG)
12310         (compare
12311           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12312                        (match_operand:QI 2 "const1_operand" ""))
12313           (const_int 0)))
12314    (clobber (match_scratch:HI 0 "=r"))]
12315   "(TARGET_SHIFT1 || optimize_size)
12316    && ix86_match_ccmode (insn, CCGOCmode)
12317    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12318   "sar{w}\t%0"
12319   [(set_attr "type" "ishift")
12320    (set_attr "length" "2")])
12321
12322 ;; This pattern can't accept a variable shift count, since shifts by
12323 ;; zero don't affect the flags.  We assume that shifts by constant
12324 ;; zero are optimized away.
12325 (define_insn "*ashrhi3_cmp"
12326   [(set (reg FLAGS_REG)
12327         (compare
12328           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12330           (const_int 0)))
12331    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12332         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12333   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12334    && ix86_match_ccmode (insn, CCGOCmode)
12335    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12336   "sar{w}\t{%2, %0|%0, %2}"
12337   [(set_attr "type" "ishift")
12338    (set_attr "mode" "HI")])
12339
12340 (define_insn "*ashrhi3_cconly"
12341   [(set (reg FLAGS_REG)
12342         (compare
12343           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12344                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12345           (const_int 0)))
12346    (clobber (match_scratch:HI 0 "=r"))]
12347   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12348    && ix86_match_ccmode (insn, CCGOCmode)
12349    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12350   "sar{w}\t{%2, %0|%0, %2}"
12351   [(set_attr "type" "ishift")
12352    (set_attr "mode" "HI")])
12353
12354 (define_expand "ashrqi3"
12355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12356         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12357                      (match_operand:QI 2 "nonmemory_operand" "")))
12358    (clobber (reg:CC FLAGS_REG))]
12359   "TARGET_QIMODE_MATH"
12360   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12361
12362 (define_insn "*ashrqi3_1_one_bit"
12363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12364         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12365                      (match_operand:QI 2 "const1_operand" "")))
12366    (clobber (reg:CC FLAGS_REG))]
12367   "(TARGET_SHIFT1 || optimize_size)
12368    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12369   "sar{b}\t%0"
12370   [(set_attr "type" "ishift")
12371    (set (attr "length")
12372      (if_then_else (match_operand 0 "register_operand" "")
12373         (const_string "2")
12374         (const_string "*")))])
12375
12376 (define_insn "*ashrqi3_1_one_bit_slp"
12377   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12378         (ashiftrt:QI (match_dup 0)
12379                      (match_operand:QI 1 "const1_operand" "")))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12382    && (TARGET_SHIFT1 || optimize_size)
12383    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12384   "sar{b}\t%0"
12385   [(set_attr "type" "ishift1")
12386    (set (attr "length")
12387      (if_then_else (match_operand 0 "register_operand" "")
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*ashrqi3_1"
12392   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12393         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12394                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395    (clobber (reg:CC FLAGS_REG))]
12396   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12397   "@
12398    sar{b}\t{%2, %0|%0, %2}
12399    sar{b}\t{%b2, %0|%0, %b2}"
12400   [(set_attr "type" "ishift")
12401    (set_attr "mode" "QI")])
12402
12403 (define_insn "*ashrqi3_1_slp"
12404   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12405         (ashiftrt:QI (match_dup 0)
12406                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12409    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12410   "@
12411    sar{b}\t{%1, %0|%0, %1}
12412    sar{b}\t{%b1, %0|%0, %b1}"
12413   [(set_attr "type" "ishift1")
12414    (set_attr "mode" "QI")])
12415
12416 ;; This pattern can't accept a variable shift count, since shifts by
12417 ;; zero don't affect the flags.  We assume that shifts by constant
12418 ;; zero are optimized away.
12419 (define_insn "*ashrqi3_one_bit_cmp"
12420   [(set (reg FLAGS_REG)
12421         (compare
12422           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12423                        (match_operand:QI 2 "const1_operand" "I"))
12424           (const_int 0)))
12425    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12426         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12427   "(TARGET_SHIFT1 || optimize_size)
12428    && ix86_match_ccmode (insn, CCGOCmode)
12429    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12430   "sar{b}\t%0"
12431   [(set_attr "type" "ishift")
12432    (set (attr "length")
12433      (if_then_else (match_operand 0 "register_operand" "")
12434         (const_string "2")
12435         (const_string "*")))])
12436
12437 (define_insn "*ashrqi3_one_bit_cconly"
12438   [(set (reg FLAGS_REG)
12439         (compare
12440           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441                        (match_operand:QI 2 "const1_operand" "I"))
12442           (const_int 0)))
12443    (clobber (match_scratch:QI 0 "=q"))]
12444   "(TARGET_SHIFT1 || optimize_size)
12445    && ix86_match_ccmode (insn, CCGOCmode)
12446    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12447   "sar{b}\t%0"
12448   [(set_attr "type" "ishift")
12449    (set_attr "length" "2")])
12450
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags.  We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrqi3_cmp"
12455   [(set (reg FLAGS_REG)
12456         (compare
12457           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12458                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12459           (const_int 0)))
12460    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12461         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12462   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12463    && ix86_match_ccmode (insn, CCGOCmode)
12464    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12465   "sar{b}\t{%2, %0|%0, %2}"
12466   [(set_attr "type" "ishift")
12467    (set_attr "mode" "QI")])
12468
12469 (define_insn "*ashrqi3_cconly"
12470   [(set (reg FLAGS_REG)
12471         (compare
12472           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12473                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12474           (const_int 0)))
12475    (clobber (match_scratch:QI 0 "=q"))]
12476   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12477    && ix86_match_ccmode (insn, CCGOCmode)
12478    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12479   "sar{b}\t{%2, %0|%0, %2}"
12480   [(set_attr "type" "ishift")
12481    (set_attr "mode" "QI")])
12482
12483 \f
12484 ;; Logical shift instructions
12485
12486 ;; See comment above `ashldi3' about how this works.
12487
12488 (define_expand "lshrti3"
12489   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12490                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12491                                 (match_operand:QI 2 "nonmemory_operand" "")))
12492               (clobber (reg:CC FLAGS_REG))])]
12493   "TARGET_64BIT"
12494 {
12495   if (! immediate_operand (operands[2], QImode))
12496     {
12497       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12498       DONE;
12499     }
12500   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12501   DONE;
12502 })
12503
12504 (define_insn "lshrti3_1"
12505   [(set (match_operand:TI 0 "register_operand" "=r")
12506         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12507                      (match_operand:QI 2 "register_operand" "c")))
12508    (clobber (match_scratch:DI 3 "=&r"))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "TARGET_64BIT"
12511   "#"
12512   [(set_attr "type" "multi")])
12513
12514 ;; This pattern must be defined before *lshrti3_2 to prevent
12515 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12516
12517 (define_insn "sse2_lshrti3"
12518   [(set (match_operand:TI 0 "register_operand" "=x")
12519         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12520                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12521   "TARGET_SSE2"
12522 {
12523   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12524   return "psrldq\t{%2, %0|%0, %2}";
12525 }
12526   [(set_attr "type" "sseishft")
12527    (set_attr "prefix_data16" "1")
12528    (set_attr "mode" "TI")])
12529
12530 (define_insn "*lshrti3_2"
12531   [(set (match_operand:TI 0 "register_operand" "=r")
12532         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12533                      (match_operand:QI 2 "immediate_operand" "O")))
12534    (clobber (reg:CC FLAGS_REG))]
12535   "TARGET_64BIT"
12536   "#"
12537   [(set_attr "type" "multi")])
12538
12539 (define_split
12540   [(set (match_operand:TI 0 "register_operand" "")
12541         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12542                      (match_operand:QI 2 "register_operand" "")))
12543    (clobber (match_scratch:DI 3 ""))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "TARGET_64BIT && reload_completed"
12546   [(const_int 0)]
12547   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12548
12549 (define_split
12550   [(set (match_operand:TI 0 "register_operand" "")
12551         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12552                      (match_operand:QI 2 "immediate_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_64BIT && reload_completed"
12555   [(const_int 0)]
12556   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12557
12558 (define_expand "lshrdi3"
12559   [(set (match_operand:DI 0 "shiftdi_operand" "")
12560         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12561                      (match_operand:QI 2 "nonmemory_operand" "")))]
12562   ""
12563   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12564
12565 (define_insn "*lshrdi3_1_one_bit_rex64"
12566   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12567         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12568                      (match_operand:QI 2 "const1_operand" "")))
12569    (clobber (reg:CC FLAGS_REG))]
12570   "TARGET_64BIT
12571    && (TARGET_SHIFT1 || optimize_size)
12572    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12573   "shr{q}\t%0"
12574   [(set_attr "type" "ishift")
12575    (set (attr "length")
12576      (if_then_else (match_operand:DI 0 "register_operand" "")
12577         (const_string "2")
12578         (const_string "*")))])
12579
12580 (define_insn "*lshrdi3_1_rex64"
12581   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12582         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12583                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12584    (clobber (reg:CC FLAGS_REG))]
12585   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12586   "@
12587    shr{q}\t{%2, %0|%0, %2}
12588    shr{q}\t{%b2, %0|%0, %b2}"
12589   [(set_attr "type" "ishift")
12590    (set_attr "mode" "DI")])
12591
12592 ;; This pattern can't accept a variable shift count, since shifts by
12593 ;; zero don't affect the flags.  We assume that shifts by constant
12594 ;; zero are optimized away.
12595 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12596   [(set (reg FLAGS_REG)
12597         (compare
12598           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12599                        (match_operand:QI 2 "const1_operand" ""))
12600           (const_int 0)))
12601    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12602         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12603   "TARGET_64BIT
12604    && (TARGET_SHIFT1 || optimize_size)
12605    && ix86_match_ccmode (insn, CCGOCmode)
12606    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12607   "shr{q}\t%0"
12608   [(set_attr "type" "ishift")
12609    (set (attr "length")
12610      (if_then_else (match_operand:DI 0 "register_operand" "")
12611         (const_string "2")
12612         (const_string "*")))])
12613
12614 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12615   [(set (reg FLAGS_REG)
12616         (compare
12617           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12618                        (match_operand:QI 2 "const1_operand" ""))
12619           (const_int 0)))
12620    (clobber (match_scratch:DI 0 "=r"))]
12621   "TARGET_64BIT
12622    && (TARGET_SHIFT1 || optimize_size)
12623    && ix86_match_ccmode (insn, CCGOCmode)
12624    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12625   "shr{q}\t%0"
12626   [(set_attr "type" "ishift")
12627    (set_attr "length" "2")])
12628
12629 ;; This pattern can't accept a variable shift count, since shifts by
12630 ;; zero don't affect the flags.  We assume that shifts by constant
12631 ;; zero are optimized away.
12632 (define_insn "*lshrdi3_cmp_rex64"
12633   [(set (reg FLAGS_REG)
12634         (compare
12635           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12636                        (match_operand:QI 2 "const_int_operand" "e"))
12637           (const_int 0)))
12638    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12639         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12640   "TARGET_64BIT
12641    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12642    && ix86_match_ccmode (insn, CCGOCmode)
12643    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12644   "shr{q}\t{%2, %0|%0, %2}"
12645   [(set_attr "type" "ishift")
12646    (set_attr "mode" "DI")])
12647
12648 (define_insn "*lshrdi3_cconly_rex64"
12649   [(set (reg FLAGS_REG)
12650         (compare
12651           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12652                        (match_operand:QI 2 "const_int_operand" "e"))
12653           (const_int 0)))
12654    (clobber (match_scratch:DI 0 "=r"))]
12655   "TARGET_64BIT
12656    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12657    && ix86_match_ccmode (insn, CCGOCmode)
12658    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12659   "shr{q}\t{%2, %0|%0, %2}"
12660   [(set_attr "type" "ishift")
12661    (set_attr "mode" "DI")])
12662
12663 (define_insn "*lshrdi3_1"
12664   [(set (match_operand:DI 0 "register_operand" "=r")
12665         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12666                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12667    (clobber (reg:CC FLAGS_REG))]
12668   "!TARGET_64BIT"
12669   "#"
12670   [(set_attr "type" "multi")])
12671
12672 ;; By default we don't ask for a scratch register, because when DImode
12673 ;; values are manipulated, registers are already at a premium.  But if
12674 ;; we have one handy, we won't turn it away.
12675 (define_peephole2
12676   [(match_scratch:SI 3 "r")
12677    (parallel [(set (match_operand:DI 0 "register_operand" "")
12678                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12679                                 (match_operand:QI 2 "nonmemory_operand" "")))
12680               (clobber (reg:CC FLAGS_REG))])
12681    (match_dup 3)]
12682   "!TARGET_64BIT && TARGET_CMOVE"
12683   [(const_int 0)]
12684   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12685
12686 (define_split
12687   [(set (match_operand:DI 0 "register_operand" "")
12688         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12689                      (match_operand:QI 2 "nonmemory_operand" "")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12692                      ? epilogue_completed : reload_completed)"
12693   [(const_int 0)]
12694   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12695
12696 (define_expand "lshrsi3"
12697   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12698         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12699                      (match_operand:QI 2 "nonmemory_operand" "")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   ""
12702   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12703
12704 (define_insn "*lshrsi3_1_one_bit"
12705   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12706         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12707                      (match_operand:QI 2 "const1_operand" "")))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "(TARGET_SHIFT1 || optimize_size)
12710    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12711   "shr{l}\t%0"
12712   [(set_attr "type" "ishift")
12713    (set (attr "length")
12714      (if_then_else (match_operand:SI 0 "register_operand" "")
12715         (const_string "2")
12716         (const_string "*")))])
12717
12718 (define_insn "*lshrsi3_1_one_bit_zext"
12719   [(set (match_operand:DI 0 "register_operand" "=r")
12720         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12721                      (match_operand:QI 2 "const1_operand" "")))
12722    (clobber (reg:CC FLAGS_REG))]
12723   "TARGET_64BIT
12724    && (TARGET_SHIFT1 || optimize_size)
12725    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12726   "shr{l}\t%k0"
12727   [(set_attr "type" "ishift")
12728    (set_attr "length" "2")])
12729
12730 (define_insn "*lshrsi3_1"
12731   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12732         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12733                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12736   "@
12737    shr{l}\t{%2, %0|%0, %2}
12738    shr{l}\t{%b2, %0|%0, %b2}"
12739   [(set_attr "type" "ishift")
12740    (set_attr "mode" "SI")])
12741
12742 (define_insn "*lshrsi3_1_zext"
12743   [(set (match_operand:DI 0 "register_operand" "=r,r")
12744         (zero_extend:DI
12745           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12746                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12747    (clobber (reg:CC FLAGS_REG))]
12748   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12749   "@
12750    shr{l}\t{%2, %k0|%k0, %2}
12751    shr{l}\t{%b2, %k0|%k0, %b2}"
12752   [(set_attr "type" "ishift")
12753    (set_attr "mode" "SI")])
12754
12755 ;; This pattern can't accept a variable shift count, since shifts by
12756 ;; zero don't affect the flags.  We assume that shifts by constant
12757 ;; zero are optimized away.
12758 (define_insn "*lshrsi3_one_bit_cmp"
12759   [(set (reg FLAGS_REG)
12760         (compare
12761           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12762                        (match_operand:QI 2 "const1_operand" ""))
12763           (const_int 0)))
12764    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12765         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12766   "(TARGET_SHIFT1 || optimize_size)
12767    && ix86_match_ccmode (insn, CCGOCmode)
12768    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12769   "shr{l}\t%0"
12770   [(set_attr "type" "ishift")
12771    (set (attr "length")
12772      (if_then_else (match_operand:SI 0 "register_operand" "")
12773         (const_string "2")
12774         (const_string "*")))])
12775
12776 (define_insn "*lshrsi3_one_bit_cconly"
12777   [(set (reg FLAGS_REG)
12778         (compare
12779           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12780                        (match_operand:QI 2 "const1_operand" ""))
12781           (const_int 0)))
12782    (clobber (match_scratch:SI 0 "=r"))]
12783   "(TARGET_SHIFT1 || optimize_size)
12784    && ix86_match_ccmode (insn, CCGOCmode)
12785    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12786   "shr{l}\t%0"
12787   [(set_attr "type" "ishift")
12788    (set_attr "length" "2")])
12789
12790 (define_insn "*lshrsi3_cmp_one_bit_zext"
12791   [(set (reg FLAGS_REG)
12792         (compare
12793           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12794                        (match_operand:QI 2 "const1_operand" ""))
12795           (const_int 0)))
12796    (set (match_operand:DI 0 "register_operand" "=r")
12797         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12798   "TARGET_64BIT
12799    && (TARGET_SHIFT1 || optimize_size)
12800    && ix86_match_ccmode (insn, CCGOCmode)
12801    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12802   "shr{l}\t%k0"
12803   [(set_attr "type" "ishift")
12804    (set_attr "length" "2")])
12805
12806 ;; This pattern can't accept a variable shift count, since shifts by
12807 ;; zero don't affect the flags.  We assume that shifts by constant
12808 ;; zero are optimized away.
12809 (define_insn "*lshrsi3_cmp"
12810   [(set (reg FLAGS_REG)
12811         (compare
12812           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12813                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12814           (const_int 0)))
12815    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12816         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12817   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12818    && ix86_match_ccmode (insn, CCGOCmode)
12819    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12820   "shr{l}\t{%2, %0|%0, %2}"
12821   [(set_attr "type" "ishift")
12822    (set_attr "mode" "SI")])
12823
12824 (define_insn "*lshrsi3_cconly"
12825   [(set (reg FLAGS_REG)
12826       (compare
12827         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12828                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12829         (const_int 0)))
12830    (clobber (match_scratch:SI 0 "=r"))]
12831   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12832    && ix86_match_ccmode (insn, CCGOCmode)
12833    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12834   "shr{l}\t{%2, %0|%0, %2}"
12835   [(set_attr "type" "ishift")
12836    (set_attr "mode" "SI")])
12837
12838 (define_insn "*lshrsi3_cmp_zext"
12839   [(set (reg FLAGS_REG)
12840         (compare
12841           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12842                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12843           (const_int 0)))
12844    (set (match_operand:DI 0 "register_operand" "=r")
12845         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12846   "TARGET_64BIT
12847    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12848    && ix86_match_ccmode (insn, CCGOCmode)
12849    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12850   "shr{l}\t{%2, %k0|%k0, %2}"
12851   [(set_attr "type" "ishift")
12852    (set_attr "mode" "SI")])
12853
12854 (define_expand "lshrhi3"
12855   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12856         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12857                      (match_operand:QI 2 "nonmemory_operand" "")))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "TARGET_HIMODE_MATH"
12860   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12861
12862 (define_insn "*lshrhi3_1_one_bit"
12863   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12864         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12865                      (match_operand:QI 2 "const1_operand" "")))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "(TARGET_SHIFT1 || optimize_size)
12868    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12869   "shr{w}\t%0"
12870   [(set_attr "type" "ishift")
12871    (set (attr "length")
12872      (if_then_else (match_operand 0 "register_operand" "")
12873         (const_string "2")
12874         (const_string "*")))])
12875
12876 (define_insn "*lshrhi3_1"
12877   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12878         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12882   "@
12883    shr{w}\t{%2, %0|%0, %2}
12884    shr{w}\t{%b2, %0|%0, %b2}"
12885   [(set_attr "type" "ishift")
12886    (set_attr "mode" "HI")])
12887
12888 ;; This pattern can't accept a variable shift count, since shifts by
12889 ;; zero don't affect the flags.  We assume that shifts by constant
12890 ;; zero are optimized away.
12891 (define_insn "*lshrhi3_one_bit_cmp"
12892   [(set (reg FLAGS_REG)
12893         (compare
12894           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12895                        (match_operand:QI 2 "const1_operand" ""))
12896           (const_int 0)))
12897    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12898         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12899   "(TARGET_SHIFT1 || optimize_size)
12900    && ix86_match_ccmode (insn, CCGOCmode)
12901    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12902   "shr{w}\t%0"
12903   [(set_attr "type" "ishift")
12904    (set (attr "length")
12905      (if_then_else (match_operand:SI 0 "register_operand" "")
12906         (const_string "2")
12907         (const_string "*")))])
12908
12909 (define_insn "*lshrhi3_one_bit_cconly"
12910   [(set (reg FLAGS_REG)
12911         (compare
12912           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12913                        (match_operand:QI 2 "const1_operand" ""))
12914           (const_int 0)))
12915    (clobber (match_scratch:HI 0 "=r"))]
12916   "(TARGET_SHIFT1 || optimize_size)
12917    && ix86_match_ccmode (insn, CCGOCmode)
12918    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12919   "shr{w}\t%0"
12920   [(set_attr "type" "ishift")
12921    (set_attr "length" "2")])
12922
12923 ;; This pattern can't accept a variable shift count, since shifts by
12924 ;; zero don't affect the flags.  We assume that shifts by constant
12925 ;; zero are optimized away.
12926 (define_insn "*lshrhi3_cmp"
12927   [(set (reg FLAGS_REG)
12928         (compare
12929           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12930                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12931           (const_int 0)))
12932    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12933         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12934   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12935    && ix86_match_ccmode (insn, CCGOCmode)
12936    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937   "shr{w}\t{%2, %0|%0, %2}"
12938   [(set_attr "type" "ishift")
12939    (set_attr "mode" "HI")])
12940
12941 (define_insn "*lshrhi3_cconly"
12942   [(set (reg FLAGS_REG)
12943         (compare
12944           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12945                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12946           (const_int 0)))
12947    (clobber (match_scratch:HI 0 "=r"))]
12948   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12949    && ix86_match_ccmode (insn, CCGOCmode)
12950    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951   "shr{w}\t{%2, %0|%0, %2}"
12952   [(set_attr "type" "ishift")
12953    (set_attr "mode" "HI")])
12954
12955 (define_expand "lshrqi3"
12956   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12957         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12958                      (match_operand:QI 2 "nonmemory_operand" "")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "TARGET_QIMODE_MATH"
12961   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12962
12963 (define_insn "*lshrqi3_1_one_bit"
12964   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12965         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12966                      (match_operand:QI 2 "const1_operand" "")))
12967    (clobber (reg:CC FLAGS_REG))]
12968   "(TARGET_SHIFT1 || optimize_size)
12969    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12970   "shr{b}\t%0"
12971   [(set_attr "type" "ishift")
12972    (set (attr "length")
12973      (if_then_else (match_operand 0 "register_operand" "")
12974         (const_string "2")
12975         (const_string "*")))])
12976
12977 (define_insn "*lshrqi3_1_one_bit_slp"
12978   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12979         (lshiftrt:QI (match_dup 0)
12980                      (match_operand:QI 1 "const1_operand" "")))
12981    (clobber (reg:CC FLAGS_REG))]
12982   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12983    && (TARGET_SHIFT1 || optimize_size)"
12984   "shr{b}\t%0"
12985   [(set_attr "type" "ishift1")
12986    (set (attr "length")
12987      (if_then_else (match_operand 0 "register_operand" "")
12988         (const_string "2")
12989         (const_string "*")))])
12990
12991 (define_insn "*lshrqi3_1"
12992   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12993         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12994                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12995    (clobber (reg:CC FLAGS_REG))]
12996   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12997   "@
12998    shr{b}\t{%2, %0|%0, %2}
12999    shr{b}\t{%b2, %0|%0, %b2}"
13000   [(set_attr "type" "ishift")
13001    (set_attr "mode" "QI")])
13002
13003 (define_insn "*lshrqi3_1_slp"
13004   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13005         (lshiftrt:QI (match_dup 0)
13006                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13007    (clobber (reg:CC FLAGS_REG))]
13008   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13009    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13010   "@
13011    shr{b}\t{%1, %0|%0, %1}
13012    shr{b}\t{%b1, %0|%0, %b1}"
13013   [(set_attr "type" "ishift1")
13014    (set_attr "mode" "QI")])
13015
13016 ;; This pattern can't accept a variable shift count, since shifts by
13017 ;; zero don't affect the flags.  We assume that shifts by constant
13018 ;; zero are optimized away.
13019 (define_insn "*lshrqi2_one_bit_cmp"
13020   [(set (reg FLAGS_REG)
13021         (compare
13022           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13023                        (match_operand:QI 2 "const1_operand" ""))
13024           (const_int 0)))
13025    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13026         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13027   "(TARGET_SHIFT1 || optimize_size)
13028    && ix86_match_ccmode (insn, CCGOCmode)
13029    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13030   "shr{b}\t%0"
13031   [(set_attr "type" "ishift")
13032    (set (attr "length")
13033      (if_then_else (match_operand:SI 0 "register_operand" "")
13034         (const_string "2")
13035         (const_string "*")))])
13036
13037 (define_insn "*lshrqi2_one_bit_cconly"
13038   [(set (reg FLAGS_REG)
13039         (compare
13040           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13041                        (match_operand:QI 2 "const1_operand" ""))
13042           (const_int 0)))
13043    (clobber (match_scratch:QI 0 "=q"))]
13044   "(TARGET_SHIFT1 || optimize_size)
13045    && ix86_match_ccmode (insn, CCGOCmode)
13046    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13047   "shr{b}\t%0"
13048   [(set_attr "type" "ishift")
13049    (set_attr "length" "2")])
13050
13051 ;; This pattern can't accept a variable shift count, since shifts by
13052 ;; zero don't affect the flags.  We assume that shifts by constant
13053 ;; zero are optimized away.
13054 (define_insn "*lshrqi2_cmp"
13055   [(set (reg FLAGS_REG)
13056         (compare
13057           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13058                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13059           (const_int 0)))
13060    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13061         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13062   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13063    && ix86_match_ccmode (insn, CCGOCmode)
13064    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13065   "shr{b}\t{%2, %0|%0, %2}"
13066   [(set_attr "type" "ishift")
13067    (set_attr "mode" "QI")])
13068
13069 (define_insn "*lshrqi2_cconly"
13070   [(set (reg FLAGS_REG)
13071         (compare
13072           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13073                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13074           (const_int 0)))
13075    (clobber (match_scratch:QI 0 "=q"))]
13076   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13077    && ix86_match_ccmode (insn, CCGOCmode)
13078    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13079   "shr{b}\t{%2, %0|%0, %2}"
13080   [(set_attr "type" "ishift")
13081    (set_attr "mode" "QI")])
13082 \f
13083 ;; Rotate instructions
13084
13085 (define_expand "rotldi3"
13086   [(set (match_operand:DI 0 "shiftdi_operand" "")
13087         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13088                    (match_operand:QI 2 "nonmemory_operand" "")))
13089    (clobber (reg:CC FLAGS_REG))]
13090  ""
13091 {
13092   if (TARGET_64BIT)
13093     {
13094       ix86_expand_binary_operator (ROTATE, DImode, operands);
13095       DONE;
13096     }
13097   if (!const_1_to_31_operand (operands[2], VOIDmode))
13098     FAIL;
13099   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13100   DONE;
13101 })
13102
13103 ;; Implement rotation using two double-precision shift instructions
13104 ;; and a scratch register.
13105 (define_insn_and_split "ix86_rotldi3"
13106  [(set (match_operand:DI 0 "register_operand" "=r")
13107        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13108                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13109   (clobber (reg:CC FLAGS_REG))
13110   (clobber (match_scratch:SI 3 "=&r"))]
13111  "!TARGET_64BIT"
13112  ""
13113  "&& reload_completed"
13114  [(set (match_dup 3) (match_dup 4))
13115   (parallel
13116    [(set (match_dup 4)
13117          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13118                  (lshiftrt:SI (match_dup 5)
13119                               (minus:QI (const_int 32) (match_dup 2)))))
13120     (clobber (reg:CC FLAGS_REG))])
13121   (parallel
13122    [(set (match_dup 5)
13123          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13124                  (lshiftrt:SI (match_dup 3)
13125                               (minus:QI (const_int 32) (match_dup 2)))))
13126     (clobber (reg:CC FLAGS_REG))])]
13127  "split_di (operands, 1, operands + 4, operands + 5);")
13128
13129 (define_insn "*rotlsi3_1_one_bit_rex64"
13130   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13131         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13132                    (match_operand:QI 2 "const1_operand" "")))
13133    (clobber (reg:CC FLAGS_REG))]
13134   "TARGET_64BIT
13135    && (TARGET_SHIFT1 || optimize_size)
13136    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13137   "rol{q}\t%0"
13138   [(set_attr "type" "rotate")
13139    (set (attr "length")
13140      (if_then_else (match_operand:DI 0 "register_operand" "")
13141         (const_string "2")
13142         (const_string "*")))])
13143
13144 (define_insn "*rotldi3_1_rex64"
13145   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13146         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13147                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13148    (clobber (reg:CC FLAGS_REG))]
13149   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13150   "@
13151    rol{q}\t{%2, %0|%0, %2}
13152    rol{q}\t{%b2, %0|%0, %b2}"
13153   [(set_attr "type" "rotate")
13154    (set_attr "mode" "DI")])
13155
13156 (define_expand "rotlsi3"
13157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13158         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13159                    (match_operand:QI 2 "nonmemory_operand" "")))
13160    (clobber (reg:CC FLAGS_REG))]
13161   ""
13162   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13163
13164 (define_insn "*rotlsi3_1_one_bit"
13165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13166         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13167                    (match_operand:QI 2 "const1_operand" "")))
13168    (clobber (reg:CC FLAGS_REG))]
13169   "(TARGET_SHIFT1 || optimize_size)
13170    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13171   "rol{l}\t%0"
13172   [(set_attr "type" "rotate")
13173    (set (attr "length")
13174      (if_then_else (match_operand:SI 0 "register_operand" "")
13175         (const_string "2")
13176         (const_string "*")))])
13177
13178 (define_insn "*rotlsi3_1_one_bit_zext"
13179   [(set (match_operand:DI 0 "register_operand" "=r")
13180         (zero_extend:DI
13181           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13182                      (match_operand:QI 2 "const1_operand" ""))))
13183    (clobber (reg:CC FLAGS_REG))]
13184   "TARGET_64BIT
13185    && (TARGET_SHIFT1 || optimize_size)
13186    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13187   "rol{l}\t%k0"
13188   [(set_attr "type" "rotate")
13189    (set_attr "length" "2")])
13190
13191 (define_insn "*rotlsi3_1"
13192   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13193         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13194                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13195    (clobber (reg:CC FLAGS_REG))]
13196   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13197   "@
13198    rol{l}\t{%2, %0|%0, %2}
13199    rol{l}\t{%b2, %0|%0, %b2}"
13200   [(set_attr "type" "rotate")
13201    (set_attr "mode" "SI")])
13202
13203 (define_insn "*rotlsi3_1_zext"
13204   [(set (match_operand:DI 0 "register_operand" "=r,r")
13205         (zero_extend:DI
13206           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13207                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13208    (clobber (reg:CC FLAGS_REG))]
13209   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13210   "@
13211    rol{l}\t{%2, %k0|%k0, %2}
13212    rol{l}\t{%b2, %k0|%k0, %b2}"
13213   [(set_attr "type" "rotate")
13214    (set_attr "mode" "SI")])
13215
13216 (define_expand "rotlhi3"
13217   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13218         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13219                    (match_operand:QI 2 "nonmemory_operand" "")))
13220    (clobber (reg:CC FLAGS_REG))]
13221   "TARGET_HIMODE_MATH"
13222   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13223
13224 (define_insn "*rotlhi3_1_one_bit"
13225   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13226         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13227                    (match_operand:QI 2 "const1_operand" "")))
13228    (clobber (reg:CC FLAGS_REG))]
13229   "(TARGET_SHIFT1 || optimize_size)
13230    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13231   "rol{w}\t%0"
13232   [(set_attr "type" "rotate")
13233    (set (attr "length")
13234      (if_then_else (match_operand 0 "register_operand" "")
13235         (const_string "2")
13236         (const_string "*")))])
13237
13238 (define_insn "*rotlhi3_1"
13239   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13240         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13241                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13242    (clobber (reg:CC FLAGS_REG))]
13243   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13244   "@
13245    rol{w}\t{%2, %0|%0, %2}
13246    rol{w}\t{%b2, %0|%0, %b2}"
13247   [(set_attr "type" "rotate")
13248    (set_attr "mode" "HI")])
13249
13250 (define_split
13251  [(set (match_operand:HI 0 "register_operand" "")
13252        (rotate:HI (match_dup 0) (const_int 8)))
13253   (clobber (reg:CC FLAGS_REG))]
13254  "reload_completed"
13255  [(parallel [(set (strict_low_part (match_dup 0))
13256                   (bswap:HI (match_dup 0)))
13257              (clobber (reg:CC FLAGS_REG))])]
13258  "")
13259
13260 (define_expand "rotlqi3"
13261   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13262         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13263                    (match_operand:QI 2 "nonmemory_operand" "")))
13264    (clobber (reg:CC FLAGS_REG))]
13265   "TARGET_QIMODE_MATH"
13266   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13267
13268 (define_insn "*rotlqi3_1_one_bit_slp"
13269   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13270         (rotate:QI (match_dup 0)
13271                    (match_operand:QI 1 "const1_operand" "")))
13272    (clobber (reg:CC FLAGS_REG))]
13273   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13274    && (TARGET_SHIFT1 || optimize_size)"
13275   "rol{b}\t%0"
13276   [(set_attr "type" "rotate1")
13277    (set (attr "length")
13278      (if_then_else (match_operand 0 "register_operand" "")
13279         (const_string "2")
13280         (const_string "*")))])
13281
13282 (define_insn "*rotlqi3_1_one_bit"
13283   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13284         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13285                    (match_operand:QI 2 "const1_operand" "")))
13286    (clobber (reg:CC FLAGS_REG))]
13287   "(TARGET_SHIFT1 || optimize_size)
13288    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13289   "rol{b}\t%0"
13290   [(set_attr "type" "rotate")
13291    (set (attr "length")
13292      (if_then_else (match_operand 0 "register_operand" "")
13293         (const_string "2")
13294         (const_string "*")))])
13295
13296 (define_insn "*rotlqi3_1_slp"
13297   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13298         (rotate:QI (match_dup 0)
13299                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13300    (clobber (reg:CC FLAGS_REG))]
13301   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13302    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13303   "@
13304    rol{b}\t{%1, %0|%0, %1}
13305    rol{b}\t{%b1, %0|%0, %b1}"
13306   [(set_attr "type" "rotate1")
13307    (set_attr "mode" "QI")])
13308
13309 (define_insn "*rotlqi3_1"
13310   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13311         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13312                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13313    (clobber (reg:CC FLAGS_REG))]
13314   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13315   "@
13316    rol{b}\t{%2, %0|%0, %2}
13317    rol{b}\t{%b2, %0|%0, %b2}"
13318   [(set_attr "type" "rotate")
13319    (set_attr "mode" "QI")])
13320
13321 (define_expand "rotrdi3"
13322   [(set (match_operand:DI 0 "shiftdi_operand" "")
13323         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13324                    (match_operand:QI 2 "nonmemory_operand" "")))
13325    (clobber (reg:CC FLAGS_REG))]
13326  ""
13327 {
13328   if (TARGET_64BIT)
13329     {
13330       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13331       DONE;
13332     }
13333   if (!const_1_to_31_operand (operands[2], VOIDmode))
13334     FAIL;
13335   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13336   DONE;
13337 })
13338
13339 ;; Implement rotation using two double-precision shift instructions
13340 ;; and a scratch register.
13341 (define_insn_and_split "ix86_rotrdi3"
13342  [(set (match_operand:DI 0 "register_operand" "=r")
13343        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13344                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13345   (clobber (reg:CC FLAGS_REG))
13346   (clobber (match_scratch:SI 3 "=&r"))]
13347  "!TARGET_64BIT"
13348  ""
13349  "&& reload_completed"
13350  [(set (match_dup 3) (match_dup 4))
13351   (parallel
13352    [(set (match_dup 4)
13353          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13354                  (ashift:SI (match_dup 5)
13355                             (minus:QI (const_int 32) (match_dup 2)))))
13356     (clobber (reg:CC FLAGS_REG))])
13357   (parallel
13358    [(set (match_dup 5)
13359          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13360                  (ashift:SI (match_dup 3)
13361                             (minus:QI (const_int 32) (match_dup 2)))))
13362     (clobber (reg:CC FLAGS_REG))])]
13363  "split_di (operands, 1, operands + 4, operands + 5);")
13364
13365 (define_insn "*rotrdi3_1_one_bit_rex64"
13366   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13367         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13368                      (match_operand:QI 2 "const1_operand" "")))
13369    (clobber (reg:CC FLAGS_REG))]
13370   "TARGET_64BIT
13371    && (TARGET_SHIFT1 || optimize_size)
13372    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13373   "ror{q}\t%0"
13374   [(set_attr "type" "rotate")
13375    (set (attr "length")
13376      (if_then_else (match_operand:DI 0 "register_operand" "")
13377         (const_string "2")
13378         (const_string "*")))])
13379
13380 (define_insn "*rotrdi3_1_rex64"
13381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13382         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13383                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13384    (clobber (reg:CC FLAGS_REG))]
13385   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13386   "@
13387    ror{q}\t{%2, %0|%0, %2}
13388    ror{q}\t{%b2, %0|%0, %b2}"
13389   [(set_attr "type" "rotate")
13390    (set_attr "mode" "DI")])
13391
13392 (define_expand "rotrsi3"
13393   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13394         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13395                      (match_operand:QI 2 "nonmemory_operand" "")))
13396    (clobber (reg:CC FLAGS_REG))]
13397   ""
13398   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13399
13400 (define_insn "*rotrsi3_1_one_bit"
13401   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13402         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13403                      (match_operand:QI 2 "const1_operand" "")))
13404    (clobber (reg:CC FLAGS_REG))]
13405   "(TARGET_SHIFT1 || optimize_size)
13406    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13407   "ror{l}\t%0"
13408   [(set_attr "type" "rotate")
13409    (set (attr "length")
13410      (if_then_else (match_operand:SI 0 "register_operand" "")
13411         (const_string "2")
13412         (const_string "*")))])
13413
13414 (define_insn "*rotrsi3_1_one_bit_zext"
13415   [(set (match_operand:DI 0 "register_operand" "=r")
13416         (zero_extend:DI
13417           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13418                        (match_operand:QI 2 "const1_operand" ""))))
13419    (clobber (reg:CC FLAGS_REG))]
13420   "TARGET_64BIT
13421    && (TARGET_SHIFT1 || optimize_size)
13422    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13423   "ror{l}\t%k0"
13424   [(set_attr "type" "rotate")
13425    (set (attr "length")
13426      (if_then_else (match_operand:SI 0 "register_operand" "")
13427         (const_string "2")
13428         (const_string "*")))])
13429
13430 (define_insn "*rotrsi3_1"
13431   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13432         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13433                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13434    (clobber (reg:CC FLAGS_REG))]
13435   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13436   "@
13437    ror{l}\t{%2, %0|%0, %2}
13438    ror{l}\t{%b2, %0|%0, %b2}"
13439   [(set_attr "type" "rotate")
13440    (set_attr "mode" "SI")])
13441
13442 (define_insn "*rotrsi3_1_zext"
13443   [(set (match_operand:DI 0 "register_operand" "=r,r")
13444         (zero_extend:DI
13445           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13446                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13447    (clobber (reg:CC FLAGS_REG))]
13448   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13449   "@
13450    ror{l}\t{%2, %k0|%k0, %2}
13451    ror{l}\t{%b2, %k0|%k0, %b2}"
13452   [(set_attr "type" "rotate")
13453    (set_attr "mode" "SI")])
13454
13455 (define_expand "rotrhi3"
13456   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13457         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13458                      (match_operand:QI 2 "nonmemory_operand" "")))
13459    (clobber (reg:CC FLAGS_REG))]
13460   "TARGET_HIMODE_MATH"
13461   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13462
13463 (define_insn "*rotrhi3_one_bit"
13464   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13465         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13466                      (match_operand:QI 2 "const1_operand" "")))
13467    (clobber (reg:CC FLAGS_REG))]
13468   "(TARGET_SHIFT1 || optimize_size)
13469    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13470   "ror{w}\t%0"
13471   [(set_attr "type" "rotate")
13472    (set (attr "length")
13473      (if_then_else (match_operand 0 "register_operand" "")
13474         (const_string "2")
13475         (const_string "*")))])
13476
13477 (define_insn "*rotrhi3_1"
13478   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13479         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13480                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481    (clobber (reg:CC FLAGS_REG))]
13482   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13483   "@
13484    ror{w}\t{%2, %0|%0, %2}
13485    ror{w}\t{%b2, %0|%0, %b2}"
13486   [(set_attr "type" "rotate")
13487    (set_attr "mode" "HI")])
13488
13489 (define_split
13490  [(set (match_operand:HI 0 "register_operand" "")
13491        (rotatert:HI (match_dup 0) (const_int 8)))
13492   (clobber (reg:CC FLAGS_REG))]
13493  "reload_completed"
13494  [(parallel [(set (strict_low_part (match_dup 0))
13495                   (bswap:HI (match_dup 0)))
13496              (clobber (reg:CC FLAGS_REG))])]
13497  "")
13498
13499 (define_expand "rotrqi3"
13500   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13501         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13502                      (match_operand:QI 2 "nonmemory_operand" "")))
13503    (clobber (reg:CC FLAGS_REG))]
13504   "TARGET_QIMODE_MATH"
13505   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13506
13507 (define_insn "*rotrqi3_1_one_bit"
13508   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13509         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13510                      (match_operand:QI 2 "const1_operand" "")))
13511    (clobber (reg:CC FLAGS_REG))]
13512   "(TARGET_SHIFT1 || optimize_size)
13513    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13514   "ror{b}\t%0"
13515   [(set_attr "type" "rotate")
13516    (set (attr "length")
13517      (if_then_else (match_operand 0 "register_operand" "")
13518         (const_string "2")
13519         (const_string "*")))])
13520
13521 (define_insn "*rotrqi3_1_one_bit_slp"
13522   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13523         (rotatert:QI (match_dup 0)
13524                      (match_operand:QI 1 "const1_operand" "")))
13525    (clobber (reg:CC FLAGS_REG))]
13526   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13527    && (TARGET_SHIFT1 || optimize_size)"
13528   "ror{b}\t%0"
13529   [(set_attr "type" "rotate1")
13530    (set (attr "length")
13531      (if_then_else (match_operand 0 "register_operand" "")
13532         (const_string "2")
13533         (const_string "*")))])
13534
13535 (define_insn "*rotrqi3_1"
13536   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13537         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13538                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13539    (clobber (reg:CC FLAGS_REG))]
13540   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13541   "@
13542    ror{b}\t{%2, %0|%0, %2}
13543    ror{b}\t{%b2, %0|%0, %b2}"
13544   [(set_attr "type" "rotate")
13545    (set_attr "mode" "QI")])
13546
13547 (define_insn "*rotrqi3_1_slp"
13548   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13549         (rotatert:QI (match_dup 0)
13550                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13551    (clobber (reg:CC FLAGS_REG))]
13552   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13553    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13554   "@
13555    ror{b}\t{%1, %0|%0, %1}
13556    ror{b}\t{%b1, %0|%0, %b1}"
13557   [(set_attr "type" "rotate1")
13558    (set_attr "mode" "QI")])
13559 \f
13560 ;; Bit set / bit test instructions
13561
13562 (define_expand "extv"
13563   [(set (match_operand:SI 0 "register_operand" "")
13564         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13565                          (match_operand:SI 2 "const8_operand" "")
13566                          (match_operand:SI 3 "const8_operand" "")))]
13567   ""
13568 {
13569   /* Handle extractions from %ah et al.  */
13570   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13571     FAIL;
13572
13573   /* From mips.md: extract_bit_field doesn't verify that our source
13574      matches the predicate, so check it again here.  */
13575   if (! ext_register_operand (operands[1], VOIDmode))
13576     FAIL;
13577 })
13578
13579 (define_expand "extzv"
13580   [(set (match_operand:SI 0 "register_operand" "")
13581         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13582                          (match_operand:SI 2 "const8_operand" "")
13583                          (match_operand:SI 3 "const8_operand" "")))]
13584   ""
13585 {
13586   /* Handle extractions from %ah et al.  */
13587   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13588     FAIL;
13589
13590   /* From mips.md: extract_bit_field doesn't verify that our source
13591      matches the predicate, so check it again here.  */
13592   if (! ext_register_operand (operands[1], VOIDmode))
13593     FAIL;
13594 })
13595
13596 (define_expand "insv"
13597   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13598                       (match_operand 1 "const8_operand" "")
13599                       (match_operand 2 "const8_operand" ""))
13600         (match_operand 3 "register_operand" ""))]
13601   ""
13602 {
13603   /* Handle insertions to %ah et al.  */
13604   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13605     FAIL;
13606
13607   /* From mips.md: insert_bit_field doesn't verify that our source
13608      matches the predicate, so check it again here.  */
13609   if (! ext_register_operand (operands[0], VOIDmode))
13610     FAIL;
13611
13612   if (TARGET_64BIT)
13613     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13614   else
13615     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13616
13617   DONE;
13618 })
13619
13620 ;; %%% bts, btr, btc, bt.
13621 ;; In general these instructions are *slow* when applied to memory,
13622 ;; since they enforce atomic operation.  When applied to registers,
13623 ;; it depends on the cpu implementation.  They're never faster than
13624 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13625 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13626 ;; within the instruction itself, so operating on bits in the high
13627 ;; 32-bits of a register becomes easier.
13628 ;;
13629 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13630 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13631 ;; negdf respectively, so they can never be disabled entirely.
13632
13633 (define_insn "*btsq"
13634   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13635                          (const_int 1)
13636                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13637         (const_int 1))
13638    (clobber (reg:CC FLAGS_REG))]
13639   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13640   "bts{q} %1,%0"
13641   [(set_attr "type" "alu1")])
13642
13643 (define_insn "*btrq"
13644   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13645                          (const_int 1)
13646                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13647         (const_int 0))
13648    (clobber (reg:CC FLAGS_REG))]
13649   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13650   "btr{q} %1,%0"
13651   [(set_attr "type" "alu1")])
13652
13653 (define_insn "*btcq"
13654   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13655                          (const_int 1)
13656                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13657         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13658    (clobber (reg:CC FLAGS_REG))]
13659   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13660   "btc{q} %1,%0"
13661   [(set_attr "type" "alu1")])
13662
13663 ;; Allow Nocona to avoid these instructions if a register is available.
13664
13665 (define_peephole2
13666   [(match_scratch:DI 2 "r")
13667    (parallel [(set (zero_extract:DI
13668                      (match_operand:DI 0 "register_operand" "")
13669                      (const_int 1)
13670                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13671                    (const_int 1))
13672               (clobber (reg:CC FLAGS_REG))])]
13673   "TARGET_64BIT && !TARGET_USE_BT"
13674   [(const_int 0)]
13675 {
13676   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13677   rtx op1;
13678
13679   if (HOST_BITS_PER_WIDE_INT >= 64)
13680     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13681   else if (i < HOST_BITS_PER_WIDE_INT)
13682     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13683   else
13684     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13685
13686   op1 = immed_double_const (lo, hi, DImode);
13687   if (i >= 31)
13688     {
13689       emit_move_insn (operands[2], op1);
13690       op1 = operands[2];
13691     }
13692
13693   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13694   DONE;
13695 })
13696
13697 (define_peephole2
13698   [(match_scratch:DI 2 "r")
13699    (parallel [(set (zero_extract:DI
13700                      (match_operand:DI 0 "register_operand" "")
13701                      (const_int 1)
13702                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13703                    (const_int 0))
13704               (clobber (reg:CC FLAGS_REG))])]
13705   "TARGET_64BIT && !TARGET_USE_BT"
13706   [(const_int 0)]
13707 {
13708   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13709   rtx op1;
13710
13711   if (HOST_BITS_PER_WIDE_INT >= 64)
13712     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13713   else if (i < HOST_BITS_PER_WIDE_INT)
13714     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13715   else
13716     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13717
13718   op1 = immed_double_const (~lo, ~hi, DImode);
13719   if (i >= 32)
13720     {
13721       emit_move_insn (operands[2], op1);
13722       op1 = operands[2];
13723     }
13724
13725   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13726   DONE;
13727 })
13728
13729 (define_peephole2
13730   [(match_scratch:DI 2 "r")
13731    (parallel [(set (zero_extract:DI
13732                      (match_operand:DI 0 "register_operand" "")
13733                      (const_int 1)
13734                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13735               (not:DI (zero_extract:DI
13736                         (match_dup 0) (const_int 1) (match_dup 1))))
13737               (clobber (reg:CC FLAGS_REG))])]
13738   "TARGET_64BIT && !TARGET_USE_BT"
13739   [(const_int 0)]
13740 {
13741   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13742   rtx op1;
13743
13744   if (HOST_BITS_PER_WIDE_INT >= 64)
13745     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13746   else if (i < HOST_BITS_PER_WIDE_INT)
13747     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13748   else
13749     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13750
13751   op1 = immed_double_const (lo, hi, DImode);
13752   if (i >= 31)
13753     {
13754       emit_move_insn (operands[2], op1);
13755       op1 = operands[2];
13756     }
13757
13758   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13759   DONE;
13760 })
13761 \f
13762 ;; Store-flag instructions.
13763
13764 ;; For all sCOND expanders, also expand the compare or test insn that
13765 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13766
13767 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13768 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13769 ;; way, which can later delete the movzx if only QImode is needed.
13770
13771 (define_expand "seq"
13772   [(set (match_operand:QI 0 "register_operand" "")
13773         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13774   ""
13775   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13776
13777 (define_expand "sne"
13778   [(set (match_operand:QI 0 "register_operand" "")
13779         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13780   ""
13781   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13782
13783 (define_expand "sgt"
13784   [(set (match_operand:QI 0 "register_operand" "")
13785         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13786   ""
13787   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13788
13789 (define_expand "sgtu"
13790   [(set (match_operand:QI 0 "register_operand" "")
13791         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13792   ""
13793   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13794
13795 (define_expand "slt"
13796   [(set (match_operand:QI 0 "register_operand" "")
13797         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13798   ""
13799   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13800
13801 (define_expand "sltu"
13802   [(set (match_operand:QI 0 "register_operand" "")
13803         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13804   ""
13805   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13806
13807 (define_expand "sge"
13808   [(set (match_operand:QI 0 "register_operand" "")
13809         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13810   ""
13811   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13812
13813 (define_expand "sgeu"
13814   [(set (match_operand:QI 0 "register_operand" "")
13815         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13816   ""
13817   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13818
13819 (define_expand "sle"
13820   [(set (match_operand:QI 0 "register_operand" "")
13821         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13822   ""
13823   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13824
13825 (define_expand "sleu"
13826   [(set (match_operand:QI 0 "register_operand" "")
13827         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13828   ""
13829   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13830
13831 (define_expand "sunordered"
13832   [(set (match_operand:QI 0 "register_operand" "")
13833         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13834   "TARGET_80387 || TARGET_SSE"
13835   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13836
13837 (define_expand "sordered"
13838   [(set (match_operand:QI 0 "register_operand" "")
13839         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13840   "TARGET_80387"
13841   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13842
13843 (define_expand "suneq"
13844   [(set (match_operand:QI 0 "register_operand" "")
13845         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13846   "TARGET_80387 || TARGET_SSE"
13847   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13848
13849 (define_expand "sunge"
13850   [(set (match_operand:QI 0 "register_operand" "")
13851         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852   "TARGET_80387 || TARGET_SSE"
13853   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13854
13855 (define_expand "sungt"
13856   [(set (match_operand:QI 0 "register_operand" "")
13857         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858   "TARGET_80387 || TARGET_SSE"
13859   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13860
13861 (define_expand "sunle"
13862   [(set (match_operand:QI 0 "register_operand" "")
13863         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864   "TARGET_80387 || TARGET_SSE"
13865   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13866
13867 (define_expand "sunlt"
13868   [(set (match_operand:QI 0 "register_operand" "")
13869         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870   "TARGET_80387 || TARGET_SSE"
13871   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13872
13873 (define_expand "sltgt"
13874   [(set (match_operand:QI 0 "register_operand" "")
13875         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13876   "TARGET_80387 || TARGET_SSE"
13877   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13878
13879 (define_insn "*setcc_1"
13880   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13881         (match_operator:QI 1 "ix86_comparison_operator"
13882           [(reg FLAGS_REG) (const_int 0)]))]
13883   ""
13884   "set%C1\t%0"
13885   [(set_attr "type" "setcc")
13886    (set_attr "mode" "QI")])
13887
13888 (define_insn "*setcc_2"
13889   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13890         (match_operator:QI 1 "ix86_comparison_operator"
13891           [(reg FLAGS_REG) (const_int 0)]))]
13892   ""
13893   "set%C1\t%0"
13894   [(set_attr "type" "setcc")
13895    (set_attr "mode" "QI")])
13896
13897 ;; In general it is not safe to assume too much about CCmode registers,
13898 ;; so simplify-rtx stops when it sees a second one.  Under certain
13899 ;; conditions this is safe on x86, so help combine not create
13900 ;;
13901 ;;      seta    %al
13902 ;;      testb   %al, %al
13903 ;;      sete    %al
13904
13905 (define_split
13906   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13907         (ne:QI (match_operator 1 "ix86_comparison_operator"
13908                  [(reg FLAGS_REG) (const_int 0)])
13909             (const_int 0)))]
13910   ""
13911   [(set (match_dup 0) (match_dup 1))]
13912 {
13913   PUT_MODE (operands[1], QImode);
13914 })
13915
13916 (define_split
13917   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13918         (ne:QI (match_operator 1 "ix86_comparison_operator"
13919                  [(reg FLAGS_REG) (const_int 0)])
13920             (const_int 0)))]
13921   ""
13922   [(set (match_dup 0) (match_dup 1))]
13923 {
13924   PUT_MODE (operands[1], QImode);
13925 })
13926
13927 (define_split
13928   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13929         (eq:QI (match_operator 1 "ix86_comparison_operator"
13930                  [(reg FLAGS_REG) (const_int 0)])
13931             (const_int 0)))]
13932   ""
13933   [(set (match_dup 0) (match_dup 1))]
13934 {
13935   rtx new_op1 = copy_rtx (operands[1]);
13936   operands[1] = new_op1;
13937   PUT_MODE (new_op1, QImode);
13938   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13939                                              GET_MODE (XEXP (new_op1, 0))));
13940
13941   /* Make sure that (a) the CCmode we have for the flags is strong
13942      enough for the reversed compare or (b) we have a valid FP compare.  */
13943   if (! ix86_comparison_operator (new_op1, VOIDmode))
13944     FAIL;
13945 })
13946
13947 (define_split
13948   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13949         (eq:QI (match_operator 1 "ix86_comparison_operator"
13950                  [(reg FLAGS_REG) (const_int 0)])
13951             (const_int 0)))]
13952   ""
13953   [(set (match_dup 0) (match_dup 1))]
13954 {
13955   rtx new_op1 = copy_rtx (operands[1]);
13956   operands[1] = new_op1;
13957   PUT_MODE (new_op1, QImode);
13958   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13959                                              GET_MODE (XEXP (new_op1, 0))));
13960
13961   /* Make sure that (a) the CCmode we have for the flags is strong
13962      enough for the reversed compare or (b) we have a valid FP compare.  */
13963   if (! ix86_comparison_operator (new_op1, VOIDmode))
13964     FAIL;
13965 })
13966
13967 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13968 ;; subsequent logical operations are used to imitate conditional moves.
13969 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13970 ;; it directly.
13971
13972 (define_insn "*sse_setccsf"
13973   [(set (match_operand:SF 0 "register_operand" "=x")
13974         (match_operator:SF 1 "sse_comparison_operator"
13975           [(match_operand:SF 2 "register_operand" "0")
13976            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13977   "TARGET_SSE && !TARGET_SSE5"
13978   "cmp%D1ss\t{%3, %0|%0, %3}"
13979   [(set_attr "type" "ssecmp")
13980    (set_attr "mode" "SF")])
13981
13982 (define_insn "*sse_setccdf"
13983   [(set (match_operand:DF 0 "register_operand" "=x")
13984         (match_operator:DF 1 "sse_comparison_operator"
13985           [(match_operand:DF 2 "register_operand" "0")
13986            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13987   "TARGET_SSE2 && !TARGET_SSE5"
13988   "cmp%D1sd\t{%3, %0|%0, %3}"
13989   [(set_attr "type" "ssecmp")
13990    (set_attr "mode" "DF")])
13991
13992 (define_insn "*sse5_setcc<mode>"
13993   [(set (match_operand:MODEF 0 "register_operand" "=x")
13994         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13995           [(match_operand:MODEF 2 "register_operand" "x")
13996            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13997   "TARGET_SSE5"
13998   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13999   [(set_attr "type" "sse4arg")
14000    (set_attr "mode" "<MODE>")])
14001
14002 \f
14003 ;; Basic conditional jump instructions.
14004 ;; We ignore the overflow flag for signed branch instructions.
14005
14006 ;; For all bCOND expanders, also expand the compare or test insn that
14007 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14008
14009 (define_expand "beq"
14010   [(set (pc)
14011         (if_then_else (match_dup 1)
14012                       (label_ref (match_operand 0 "" ""))
14013                       (pc)))]
14014   ""
14015   "ix86_expand_branch (EQ, operands[0]); DONE;")
14016
14017 (define_expand "bne"
14018   [(set (pc)
14019         (if_then_else (match_dup 1)
14020                       (label_ref (match_operand 0 "" ""))
14021                       (pc)))]
14022   ""
14023   "ix86_expand_branch (NE, operands[0]); DONE;")
14024
14025 (define_expand "bgt"
14026   [(set (pc)
14027         (if_then_else (match_dup 1)
14028                       (label_ref (match_operand 0 "" ""))
14029                       (pc)))]
14030   ""
14031   "ix86_expand_branch (GT, operands[0]); DONE;")
14032
14033 (define_expand "bgtu"
14034   [(set (pc)
14035         (if_then_else (match_dup 1)
14036                       (label_ref (match_operand 0 "" ""))
14037                       (pc)))]
14038   ""
14039   "ix86_expand_branch (GTU, operands[0]); DONE;")
14040
14041 (define_expand "blt"
14042   [(set (pc)
14043         (if_then_else (match_dup 1)
14044                       (label_ref (match_operand 0 "" ""))
14045                       (pc)))]
14046   ""
14047   "ix86_expand_branch (LT, operands[0]); DONE;")
14048
14049 (define_expand "bltu"
14050   [(set (pc)
14051         (if_then_else (match_dup 1)
14052                       (label_ref (match_operand 0 "" ""))
14053                       (pc)))]
14054   ""
14055   "ix86_expand_branch (LTU, operands[0]); DONE;")
14056
14057 (define_expand "bge"
14058   [(set (pc)
14059         (if_then_else (match_dup 1)
14060                       (label_ref (match_operand 0 "" ""))
14061                       (pc)))]
14062   ""
14063   "ix86_expand_branch (GE, operands[0]); DONE;")
14064
14065 (define_expand "bgeu"
14066   [(set (pc)
14067         (if_then_else (match_dup 1)
14068                       (label_ref (match_operand 0 "" ""))
14069                       (pc)))]
14070   ""
14071   "ix86_expand_branch (GEU, operands[0]); DONE;")
14072
14073 (define_expand "ble"
14074   [(set (pc)
14075         (if_then_else (match_dup 1)
14076                       (label_ref (match_operand 0 "" ""))
14077                       (pc)))]
14078   ""
14079   "ix86_expand_branch (LE, operands[0]); DONE;")
14080
14081 (define_expand "bleu"
14082   [(set (pc)
14083         (if_then_else (match_dup 1)
14084                       (label_ref (match_operand 0 "" ""))
14085                       (pc)))]
14086   ""
14087   "ix86_expand_branch (LEU, operands[0]); DONE;")
14088
14089 (define_expand "bunordered"
14090   [(set (pc)
14091         (if_then_else (match_dup 1)
14092                       (label_ref (match_operand 0 "" ""))
14093                       (pc)))]
14094   "TARGET_80387 || TARGET_SSE_MATH"
14095   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14096
14097 (define_expand "bordered"
14098   [(set (pc)
14099         (if_then_else (match_dup 1)
14100                       (label_ref (match_operand 0 "" ""))
14101                       (pc)))]
14102   "TARGET_80387 || TARGET_SSE_MATH"
14103   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14104
14105 (define_expand "buneq"
14106   [(set (pc)
14107         (if_then_else (match_dup 1)
14108                       (label_ref (match_operand 0 "" ""))
14109                       (pc)))]
14110   "TARGET_80387 || TARGET_SSE_MATH"
14111   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14112
14113 (define_expand "bunge"
14114   [(set (pc)
14115         (if_then_else (match_dup 1)
14116                       (label_ref (match_operand 0 "" ""))
14117                       (pc)))]
14118   "TARGET_80387 || TARGET_SSE_MATH"
14119   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14120
14121 (define_expand "bungt"
14122   [(set (pc)
14123         (if_then_else (match_dup 1)
14124                       (label_ref (match_operand 0 "" ""))
14125                       (pc)))]
14126   "TARGET_80387 || TARGET_SSE_MATH"
14127   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14128
14129 (define_expand "bunle"
14130   [(set (pc)
14131         (if_then_else (match_dup 1)
14132                       (label_ref (match_operand 0 "" ""))
14133                       (pc)))]
14134   "TARGET_80387 || TARGET_SSE_MATH"
14135   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14136
14137 (define_expand "bunlt"
14138   [(set (pc)
14139         (if_then_else (match_dup 1)
14140                       (label_ref (match_operand 0 "" ""))
14141                       (pc)))]
14142   "TARGET_80387 || TARGET_SSE_MATH"
14143   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14144
14145 (define_expand "bltgt"
14146   [(set (pc)
14147         (if_then_else (match_dup 1)
14148                       (label_ref (match_operand 0 "" ""))
14149                       (pc)))]
14150   "TARGET_80387 || TARGET_SSE_MATH"
14151   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14152
14153 (define_insn "*jcc_1"
14154   [(set (pc)
14155         (if_then_else (match_operator 1 "ix86_comparison_operator"
14156                                       [(reg FLAGS_REG) (const_int 0)])
14157                       (label_ref (match_operand 0 "" ""))
14158                       (pc)))]
14159   ""
14160   "%+j%C1\t%l0"
14161   [(set_attr "type" "ibr")
14162    (set_attr "modrm" "0")
14163    (set (attr "length")
14164            (if_then_else (and (ge (minus (match_dup 0) (pc))
14165                                   (const_int -126))
14166                               (lt (minus (match_dup 0) (pc))
14167                                   (const_int 128)))
14168              (const_int 2)
14169              (const_int 6)))])
14170
14171 (define_insn "*jcc_2"
14172   [(set (pc)
14173         (if_then_else (match_operator 1 "ix86_comparison_operator"
14174                                       [(reg FLAGS_REG) (const_int 0)])
14175                       (pc)
14176                       (label_ref (match_operand 0 "" ""))))]
14177   ""
14178   "%+j%c1\t%l0"
14179   [(set_attr "type" "ibr")
14180    (set_attr "modrm" "0")
14181    (set (attr "length")
14182            (if_then_else (and (ge (minus (match_dup 0) (pc))
14183                                   (const_int -126))
14184                               (lt (minus (match_dup 0) (pc))
14185                                   (const_int 128)))
14186              (const_int 2)
14187              (const_int 6)))])
14188
14189 ;; In general it is not safe to assume too much about CCmode registers,
14190 ;; so simplify-rtx stops when it sees a second one.  Under certain
14191 ;; conditions this is safe on x86, so help combine not create
14192 ;;
14193 ;;      seta    %al
14194 ;;      testb   %al, %al
14195 ;;      je      Lfoo
14196
14197 (define_split
14198   [(set (pc)
14199         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14200                                       [(reg FLAGS_REG) (const_int 0)])
14201                           (const_int 0))
14202                       (label_ref (match_operand 1 "" ""))
14203                       (pc)))]
14204   ""
14205   [(set (pc)
14206         (if_then_else (match_dup 0)
14207                       (label_ref (match_dup 1))
14208                       (pc)))]
14209 {
14210   PUT_MODE (operands[0], VOIDmode);
14211 })
14212
14213 (define_split
14214   [(set (pc)
14215         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14216                                       [(reg FLAGS_REG) (const_int 0)])
14217                           (const_int 0))
14218                       (label_ref (match_operand 1 "" ""))
14219                       (pc)))]
14220   ""
14221   [(set (pc)
14222         (if_then_else (match_dup 0)
14223                       (label_ref (match_dup 1))
14224                       (pc)))]
14225 {
14226   rtx new_op0 = copy_rtx (operands[0]);
14227   operands[0] = new_op0;
14228   PUT_MODE (new_op0, VOIDmode);
14229   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14230                                              GET_MODE (XEXP (new_op0, 0))));
14231
14232   /* Make sure that (a) the CCmode we have for the flags is strong
14233      enough for the reversed compare or (b) we have a valid FP compare.  */
14234   if (! ix86_comparison_operator (new_op0, VOIDmode))
14235     FAIL;
14236 })
14237
14238 ;; Define combination compare-and-branch fp compare instructions to use
14239 ;; during early optimization.  Splitting the operation apart early makes
14240 ;; for bad code when we want to reverse the operation.
14241
14242 (define_insn "*fp_jcc_1_mixed"
14243   [(set (pc)
14244         (if_then_else (match_operator 0 "comparison_operator"
14245                         [(match_operand 1 "register_operand" "f,x")
14246                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14247           (label_ref (match_operand 3 "" ""))
14248           (pc)))
14249    (clobber (reg:CCFP FPSR_REG))
14250    (clobber (reg:CCFP FLAGS_REG))]
14251   "TARGET_MIX_SSE_I387
14252    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14253    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14254    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14255   "#")
14256
14257 (define_insn "*fp_jcc_1_sse"
14258   [(set (pc)
14259         (if_then_else (match_operator 0 "comparison_operator"
14260                         [(match_operand 1 "register_operand" "x")
14261                          (match_operand 2 "nonimmediate_operand" "xm")])
14262           (label_ref (match_operand 3 "" ""))
14263           (pc)))
14264    (clobber (reg:CCFP FPSR_REG))
14265    (clobber (reg:CCFP FLAGS_REG))]
14266   "TARGET_SSE_MATH
14267    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14268    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14269    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14270   "#")
14271
14272 (define_insn "*fp_jcc_1_387"
14273   [(set (pc)
14274         (if_then_else (match_operator 0 "comparison_operator"
14275                         [(match_operand 1 "register_operand" "f")
14276                          (match_operand 2 "register_operand" "f")])
14277           (label_ref (match_operand 3 "" ""))
14278           (pc)))
14279    (clobber (reg:CCFP FPSR_REG))
14280    (clobber (reg:CCFP FLAGS_REG))]
14281   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14282    && TARGET_CMOVE
14283    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14284    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14285   "#")
14286
14287 (define_insn "*fp_jcc_2_mixed"
14288   [(set (pc)
14289         (if_then_else (match_operator 0 "comparison_operator"
14290                         [(match_operand 1 "register_operand" "f,x")
14291                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14292           (pc)
14293           (label_ref (match_operand 3 "" ""))))
14294    (clobber (reg:CCFP FPSR_REG))
14295    (clobber (reg:CCFP FLAGS_REG))]
14296   "TARGET_MIX_SSE_I387
14297    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14298    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14299    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14300   "#")
14301
14302 (define_insn "*fp_jcc_2_sse"
14303   [(set (pc)
14304         (if_then_else (match_operator 0 "comparison_operator"
14305                         [(match_operand 1 "register_operand" "x")
14306                          (match_operand 2 "nonimmediate_operand" "xm")])
14307           (pc)
14308           (label_ref (match_operand 3 "" ""))))
14309    (clobber (reg:CCFP FPSR_REG))
14310    (clobber (reg:CCFP FLAGS_REG))]
14311   "TARGET_SSE_MATH
14312    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14313    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14314    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14315   "#")
14316
14317 (define_insn "*fp_jcc_2_387"
14318   [(set (pc)
14319         (if_then_else (match_operator 0 "comparison_operator"
14320                         [(match_operand 1 "register_operand" "f")
14321                          (match_operand 2 "register_operand" "f")])
14322           (pc)
14323           (label_ref (match_operand 3 "" ""))))
14324    (clobber (reg:CCFP FPSR_REG))
14325    (clobber (reg:CCFP FLAGS_REG))]
14326   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14327    && TARGET_CMOVE
14328    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14329    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14330   "#")
14331
14332 (define_insn "*fp_jcc_3_387"
14333   [(set (pc)
14334         (if_then_else (match_operator 0 "comparison_operator"
14335                         [(match_operand 1 "register_operand" "f")
14336                          (match_operand 2 "nonimmediate_operand" "fm")])
14337           (label_ref (match_operand 3 "" ""))
14338           (pc)))
14339    (clobber (reg:CCFP FPSR_REG))
14340    (clobber (reg:CCFP FLAGS_REG))
14341    (clobber (match_scratch:HI 4 "=a"))]
14342   "TARGET_80387
14343    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14344    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14345    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14346    && SELECT_CC_MODE (GET_CODE (operands[0]),
14347                       operands[1], operands[2]) == CCFPmode
14348    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14349   "#")
14350
14351 (define_insn "*fp_jcc_4_387"
14352   [(set (pc)
14353         (if_then_else (match_operator 0 "comparison_operator"
14354                         [(match_operand 1 "register_operand" "f")
14355                          (match_operand 2 "nonimmediate_operand" "fm")])
14356           (pc)
14357           (label_ref (match_operand 3 "" ""))))
14358    (clobber (reg:CCFP FPSR_REG))
14359    (clobber (reg:CCFP FLAGS_REG))
14360    (clobber (match_scratch:HI 4 "=a"))]
14361   "TARGET_80387
14362    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14363    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14364    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14365    && SELECT_CC_MODE (GET_CODE (operands[0]),
14366                       operands[1], operands[2]) == CCFPmode
14367    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14368   "#")
14369
14370 (define_insn "*fp_jcc_5_387"
14371   [(set (pc)
14372         (if_then_else (match_operator 0 "comparison_operator"
14373                         [(match_operand 1 "register_operand" "f")
14374                          (match_operand 2 "register_operand" "f")])
14375           (label_ref (match_operand 3 "" ""))
14376           (pc)))
14377    (clobber (reg:CCFP FPSR_REG))
14378    (clobber (reg:CCFP FLAGS_REG))
14379    (clobber (match_scratch:HI 4 "=a"))]
14380   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14381    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14382    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14383   "#")
14384
14385 (define_insn "*fp_jcc_6_387"
14386   [(set (pc)
14387         (if_then_else (match_operator 0 "comparison_operator"
14388                         [(match_operand 1 "register_operand" "f")
14389                          (match_operand 2 "register_operand" "f")])
14390           (pc)
14391           (label_ref (match_operand 3 "" ""))))
14392    (clobber (reg:CCFP FPSR_REG))
14393    (clobber (reg:CCFP FLAGS_REG))
14394    (clobber (match_scratch:HI 4 "=a"))]
14395   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14396    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14397    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14398   "#")
14399
14400 (define_insn "*fp_jcc_7_387"
14401   [(set (pc)
14402         (if_then_else (match_operator 0 "comparison_operator"
14403                         [(match_operand 1 "register_operand" "f")
14404                          (match_operand 2 "const0_operand" "X")])
14405           (label_ref (match_operand 3 "" ""))
14406           (pc)))
14407    (clobber (reg:CCFP FPSR_REG))
14408    (clobber (reg:CCFP FLAGS_REG))
14409    (clobber (match_scratch:HI 4 "=a"))]
14410   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14411    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14412    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14413    && SELECT_CC_MODE (GET_CODE (operands[0]),
14414                       operands[1], operands[2]) == CCFPmode
14415    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14416   "#")
14417
14418 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14419 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14420 ;; with a precedence over other operators and is always put in the first
14421 ;; place. Swap condition and operands to match ficom instruction.
14422
14423 (define_insn "*fp_jcc_8<mode>_387"
14424   [(set (pc)
14425         (if_then_else (match_operator 0 "comparison_operator"
14426                         [(match_operator 1 "float_operator"
14427                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14428                            (match_operand 3 "register_operand" "f,f")])
14429           (label_ref (match_operand 4 "" ""))
14430           (pc)))
14431    (clobber (reg:CCFP FPSR_REG))
14432    (clobber (reg:CCFP FLAGS_REG))
14433    (clobber (match_scratch:HI 5 "=a,a"))]
14434   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14435    && TARGET_USE_<MODE>MODE_FIOP
14436    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14437    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14438    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14439    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14440   "#")
14441
14442 (define_split
14443   [(set (pc)
14444         (if_then_else (match_operator 0 "comparison_operator"
14445                         [(match_operand 1 "register_operand" "")
14446                          (match_operand 2 "nonimmediate_operand" "")])
14447           (match_operand 3 "" "")
14448           (match_operand 4 "" "")))
14449    (clobber (reg:CCFP FPSR_REG))
14450    (clobber (reg:CCFP FLAGS_REG))]
14451   "reload_completed"
14452   [(const_int 0)]
14453 {
14454   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14455                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14456   DONE;
14457 })
14458
14459 (define_split
14460   [(set (pc)
14461         (if_then_else (match_operator 0 "comparison_operator"
14462                         [(match_operand 1 "register_operand" "")
14463                          (match_operand 2 "general_operand" "")])
14464           (match_operand 3 "" "")
14465           (match_operand 4 "" "")))
14466    (clobber (reg:CCFP FPSR_REG))
14467    (clobber (reg:CCFP FLAGS_REG))
14468    (clobber (match_scratch:HI 5 "=a"))]
14469   "reload_completed"
14470   [(const_int 0)]
14471 {
14472   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14473                         operands[3], operands[4], operands[5], NULL_RTX);
14474   DONE;
14475 })
14476
14477 (define_split
14478   [(set (pc)
14479         (if_then_else (match_operator 0 "comparison_operator"
14480                         [(match_operator 1 "float_operator"
14481                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14482                            (match_operand 3 "register_operand" "")])
14483           (match_operand 4 "" "")
14484           (match_operand 5 "" "")))
14485    (clobber (reg:CCFP FPSR_REG))
14486    (clobber (reg:CCFP FLAGS_REG))
14487    (clobber (match_scratch:HI 6 "=a"))]
14488   "reload_completed"
14489   [(const_int 0)]
14490 {
14491   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14492   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14493                         operands[3], operands[7],
14494                         operands[4], operands[5], operands[6], NULL_RTX);
14495   DONE;
14496 })
14497
14498 ;; %%% Kill this when reload knows how to do it.
14499 (define_split
14500   [(set (pc)
14501         (if_then_else (match_operator 0 "comparison_operator"
14502                         [(match_operator 1 "float_operator"
14503                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14504                            (match_operand 3 "register_operand" "")])
14505           (match_operand 4 "" "")
14506           (match_operand 5 "" "")))
14507    (clobber (reg:CCFP FPSR_REG))
14508    (clobber (reg:CCFP FLAGS_REG))
14509    (clobber (match_scratch:HI 6 "=a"))]
14510   "reload_completed"
14511   [(const_int 0)]
14512 {
14513   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14514   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14515   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14516                         operands[3], operands[7],
14517                         operands[4], operands[5], operands[6], operands[2]);
14518   DONE;
14519 })
14520 \f
14521 ;; Unconditional and other jump instructions
14522
14523 (define_insn "jump"
14524   [(set (pc)
14525         (label_ref (match_operand 0 "" "")))]
14526   ""
14527   "jmp\t%l0"
14528   [(set_attr "type" "ibr")
14529    (set (attr "length")
14530            (if_then_else (and (ge (minus (match_dup 0) (pc))
14531                                   (const_int -126))
14532                               (lt (minus (match_dup 0) (pc))
14533                                   (const_int 128)))
14534              (const_int 2)
14535              (const_int 5)))
14536    (set_attr "modrm" "0")])
14537
14538 (define_expand "indirect_jump"
14539   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14540   ""
14541   "")
14542
14543 (define_insn "*indirect_jump"
14544   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14545   "!TARGET_64BIT"
14546   "jmp\t%A0"
14547   [(set_attr "type" "ibr")
14548    (set_attr "length_immediate" "0")])
14549
14550 (define_insn "*indirect_jump_rtx64"
14551   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14552   "TARGET_64BIT"
14553   "jmp\t%A0"
14554   [(set_attr "type" "ibr")
14555    (set_attr "length_immediate" "0")])
14556
14557 (define_expand "tablejump"
14558   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14559               (use (label_ref (match_operand 1 "" "")))])]
14560   ""
14561 {
14562   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14563      relative.  Convert the relative address to an absolute address.  */
14564   if (flag_pic)
14565     {
14566       rtx op0, op1;
14567       enum rtx_code code;
14568
14569       /* We can't use @GOTOFF for text labels on VxWorks;
14570          see gotoff_operand.  */
14571       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14572         {
14573           code = PLUS;
14574           op0 = operands[0];
14575           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14576         }
14577       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14578         {
14579           code = PLUS;
14580           op0 = operands[0];
14581           op1 = pic_offset_table_rtx;
14582         }
14583       else
14584         {
14585           code = MINUS;
14586           op0 = pic_offset_table_rtx;
14587           op1 = operands[0];
14588         }
14589
14590       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14591                                          OPTAB_DIRECT);
14592     }
14593 })
14594
14595 (define_insn "*tablejump_1"
14596   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14597    (use (label_ref (match_operand 1 "" "")))]
14598   "!TARGET_64BIT"
14599   "jmp\t%A0"
14600   [(set_attr "type" "ibr")
14601    (set_attr "length_immediate" "0")])
14602
14603 (define_insn "*tablejump_1_rtx64"
14604   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14605    (use (label_ref (match_operand 1 "" "")))]
14606   "TARGET_64BIT"
14607   "jmp\t%A0"
14608   [(set_attr "type" "ibr")
14609    (set_attr "length_immediate" "0")])
14610 \f
14611 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14612
14613 (define_peephole2
14614   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14615    (set (match_operand:QI 1 "register_operand" "")
14616         (match_operator:QI 2 "ix86_comparison_operator"
14617           [(reg FLAGS_REG) (const_int 0)]))
14618    (set (match_operand 3 "q_regs_operand" "")
14619         (zero_extend (match_dup 1)))]
14620   "(peep2_reg_dead_p (3, operands[1])
14621     || operands_match_p (operands[1], operands[3]))
14622    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14623   [(set (match_dup 4) (match_dup 0))
14624    (set (strict_low_part (match_dup 5))
14625         (match_dup 2))]
14626 {
14627   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14628   operands[5] = gen_lowpart (QImode, operands[3]);
14629   ix86_expand_clear (operands[3]);
14630 })
14631
14632 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14633
14634 (define_peephole2
14635   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14636    (set (match_operand:QI 1 "register_operand" "")
14637         (match_operator:QI 2 "ix86_comparison_operator"
14638           [(reg FLAGS_REG) (const_int 0)]))
14639    (parallel [(set (match_operand 3 "q_regs_operand" "")
14640                    (zero_extend (match_dup 1)))
14641               (clobber (reg:CC FLAGS_REG))])]
14642   "(peep2_reg_dead_p (3, operands[1])
14643     || operands_match_p (operands[1], operands[3]))
14644    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14645   [(set (match_dup 4) (match_dup 0))
14646    (set (strict_low_part (match_dup 5))
14647         (match_dup 2))]
14648 {
14649   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14650   operands[5] = gen_lowpart (QImode, operands[3]);
14651   ix86_expand_clear (operands[3]);
14652 })
14653 \f
14654 ;; Call instructions.
14655
14656 ;; The predicates normally associated with named expanders are not properly
14657 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14658 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14659
14660 ;; Call subroutine returning no value.
14661
14662 (define_expand "call_pop"
14663   [(parallel [(call (match_operand:QI 0 "" "")
14664                     (match_operand:SI 1 "" ""))
14665               (set (reg:SI SP_REG)
14666                    (plus:SI (reg:SI SP_REG)
14667                             (match_operand:SI 3 "" "")))])]
14668   "!TARGET_64BIT"
14669 {
14670   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14671   DONE;
14672 })
14673
14674 (define_insn "*call_pop_0"
14675   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14676          (match_operand:SI 1 "" ""))
14677    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14678                             (match_operand:SI 2 "immediate_operand" "")))]
14679   "!TARGET_64BIT"
14680 {
14681   if (SIBLING_CALL_P (insn))
14682     return "jmp\t%P0";
14683   else
14684     return "call\t%P0";
14685 }
14686   [(set_attr "type" "call")])
14687
14688 (define_insn "*call_pop_1"
14689   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14690          (match_operand:SI 1 "" ""))
14691    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14692                             (match_operand:SI 2 "immediate_operand" "i")))]
14693   "!TARGET_64BIT"
14694 {
14695   if (constant_call_address_operand (operands[0], Pmode))
14696     {
14697       if (SIBLING_CALL_P (insn))
14698         return "jmp\t%P0";
14699       else
14700         return "call\t%P0";
14701     }
14702   if (SIBLING_CALL_P (insn))
14703     return "jmp\t%A0";
14704   else
14705     return "call\t%A0";
14706 }
14707   [(set_attr "type" "call")])
14708
14709 (define_expand "call"
14710   [(call (match_operand:QI 0 "" "")
14711          (match_operand 1 "" ""))
14712    (use (match_operand 2 "" ""))]
14713   ""
14714 {
14715   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14716   DONE;
14717 })
14718
14719 (define_expand "sibcall"
14720   [(call (match_operand:QI 0 "" "")
14721          (match_operand 1 "" ""))
14722    (use (match_operand 2 "" ""))]
14723   ""
14724 {
14725   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14726   DONE;
14727 })
14728
14729 (define_insn "*call_0"
14730   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14731          (match_operand 1 "" ""))]
14732   ""
14733 {
14734   if (SIBLING_CALL_P (insn))
14735     return "jmp\t%P0";
14736   else
14737     return "call\t%P0";
14738 }
14739   [(set_attr "type" "call")])
14740
14741 (define_insn "*call_1"
14742   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14743          (match_operand 1 "" ""))]
14744   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14745 {
14746   if (constant_call_address_operand (operands[0], Pmode))
14747     return "call\t%P0";
14748   return "call\t%A0";
14749 }
14750   [(set_attr "type" "call")])
14751
14752 (define_insn "*sibcall_1"
14753   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14754          (match_operand 1 "" ""))]
14755   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14756 {
14757   if (constant_call_address_operand (operands[0], Pmode))
14758     return "jmp\t%P0";
14759   return "jmp\t%A0";
14760 }
14761   [(set_attr "type" "call")])
14762
14763 (define_insn "*call_1_rex64"
14764   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14765          (match_operand 1 "" ""))]
14766   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14767    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14768 {
14769   if (constant_call_address_operand (operands[0], Pmode))
14770     return "call\t%P0";
14771   return "call\t%A0";
14772 }
14773   [(set_attr "type" "call")])
14774
14775 (define_insn "*call_1_rex64_large"
14776   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14777          (match_operand 1 "" ""))]
14778   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14779   "call\t%A0"
14780   [(set_attr "type" "call")])
14781
14782 (define_insn "*sibcall_1_rex64"
14783   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14784          (match_operand 1 "" ""))]
14785   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14786   "jmp\t%P0"
14787   [(set_attr "type" "call")])
14788
14789 (define_insn "*sibcall_1_rex64_v"
14790   [(call (mem:QI (reg:DI R11_REG))
14791          (match_operand 0 "" ""))]
14792   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14793   "jmp\t{*%%}r11"
14794   [(set_attr "type" "call")])
14795
14796
14797 ;; Call subroutine, returning value in operand 0
14798
14799 (define_expand "call_value_pop"
14800   [(parallel [(set (match_operand 0 "" "")
14801                    (call (match_operand:QI 1 "" "")
14802                          (match_operand:SI 2 "" "")))
14803               (set (reg:SI SP_REG)
14804                    (plus:SI (reg:SI SP_REG)
14805                             (match_operand:SI 4 "" "")))])]
14806   "!TARGET_64BIT"
14807 {
14808   ix86_expand_call (operands[0], operands[1], operands[2],
14809                     operands[3], operands[4], 0);
14810   DONE;
14811 })
14812
14813 (define_expand "call_value"
14814   [(set (match_operand 0 "" "")
14815         (call (match_operand:QI 1 "" "")
14816               (match_operand:SI 2 "" "")))
14817    (use (match_operand:SI 3 "" ""))]
14818   ;; Operand 2 not used on the i386.
14819   ""
14820 {
14821   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14822   DONE;
14823 })
14824
14825 (define_expand "sibcall_value"
14826   [(set (match_operand 0 "" "")
14827         (call (match_operand:QI 1 "" "")
14828               (match_operand:SI 2 "" "")))
14829    (use (match_operand:SI 3 "" ""))]
14830   ;; Operand 2 not used on the i386.
14831   ""
14832 {
14833   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14834   DONE;
14835 })
14836
14837 ;; Call subroutine returning any type.
14838
14839 (define_expand "untyped_call"
14840   [(parallel [(call (match_operand 0 "" "")
14841                     (const_int 0))
14842               (match_operand 1 "" "")
14843               (match_operand 2 "" "")])]
14844   ""
14845 {
14846   int i;
14847
14848   /* In order to give reg-stack an easier job in validating two
14849      coprocessor registers as containing a possible return value,
14850      simply pretend the untyped call returns a complex long double
14851      value.  */
14852
14853   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14854                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14855                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14856                     NULL, 0);
14857
14858   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14859     {
14860       rtx set = XVECEXP (operands[2], 0, i);
14861       emit_move_insn (SET_DEST (set), SET_SRC (set));
14862     }
14863
14864   /* The optimizer does not know that the call sets the function value
14865      registers we stored in the result block.  We avoid problems by
14866      claiming that all hard registers are used and clobbered at this
14867      point.  */
14868   emit_insn (gen_blockage ());
14869
14870   DONE;
14871 })
14872 \f
14873 ;; Prologue and epilogue instructions
14874
14875 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14876 ;; all of memory.  This blocks insns from being moved across this point.
14877
14878 (define_insn "blockage"
14879   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14880   ""
14881   ""
14882   [(set_attr "length" "0")])
14883
14884 ;; As USE insns aren't meaningful after reload, this is used instead
14885 ;; to prevent deleting instructions setting registers for PIC code
14886 (define_insn "prologue_use"
14887   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14888   ""
14889   ""
14890   [(set_attr "length" "0")])
14891
14892 ;; Insn emitted into the body of a function to return from a function.
14893 ;; This is only done if the function's epilogue is known to be simple.
14894 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14895
14896 (define_expand "return"
14897   [(return)]
14898   "ix86_can_use_return_insn_p ()"
14899 {
14900   if (current_function_pops_args)
14901     {
14902       rtx popc = GEN_INT (current_function_pops_args);
14903       emit_jump_insn (gen_return_pop_internal (popc));
14904       DONE;
14905     }
14906 })
14907
14908 (define_insn "return_internal"
14909   [(return)]
14910   "reload_completed"
14911   "ret"
14912   [(set_attr "length" "1")
14913    (set_attr "length_immediate" "0")
14914    (set_attr "modrm" "0")])
14915
14916 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14917 ;; instruction Athlon and K8 have.
14918
14919 (define_insn "return_internal_long"
14920   [(return)
14921    (unspec [(const_int 0)] UNSPEC_REP)]
14922   "reload_completed"
14923   "rep\;ret"
14924   [(set_attr "length" "1")
14925    (set_attr "length_immediate" "0")
14926    (set_attr "prefix_rep" "1")
14927    (set_attr "modrm" "0")])
14928
14929 (define_insn "return_pop_internal"
14930   [(return)
14931    (use (match_operand:SI 0 "const_int_operand" ""))]
14932   "reload_completed"
14933   "ret\t%0"
14934   [(set_attr "length" "3")
14935    (set_attr "length_immediate" "2")
14936    (set_attr "modrm" "0")])
14937
14938 (define_insn "return_indirect_internal"
14939   [(return)
14940    (use (match_operand:SI 0 "register_operand" "r"))]
14941   "reload_completed"
14942   "jmp\t%A0"
14943   [(set_attr "type" "ibr")
14944    (set_attr "length_immediate" "0")])
14945
14946 (define_insn "nop"
14947   [(const_int 0)]
14948   ""
14949   "nop"
14950   [(set_attr "length" "1")
14951    (set_attr "length_immediate" "0")
14952    (set_attr "modrm" "0")])
14953
14954 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14955 ;; branch prediction penalty for the third jump in a 16-byte
14956 ;; block on K8.
14957
14958 (define_insn "align"
14959   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14960   ""
14961 {
14962 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14963   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14964 #else
14965   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14966      The align insn is used to avoid 3 jump instructions in the row to improve
14967      branch prediction and the benefits hardly outweigh the cost of extra 8
14968      nops on the average inserted by full alignment pseudo operation.  */
14969 #endif
14970   return "";
14971 }
14972   [(set_attr "length" "16")])
14973
14974 (define_expand "prologue"
14975   [(const_int 0)]
14976   ""
14977   "ix86_expand_prologue (); DONE;")
14978
14979 (define_insn "set_got"
14980   [(set (match_operand:SI 0 "register_operand" "=r")
14981         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14982    (clobber (reg:CC FLAGS_REG))]
14983   "!TARGET_64BIT"
14984   { return output_set_got (operands[0], NULL_RTX); }
14985   [(set_attr "type" "multi")
14986    (set_attr "length" "12")])
14987
14988 (define_insn "set_got_labelled"
14989   [(set (match_operand:SI 0 "register_operand" "=r")
14990         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14991          UNSPEC_SET_GOT))
14992    (clobber (reg:CC FLAGS_REG))]
14993   "!TARGET_64BIT"
14994   { return output_set_got (operands[0], operands[1]); }
14995   [(set_attr "type" "multi")
14996    (set_attr "length" "12")])
14997
14998 (define_insn "set_got_rex64"
14999   [(set (match_operand:DI 0 "register_operand" "=r")
15000         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15001   "TARGET_64BIT"
15002   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15003   [(set_attr "type" "lea")
15004    (set_attr "length" "6")])
15005
15006 (define_insn "set_rip_rex64"
15007   [(set (match_operand:DI 0 "register_operand" "=r")
15008         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15009   "TARGET_64BIT"
15010   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15011   [(set_attr "type" "lea")
15012    (set_attr "length" "6")])
15013
15014 (define_insn "set_got_offset_rex64"
15015   [(set (match_operand:DI 0 "register_operand" "=r")
15016         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15017   "TARGET_64BIT"
15018   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15019   [(set_attr "type" "imov")
15020    (set_attr "length" "11")])
15021
15022 (define_expand "epilogue"
15023   [(const_int 0)]
15024   ""
15025   "ix86_expand_epilogue (1); DONE;")
15026
15027 (define_expand "sibcall_epilogue"
15028   [(const_int 0)]
15029   ""
15030   "ix86_expand_epilogue (0); DONE;")
15031
15032 (define_expand "eh_return"
15033   [(use (match_operand 0 "register_operand" ""))]
15034   ""
15035 {
15036   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15037
15038   /* Tricky bit: we write the address of the handler to which we will
15039      be returning into someone else's stack frame, one word below the
15040      stack address we wish to restore.  */
15041   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15042   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15043   tmp = gen_rtx_MEM (Pmode, tmp);
15044   emit_move_insn (tmp, ra);
15045
15046   if (Pmode == SImode)
15047     emit_jump_insn (gen_eh_return_si (sa));
15048   else
15049     emit_jump_insn (gen_eh_return_di (sa));
15050   emit_barrier ();
15051   DONE;
15052 })
15053
15054 (define_insn_and_split "eh_return_si"
15055   [(set (pc)
15056         (unspec [(match_operand:SI 0 "register_operand" "c")]
15057                  UNSPEC_EH_RETURN))]
15058   "!TARGET_64BIT"
15059   "#"
15060   "reload_completed"
15061   [(const_int 0)]
15062   "ix86_expand_epilogue (2); DONE;")
15063
15064 (define_insn_and_split "eh_return_di"
15065   [(set (pc)
15066         (unspec [(match_operand:DI 0 "register_operand" "c")]
15067                  UNSPEC_EH_RETURN))]
15068   "TARGET_64BIT"
15069   "#"
15070   "reload_completed"
15071   [(const_int 0)]
15072   "ix86_expand_epilogue (2); DONE;")
15073
15074 (define_insn "leave"
15075   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15076    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15077    (clobber (mem:BLK (scratch)))]
15078   "!TARGET_64BIT"
15079   "leave"
15080   [(set_attr "type" "leave")])
15081
15082 (define_insn "leave_rex64"
15083   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15084    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15085    (clobber (mem:BLK (scratch)))]
15086   "TARGET_64BIT"
15087   "leave"
15088   [(set_attr "type" "leave")])
15089 \f
15090 (define_expand "ffssi2"
15091   [(parallel
15092      [(set (match_operand:SI 0 "register_operand" "")
15093            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15094       (clobber (match_scratch:SI 2 ""))
15095       (clobber (reg:CC FLAGS_REG))])]
15096   ""
15097 {
15098   if (TARGET_CMOVE)
15099     {
15100       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15101       DONE;
15102     }
15103 })
15104
15105 (define_expand "ffs_cmove"
15106   [(set (match_dup 2) (const_int -1))
15107    (parallel [(set (reg:CCZ FLAGS_REG)
15108                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15109                                 (const_int 0)))
15110               (set (match_operand:SI 0 "nonimmediate_operand" "")
15111                    (ctz:SI (match_dup 1)))])
15112    (set (match_dup 0) (if_then_else:SI
15113                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15114                         (match_dup 2)
15115                         (match_dup 0)))
15116    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15117               (clobber (reg:CC FLAGS_REG))])]
15118   "TARGET_CMOVE"
15119   "operands[2] = gen_reg_rtx (SImode);")
15120
15121 (define_insn_and_split "*ffs_no_cmove"
15122   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15123         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15124    (clobber (match_scratch:SI 2 "=&q"))
15125    (clobber (reg:CC FLAGS_REG))]
15126   "!TARGET_CMOVE"
15127   "#"
15128   "&& reload_completed"
15129   [(parallel [(set (reg:CCZ FLAGS_REG)
15130                    (compare:CCZ (match_dup 1) (const_int 0)))
15131               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15132    (set (strict_low_part (match_dup 3))
15133         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15134    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15135               (clobber (reg:CC FLAGS_REG))])
15136    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15137               (clobber (reg:CC FLAGS_REG))])
15138    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15139               (clobber (reg:CC FLAGS_REG))])]
15140 {
15141   operands[3] = gen_lowpart (QImode, operands[2]);
15142   ix86_expand_clear (operands[2]);
15143 })
15144
15145 (define_insn "*ffssi_1"
15146   [(set (reg:CCZ FLAGS_REG)
15147         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15148                      (const_int 0)))
15149    (set (match_operand:SI 0 "register_operand" "=r")
15150         (ctz:SI (match_dup 1)))]
15151   ""
15152   "bsf{l}\t{%1, %0|%0, %1}"
15153   [(set_attr "prefix_0f" "1")])
15154
15155 (define_expand "ffsdi2"
15156   [(set (match_dup 2) (const_int -1))
15157    (parallel [(set (reg:CCZ FLAGS_REG)
15158                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15159                                 (const_int 0)))
15160               (set (match_operand:DI 0 "nonimmediate_operand" "")
15161                    (ctz:DI (match_dup 1)))])
15162    (set (match_dup 0) (if_then_else:DI
15163                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15164                         (match_dup 2)
15165                         (match_dup 0)))
15166    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15167               (clobber (reg:CC FLAGS_REG))])]
15168   "TARGET_64BIT"
15169   "operands[2] = gen_reg_rtx (DImode);")
15170
15171 (define_insn "*ffsdi_1"
15172   [(set (reg:CCZ FLAGS_REG)
15173         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15174                      (const_int 0)))
15175    (set (match_operand:DI 0 "register_operand" "=r")
15176         (ctz:DI (match_dup 1)))]
15177   "TARGET_64BIT"
15178   "bsf{q}\t{%1, %0|%0, %1}"
15179   [(set_attr "prefix_0f" "1")])
15180
15181 (define_insn "ctzsi2"
15182   [(set (match_operand:SI 0 "register_operand" "=r")
15183         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15184    (clobber (reg:CC FLAGS_REG))]
15185   ""
15186   "bsf{l}\t{%1, %0|%0, %1}"
15187   [(set_attr "prefix_0f" "1")])
15188
15189 (define_insn "ctzdi2"
15190   [(set (match_operand:DI 0 "register_operand" "=r")
15191         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15192    (clobber (reg:CC FLAGS_REG))]
15193   "TARGET_64BIT"
15194   "bsf{q}\t{%1, %0|%0, %1}"
15195   [(set_attr "prefix_0f" "1")])
15196
15197 (define_expand "clzsi2"
15198   [(parallel
15199      [(set (match_operand:SI 0 "register_operand" "")
15200            (minus:SI (const_int 31)
15201                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15202       (clobber (reg:CC FLAGS_REG))])
15203    (parallel
15204      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15205       (clobber (reg:CC FLAGS_REG))])]
15206   ""
15207 {
15208   if (TARGET_ABM)
15209     {
15210       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15211       DONE;
15212     }
15213 })
15214
15215 (define_insn "clzsi2_abm"
15216   [(set (match_operand:SI 0 "register_operand" "=r")
15217         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15218    (clobber (reg:CC FLAGS_REG))]
15219   "TARGET_ABM"
15220   "lzcnt{l}\t{%1, %0|%0, %1}"
15221   [(set_attr "prefix_rep" "1")
15222    (set_attr "type" "bitmanip")
15223    (set_attr "mode" "SI")])
15224
15225 (define_insn "*bsr"
15226   [(set (match_operand:SI 0 "register_operand" "=r")
15227         (minus:SI (const_int 31)
15228                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15229    (clobber (reg:CC FLAGS_REG))]
15230   ""
15231   "bsr{l}\t{%1, %0|%0, %1}"
15232   [(set_attr "prefix_0f" "1")
15233    (set_attr "mode" "SI")])
15234
15235 (define_insn "popcountsi2"
15236   [(set (match_operand:SI 0 "register_operand" "=r")
15237         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15238    (clobber (reg:CC FLAGS_REG))]
15239   "TARGET_POPCNT"
15240   "popcnt{l}\t{%1, %0|%0, %1}"
15241   [(set_attr "prefix_rep" "1")
15242    (set_attr "type" "bitmanip")
15243    (set_attr "mode" "SI")])
15244
15245 (define_insn "*popcountsi2_cmp"
15246   [(set (reg FLAGS_REG)
15247         (compare
15248           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15249           (const_int 0)))
15250    (set (match_operand:SI 0 "register_operand" "=r")
15251         (popcount:SI (match_dup 1)))]
15252   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15253   "popcnt{l}\t{%1, %0|%0, %1}"
15254   [(set_attr "prefix_rep" "1")
15255    (set_attr "type" "bitmanip")
15256    (set_attr "mode" "SI")])
15257
15258 (define_insn "*popcountsi2_cmp_zext"
15259   [(set (reg FLAGS_REG)
15260         (compare
15261           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15262           (const_int 0)))
15263    (set (match_operand:DI 0 "register_operand" "=r")
15264         (zero_extend:DI(popcount:SI (match_dup 1))))]
15265   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15266   "popcnt{l}\t{%1, %0|%0, %1}"
15267   [(set_attr "prefix_rep" "1")
15268    (set_attr "type" "bitmanip")
15269    (set_attr "mode" "SI")])
15270
15271 (define_expand "bswapsi2"
15272   [(set (match_operand:SI 0 "register_operand" "")
15273         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15274   ""
15275 {
15276   if (!TARGET_BSWAP)
15277     {
15278       rtx x = operands[0];
15279
15280       emit_move_insn (x, operands[1]);
15281       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15282       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15283       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15284       DONE;
15285     }
15286 })
15287
15288 (define_insn "*bswapsi_1"
15289   [(set (match_operand:SI 0 "register_operand" "=r")
15290         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15291   "TARGET_BSWAP"
15292   "bswap\t%0"
15293   [(set_attr "prefix_0f" "1")
15294    (set_attr "length" "2")])
15295
15296 (define_insn "*bswaphi_lowpart_1"
15297   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15298         (bswap:HI (match_dup 0)))
15299    (clobber (reg:CC FLAGS_REG))]
15300   "TARGET_USE_XCHGB || optimize_size"
15301   "@
15302     xchg{b}\t{%h0, %b0|%b0, %h0}
15303     rol{w}\t{$8, %0|%0, 8}"
15304   [(set_attr "length" "2,4")
15305    (set_attr "mode" "QI,HI")])
15306
15307 (define_insn "bswaphi_lowpart"
15308   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15309         (bswap:HI (match_dup 0)))
15310    (clobber (reg:CC FLAGS_REG))]
15311   ""
15312   "rol{w}\t{$8, %0|%0, 8}"
15313   [(set_attr "length" "4")
15314    (set_attr "mode" "HI")])
15315
15316 (define_insn "bswapdi2"
15317   [(set (match_operand:DI 0 "register_operand" "=r")
15318         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15319   "TARGET_64BIT"
15320   "bswap\t%0"
15321   [(set_attr "prefix_0f" "1")
15322    (set_attr "length" "3")])
15323
15324 (define_expand "clzdi2"
15325   [(parallel
15326      [(set (match_operand:DI 0 "register_operand" "")
15327            (minus:DI (const_int 63)
15328                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15329       (clobber (reg:CC FLAGS_REG))])
15330    (parallel
15331      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15332       (clobber (reg:CC FLAGS_REG))])]
15333   "TARGET_64BIT"
15334 {
15335   if (TARGET_ABM)
15336     {
15337       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15338       DONE;
15339     }
15340 })
15341
15342 (define_insn "clzdi2_abm"
15343   [(set (match_operand:DI 0 "register_operand" "=r")
15344         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15345    (clobber (reg:CC FLAGS_REG))]
15346   "TARGET_64BIT && TARGET_ABM"
15347   "lzcnt{q}\t{%1, %0|%0, %1}"
15348   [(set_attr "prefix_rep" "1")
15349    (set_attr "type" "bitmanip")
15350    (set_attr "mode" "DI")])
15351
15352 (define_insn "*bsr_rex64"
15353   [(set (match_operand:DI 0 "register_operand" "=r")
15354         (minus:DI (const_int 63)
15355                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15356    (clobber (reg:CC FLAGS_REG))]
15357   "TARGET_64BIT"
15358   "bsr{q}\t{%1, %0|%0, %1}"
15359   [(set_attr "prefix_0f" "1")
15360    (set_attr "mode" "DI")])
15361
15362 (define_insn "popcountdi2"
15363   [(set (match_operand:DI 0 "register_operand" "=r")
15364         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15365    (clobber (reg:CC FLAGS_REG))]
15366   "TARGET_64BIT && TARGET_POPCNT"
15367   "popcnt{q}\t{%1, %0|%0, %1}"
15368   [(set_attr "prefix_rep" "1")
15369    (set_attr "type" "bitmanip")
15370    (set_attr "mode" "DI")])
15371
15372 (define_insn "*popcountdi2_cmp"
15373   [(set (reg FLAGS_REG)
15374         (compare
15375           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15376           (const_int 0)))
15377    (set (match_operand:DI 0 "register_operand" "=r")
15378         (popcount:DI (match_dup 1)))]
15379   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15380   "popcnt{q}\t{%1, %0|%0, %1}"
15381   [(set_attr "prefix_rep" "1")
15382    (set_attr "type" "bitmanip")
15383    (set_attr "mode" "DI")])
15384
15385 (define_expand "clzhi2"
15386   [(parallel
15387      [(set (match_operand:HI 0 "register_operand" "")
15388            (minus:HI (const_int 15)
15389                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15390       (clobber (reg:CC FLAGS_REG))])
15391    (parallel
15392      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15393       (clobber (reg:CC FLAGS_REG))])]
15394   ""
15395 {
15396   if (TARGET_ABM)
15397     {
15398       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15399       DONE;
15400     }
15401 })
15402
15403 (define_insn "clzhi2_abm"
15404   [(set (match_operand:HI 0 "register_operand" "=r")
15405         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15406    (clobber (reg:CC FLAGS_REG))]
15407   "TARGET_ABM"
15408   "lzcnt{w}\t{%1, %0|%0, %1}"
15409   [(set_attr "prefix_rep" "1")
15410    (set_attr "type" "bitmanip")
15411    (set_attr "mode" "HI")])
15412
15413 (define_insn "*bsrhi"
15414   [(set (match_operand:HI 0 "register_operand" "=r")
15415         (minus:HI (const_int 15)
15416                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15417    (clobber (reg:CC FLAGS_REG))]
15418   ""
15419   "bsr{w}\t{%1, %0|%0, %1}"
15420   [(set_attr "prefix_0f" "1")
15421    (set_attr "mode" "HI")])
15422
15423 (define_insn "popcounthi2"
15424   [(set (match_operand:HI 0 "register_operand" "=r")
15425         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15426    (clobber (reg:CC FLAGS_REG))]
15427   "TARGET_POPCNT"
15428   "popcnt{w}\t{%1, %0|%0, %1}"
15429   [(set_attr "prefix_rep" "1")
15430    (set_attr "type" "bitmanip")
15431    (set_attr "mode" "HI")])
15432
15433 (define_insn "*popcounthi2_cmp"
15434   [(set (reg FLAGS_REG)
15435         (compare
15436           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15437           (const_int 0)))
15438    (set (match_operand:HI 0 "register_operand" "=r")
15439         (popcount:HI (match_dup 1)))]
15440   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15441   "popcnt{w}\t{%1, %0|%0, %1}"
15442   [(set_attr "prefix_rep" "1")
15443    (set_attr "type" "bitmanip")
15444    (set_attr "mode" "HI")])
15445
15446 (define_expand "paritydi2"
15447   [(set (match_operand:DI 0 "register_operand" "")
15448         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15449   "! TARGET_POPCNT"
15450 {
15451   rtx scratch = gen_reg_rtx (QImode);
15452   rtx cond;
15453
15454   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15455                                 NULL_RTX, operands[1]));
15456
15457   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15458                          gen_rtx_REG (CCmode, FLAGS_REG),
15459                          const0_rtx);
15460   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15461
15462   if (TARGET_64BIT)
15463     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15464   else
15465     {
15466       rtx tmp = gen_reg_rtx (SImode);
15467
15468       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15469       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15470     }
15471   DONE;
15472 })
15473
15474 (define_insn_and_split "paritydi2_cmp"
15475   [(set (reg:CC FLAGS_REG)
15476         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15477    (clobber (match_scratch:DI 0 "=r,X"))
15478    (clobber (match_scratch:SI 1 "=r,r"))
15479    (clobber (match_scratch:HI 2 "=Q,Q"))]
15480   "! TARGET_POPCNT"
15481   "#"
15482   "&& reload_completed"
15483   [(parallel
15484      [(set (match_dup 1)
15485            (xor:SI (match_dup 1) (match_dup 4)))
15486       (clobber (reg:CC FLAGS_REG))])
15487    (parallel
15488      [(set (reg:CC FLAGS_REG)
15489            (parity:CC (match_dup 1)))
15490       (clobber (match_dup 1))
15491       (clobber (match_dup 2))])]
15492 {
15493   operands[4] = gen_lowpart (SImode, operands[3]);
15494
15495   if (MEM_P (operands[3]))
15496     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15497   else if (! TARGET_64BIT)
15498     operands[1] = gen_highpart (SImode, operands[3]);
15499   else
15500     {
15501       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15502       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15503     }
15504 })
15505
15506 (define_expand "paritysi2"
15507   [(set (match_operand:SI 0 "register_operand" "")
15508         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15509   "! TARGET_POPCNT"
15510 {
15511   rtx scratch = gen_reg_rtx (QImode);
15512   rtx cond;
15513
15514   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15515
15516   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15517                          gen_rtx_REG (CCmode, FLAGS_REG),
15518                          const0_rtx);
15519   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15520
15521   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15522   DONE;
15523 })
15524
15525 (define_insn_and_split "paritysi2_cmp"
15526   [(set (reg:CC FLAGS_REG)
15527         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15528    (clobber (match_scratch:SI 0 "=r,X"))
15529    (clobber (match_scratch:HI 1 "=Q,Q"))]
15530   "! TARGET_POPCNT"
15531   "#"
15532   "&& reload_completed"
15533   [(parallel
15534      [(set (match_dup 1)
15535            (xor:HI (match_dup 1) (match_dup 3)))
15536       (clobber (reg:CC FLAGS_REG))])
15537    (parallel
15538      [(set (reg:CC FLAGS_REG)
15539            (parity:CC (match_dup 1)))
15540       (clobber (match_dup 1))])]
15541 {
15542   operands[3] = gen_lowpart (HImode, operands[2]);
15543
15544   if (MEM_P (operands[2]))
15545     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15546   else
15547     {
15548       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15549       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15550     }
15551 })
15552
15553 (define_insn "*parityhi2_cmp"
15554   [(set (reg:CC FLAGS_REG)
15555         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15556    (clobber (match_scratch:HI 0 "=Q"))]
15557   "! TARGET_POPCNT"
15558   "xor{b}\t{%h0, %b0|%b0, %h0}"
15559   [(set_attr "length" "2")
15560    (set_attr "mode" "HI")])
15561
15562 (define_insn "*parityqi2_cmp"
15563   [(set (reg:CC FLAGS_REG)
15564         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15565   "! TARGET_POPCNT"
15566   "test{b}\t%0, %0"
15567   [(set_attr "length" "2")
15568    (set_attr "mode" "QI")])
15569 \f
15570 ;; Thread-local storage patterns for ELF.
15571 ;;
15572 ;; Note that these code sequences must appear exactly as shown
15573 ;; in order to allow linker relaxation.
15574
15575 (define_insn "*tls_global_dynamic_32_gnu"
15576   [(set (match_operand:SI 0 "register_operand" "=a")
15577         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15578                     (match_operand:SI 2 "tls_symbolic_operand" "")
15579                     (match_operand:SI 3 "call_insn_operand" "")]
15580                     UNSPEC_TLS_GD))
15581    (clobber (match_scratch:SI 4 "=d"))
15582    (clobber (match_scratch:SI 5 "=c"))
15583    (clobber (reg:CC FLAGS_REG))]
15584   "!TARGET_64BIT && TARGET_GNU_TLS"
15585   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15586   [(set_attr "type" "multi")
15587    (set_attr "length" "12")])
15588
15589 (define_insn "*tls_global_dynamic_32_sun"
15590   [(set (match_operand:SI 0 "register_operand" "=a")
15591         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15592                     (match_operand:SI 2 "tls_symbolic_operand" "")
15593                     (match_operand:SI 3 "call_insn_operand" "")]
15594                     UNSPEC_TLS_GD))
15595    (clobber (match_scratch:SI 4 "=d"))
15596    (clobber (match_scratch:SI 5 "=c"))
15597    (clobber (reg:CC FLAGS_REG))]
15598   "!TARGET_64BIT && TARGET_SUN_TLS"
15599   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15600         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15601   [(set_attr "type" "multi")
15602    (set_attr "length" "14")])
15603
15604 (define_expand "tls_global_dynamic_32"
15605   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15606                    (unspec:SI
15607                     [(match_dup 2)
15608                      (match_operand:SI 1 "tls_symbolic_operand" "")
15609                      (match_dup 3)]
15610                     UNSPEC_TLS_GD))
15611               (clobber (match_scratch:SI 4 ""))
15612               (clobber (match_scratch:SI 5 ""))
15613               (clobber (reg:CC FLAGS_REG))])]
15614   ""
15615 {
15616   if (flag_pic)
15617     operands[2] = pic_offset_table_rtx;
15618   else
15619     {
15620       operands[2] = gen_reg_rtx (Pmode);
15621       emit_insn (gen_set_got (operands[2]));
15622     }
15623   if (TARGET_GNU2_TLS)
15624     {
15625        emit_insn (gen_tls_dynamic_gnu2_32
15626                   (operands[0], operands[1], operands[2]));
15627        DONE;
15628     }
15629   operands[3] = ix86_tls_get_addr ();
15630 })
15631
15632 (define_insn "*tls_global_dynamic_64"
15633   [(set (match_operand:DI 0 "register_operand" "=a")
15634         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15635                  (match_operand:DI 3 "" "")))
15636    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15637               UNSPEC_TLS_GD)]
15638   "TARGET_64BIT"
15639   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15640   [(set_attr "type" "multi")
15641    (set_attr "length" "16")])
15642
15643 (define_expand "tls_global_dynamic_64"
15644   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15645                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15646               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15647                          UNSPEC_TLS_GD)])]
15648   ""
15649 {
15650   if (TARGET_GNU2_TLS)
15651     {
15652        emit_insn (gen_tls_dynamic_gnu2_64
15653                   (operands[0], operands[1]));
15654        DONE;
15655     }
15656   operands[2] = ix86_tls_get_addr ();
15657 })
15658
15659 (define_insn "*tls_local_dynamic_base_32_gnu"
15660   [(set (match_operand:SI 0 "register_operand" "=a")
15661         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15662                     (match_operand:SI 2 "call_insn_operand" "")]
15663                    UNSPEC_TLS_LD_BASE))
15664    (clobber (match_scratch:SI 3 "=d"))
15665    (clobber (match_scratch:SI 4 "=c"))
15666    (clobber (reg:CC FLAGS_REG))]
15667   "!TARGET_64BIT && TARGET_GNU_TLS"
15668   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15669   [(set_attr "type" "multi")
15670    (set_attr "length" "11")])
15671
15672 (define_insn "*tls_local_dynamic_base_32_sun"
15673   [(set (match_operand:SI 0 "register_operand" "=a")
15674         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15675                     (match_operand:SI 2 "call_insn_operand" "")]
15676                    UNSPEC_TLS_LD_BASE))
15677    (clobber (match_scratch:SI 3 "=d"))
15678    (clobber (match_scratch:SI 4 "=c"))
15679    (clobber (reg:CC FLAGS_REG))]
15680   "!TARGET_64BIT && TARGET_SUN_TLS"
15681   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15682         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15683   [(set_attr "type" "multi")
15684    (set_attr "length" "13")])
15685
15686 (define_expand "tls_local_dynamic_base_32"
15687   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15688                    (unspec:SI [(match_dup 1) (match_dup 2)]
15689                               UNSPEC_TLS_LD_BASE))
15690               (clobber (match_scratch:SI 3 ""))
15691               (clobber (match_scratch:SI 4 ""))
15692               (clobber (reg:CC FLAGS_REG))])]
15693   ""
15694 {
15695   if (flag_pic)
15696     operands[1] = pic_offset_table_rtx;
15697   else
15698     {
15699       operands[1] = gen_reg_rtx (Pmode);
15700       emit_insn (gen_set_got (operands[1]));
15701     }
15702   if (TARGET_GNU2_TLS)
15703     {
15704        emit_insn (gen_tls_dynamic_gnu2_32
15705                   (operands[0], ix86_tls_module_base (), operands[1]));
15706        DONE;
15707     }
15708   operands[2] = ix86_tls_get_addr ();
15709 })
15710
15711 (define_insn "*tls_local_dynamic_base_64"
15712   [(set (match_operand:DI 0 "register_operand" "=a")
15713         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15714                  (match_operand:DI 2 "" "")))
15715    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15716   "TARGET_64BIT"
15717   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15718   [(set_attr "type" "multi")
15719    (set_attr "length" "12")])
15720
15721 (define_expand "tls_local_dynamic_base_64"
15722   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15723                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15724               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15725   ""
15726 {
15727   if (TARGET_GNU2_TLS)
15728     {
15729        emit_insn (gen_tls_dynamic_gnu2_64
15730                   (operands[0], ix86_tls_module_base ()));
15731        DONE;
15732     }
15733   operands[1] = ix86_tls_get_addr ();
15734 })
15735
15736 ;; Local dynamic of a single variable is a lose.  Show combine how
15737 ;; to convert that back to global dynamic.
15738
15739 (define_insn_and_split "*tls_local_dynamic_32_once"
15740   [(set (match_operand:SI 0 "register_operand" "=a")
15741         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15742                              (match_operand:SI 2 "call_insn_operand" "")]
15743                             UNSPEC_TLS_LD_BASE)
15744                  (const:SI (unspec:SI
15745                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15746                             UNSPEC_DTPOFF))))
15747    (clobber (match_scratch:SI 4 "=d"))
15748    (clobber (match_scratch:SI 5 "=c"))
15749    (clobber (reg:CC FLAGS_REG))]
15750   ""
15751   "#"
15752   ""
15753   [(parallel [(set (match_dup 0)
15754                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15755                               UNSPEC_TLS_GD))
15756               (clobber (match_dup 4))
15757               (clobber (match_dup 5))
15758               (clobber (reg:CC FLAGS_REG))])]
15759   "")
15760
15761 ;; Load and add the thread base pointer from %gs:0.
15762
15763 (define_insn "*load_tp_si"
15764   [(set (match_operand:SI 0 "register_operand" "=r")
15765         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15766   "!TARGET_64BIT"
15767   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15768   [(set_attr "type" "imov")
15769    (set_attr "modrm" "0")
15770    (set_attr "length" "7")
15771    (set_attr "memory" "load")
15772    (set_attr "imm_disp" "false")])
15773
15774 (define_insn "*add_tp_si"
15775   [(set (match_operand:SI 0 "register_operand" "=r")
15776         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15777                  (match_operand:SI 1 "register_operand" "0")))
15778    (clobber (reg:CC FLAGS_REG))]
15779   "!TARGET_64BIT"
15780   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15781   [(set_attr "type" "alu")
15782    (set_attr "modrm" "0")
15783    (set_attr "length" "7")
15784    (set_attr "memory" "load")
15785    (set_attr "imm_disp" "false")])
15786
15787 (define_insn "*load_tp_di"
15788   [(set (match_operand:DI 0 "register_operand" "=r")
15789         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15790   "TARGET_64BIT"
15791   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15792   [(set_attr "type" "imov")
15793    (set_attr "modrm" "0")
15794    (set_attr "length" "7")
15795    (set_attr "memory" "load")
15796    (set_attr "imm_disp" "false")])
15797
15798 (define_insn "*add_tp_di"
15799   [(set (match_operand:DI 0 "register_operand" "=r")
15800         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15801                  (match_operand:DI 1 "register_operand" "0")))
15802    (clobber (reg:CC FLAGS_REG))]
15803   "TARGET_64BIT"
15804   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15805   [(set_attr "type" "alu")
15806    (set_attr "modrm" "0")
15807    (set_attr "length" "7")
15808    (set_attr "memory" "load")
15809    (set_attr "imm_disp" "false")])
15810
15811 ;; GNU2 TLS patterns can be split.
15812
15813 (define_expand "tls_dynamic_gnu2_32"
15814   [(set (match_dup 3)
15815         (plus:SI (match_operand:SI 2 "register_operand" "")
15816                  (const:SI
15817                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15818                              UNSPEC_TLSDESC))))
15819    (parallel
15820     [(set (match_operand:SI 0 "register_operand" "")
15821           (unspec:SI [(match_dup 1) (match_dup 3)
15822                       (match_dup 2) (reg:SI SP_REG)]
15823                       UNSPEC_TLSDESC))
15824      (clobber (reg:CC FLAGS_REG))])]
15825   "!TARGET_64BIT && TARGET_GNU2_TLS"
15826 {
15827   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15828   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15829 })
15830
15831 (define_insn "*tls_dynamic_lea_32"
15832   [(set (match_operand:SI 0 "register_operand" "=r")
15833         (plus:SI (match_operand:SI 1 "register_operand" "b")
15834                  (const:SI
15835                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15836                               UNSPEC_TLSDESC))))]
15837   "!TARGET_64BIT && TARGET_GNU2_TLS"
15838   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15839   [(set_attr "type" "lea")
15840    (set_attr "mode" "SI")
15841    (set_attr "length" "6")
15842    (set_attr "length_address" "4")])
15843
15844 (define_insn "*tls_dynamic_call_32"
15845   [(set (match_operand:SI 0 "register_operand" "=a")
15846         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15847                     (match_operand:SI 2 "register_operand" "0")
15848                     ;; we have to make sure %ebx still points to the GOT
15849                     (match_operand:SI 3 "register_operand" "b")
15850                     (reg:SI SP_REG)]
15851                    UNSPEC_TLSDESC))
15852    (clobber (reg:CC FLAGS_REG))]
15853   "!TARGET_64BIT && TARGET_GNU2_TLS"
15854   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15855   [(set_attr "type" "call")
15856    (set_attr "length" "2")
15857    (set_attr "length_address" "0")])
15858
15859 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15860   [(set (match_operand:SI 0 "register_operand" "=&a")
15861         (plus:SI
15862          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15863                      (match_operand:SI 4 "" "")
15864                      (match_operand:SI 2 "register_operand" "b")
15865                      (reg:SI SP_REG)]
15866                     UNSPEC_TLSDESC)
15867          (const:SI (unspec:SI
15868                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15869                     UNSPEC_DTPOFF))))
15870    (clobber (reg:CC FLAGS_REG))]
15871   "!TARGET_64BIT && TARGET_GNU2_TLS"
15872   "#"
15873   ""
15874   [(set (match_dup 0) (match_dup 5))]
15875 {
15876   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15877   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15878 })
15879
15880 (define_expand "tls_dynamic_gnu2_64"
15881   [(set (match_dup 2)
15882         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15883                    UNSPEC_TLSDESC))
15884    (parallel
15885     [(set (match_operand:DI 0 "register_operand" "")
15886           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15887                      UNSPEC_TLSDESC))
15888      (clobber (reg:CC FLAGS_REG))])]
15889   "TARGET_64BIT && TARGET_GNU2_TLS"
15890 {
15891   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15892   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15893 })
15894
15895 (define_insn "*tls_dynamic_lea_64"
15896   [(set (match_operand:DI 0 "register_operand" "=r")
15897         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15898                    UNSPEC_TLSDESC))]
15899   "TARGET_64BIT && TARGET_GNU2_TLS"
15900   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15901   [(set_attr "type" "lea")
15902    (set_attr "mode" "DI")
15903    (set_attr "length" "7")
15904    (set_attr "length_address" "4")])
15905
15906 (define_insn "*tls_dynamic_call_64"
15907   [(set (match_operand:DI 0 "register_operand" "=a")
15908         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15909                     (match_operand:DI 2 "register_operand" "0")
15910                     (reg:DI SP_REG)]
15911                    UNSPEC_TLSDESC))
15912    (clobber (reg:CC FLAGS_REG))]
15913   "TARGET_64BIT && TARGET_GNU2_TLS"
15914   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15915   [(set_attr "type" "call")
15916    (set_attr "length" "2")
15917    (set_attr "length_address" "0")])
15918
15919 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15920   [(set (match_operand:DI 0 "register_operand" "=&a")
15921         (plus:DI
15922          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15923                      (match_operand:DI 3 "" "")
15924                      (reg:DI SP_REG)]
15925                     UNSPEC_TLSDESC)
15926          (const:DI (unspec:DI
15927                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15928                     UNSPEC_DTPOFF))))
15929    (clobber (reg:CC FLAGS_REG))]
15930   "TARGET_64BIT && TARGET_GNU2_TLS"
15931   "#"
15932   ""
15933   [(set (match_dup 0) (match_dup 4))]
15934 {
15935   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15936   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15937 })
15938
15939 ;;
15940 \f
15941 ;; These patterns match the binary 387 instructions for addM3, subM3,
15942 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15943 ;; SFmode.  The first is the normal insn, the second the same insn but
15944 ;; with one operand a conversion, and the third the same insn but with
15945 ;; the other operand a conversion.  The conversion may be SFmode or
15946 ;; SImode if the target mode DFmode, but only SImode if the target mode
15947 ;; is SFmode.
15948
15949 ;; Gcc is slightly more smart about handling normal two address instructions
15950 ;; so use special patterns for add and mull.
15951
15952 (define_insn "*fop_sf_comm_mixed"
15953   [(set (match_operand:SF 0 "register_operand" "=f,x")
15954         (match_operator:SF 3 "binary_fp_operator"
15955                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15956                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15957   "TARGET_MIX_SSE_I387
15958    && COMMUTATIVE_ARITH_P (operands[3])
15959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960   "* return output_387_binary_op (insn, operands);"
15961   [(set (attr "type")
15962         (if_then_else (eq_attr "alternative" "1")
15963            (if_then_else (match_operand:SF 3 "mult_operator" "")
15964               (const_string "ssemul")
15965               (const_string "sseadd"))
15966            (if_then_else (match_operand:SF 3 "mult_operator" "")
15967               (const_string "fmul")
15968               (const_string "fop"))))
15969    (set_attr "mode" "SF")])
15970
15971 (define_insn "*fop_sf_comm_sse"
15972   [(set (match_operand:SF 0 "register_operand" "=x")
15973         (match_operator:SF 3 "binary_fp_operator"
15974                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15975                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15976   "TARGET_SSE_MATH
15977    && COMMUTATIVE_ARITH_P (operands[3])
15978    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15979   "* return output_387_binary_op (insn, operands);"
15980   [(set (attr "type")
15981         (if_then_else (match_operand:SF 3 "mult_operator" "")
15982            (const_string "ssemul")
15983            (const_string "sseadd")))
15984    (set_attr "mode" "SF")])
15985
15986 (define_insn "*fop_sf_comm_i387"
15987   [(set (match_operand:SF 0 "register_operand" "=f")
15988         (match_operator:SF 3 "binary_fp_operator"
15989                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15990                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15991   "TARGET_80387
15992    && COMMUTATIVE_ARITH_P (operands[3])
15993    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15994   "* return output_387_binary_op (insn, operands);"
15995   [(set (attr "type")
15996         (if_then_else (match_operand:SF 3 "mult_operator" "")
15997            (const_string "fmul")
15998            (const_string "fop")))
15999    (set_attr "mode" "SF")])
16000
16001 (define_insn "*fop_sf_1_mixed"
16002   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16003         (match_operator:SF 3 "binary_fp_operator"
16004                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16005                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16006   "TARGET_MIX_SSE_I387
16007    && !COMMUTATIVE_ARITH_P (operands[3])
16008    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16009   "* return output_387_binary_op (insn, operands);"
16010   [(set (attr "type")
16011         (cond [(and (eq_attr "alternative" "2")
16012                     (match_operand:SF 3 "mult_operator" ""))
16013                  (const_string "ssemul")
16014                (and (eq_attr "alternative" "2")
16015                     (match_operand:SF 3 "div_operator" ""))
16016                  (const_string "ssediv")
16017                (eq_attr "alternative" "2")
16018                  (const_string "sseadd")
16019                (match_operand:SF 3 "mult_operator" "")
16020                  (const_string "fmul")
16021                (match_operand:SF 3 "div_operator" "")
16022                  (const_string "fdiv")
16023               ]
16024               (const_string "fop")))
16025    (set_attr "mode" "SF")])
16026
16027 (define_insn "*rcpsf2_sse"
16028   [(set (match_operand:SF 0 "register_operand" "=x")
16029         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16030                    UNSPEC_RCP))]
16031   "TARGET_SSE_MATH"
16032   "rcpss\t{%1, %0|%0, %1}"
16033   [(set_attr "type" "sse")
16034    (set_attr "mode" "SF")])
16035
16036 (define_insn "*fop_sf_1_sse"
16037   [(set (match_operand:SF 0 "register_operand" "=x")
16038         (match_operator:SF 3 "binary_fp_operator"
16039                         [(match_operand:SF 1 "register_operand" "0")
16040                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16041   "TARGET_SSE_MATH
16042    && !COMMUTATIVE_ARITH_P (operands[3])"
16043   "* return output_387_binary_op (insn, operands);"
16044   [(set (attr "type")
16045         (cond [(match_operand:SF 3 "mult_operator" "")
16046                  (const_string "ssemul")
16047                (match_operand:SF 3 "div_operator" "")
16048                  (const_string "ssediv")
16049               ]
16050               (const_string "sseadd")))
16051    (set_attr "mode" "SF")])
16052
16053 ;; This pattern is not fully shadowed by the pattern above.
16054 (define_insn "*fop_sf_1_i387"
16055   [(set (match_operand:SF 0 "register_operand" "=f,f")
16056         (match_operator:SF 3 "binary_fp_operator"
16057                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16058                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16059   "TARGET_80387 && !TARGET_SSE_MATH
16060    && !COMMUTATIVE_ARITH_P (operands[3])
16061    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16062   "* return output_387_binary_op (insn, operands);"
16063   [(set (attr "type")
16064         (cond [(match_operand:SF 3 "mult_operator" "")
16065                  (const_string "fmul")
16066                (match_operand:SF 3 "div_operator" "")
16067                  (const_string "fdiv")
16068               ]
16069               (const_string "fop")))
16070    (set_attr "mode" "SF")])
16071
16072 ;; ??? Add SSE splitters for these!
16073 (define_insn "*fop_sf_2<mode>_i387"
16074   [(set (match_operand:SF 0 "register_operand" "=f,f")
16075         (match_operator:SF 3 "binary_fp_operator"
16076           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16077            (match_operand:SF 2 "register_operand" "0,0")]))]
16078   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16079   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16080   [(set (attr "type")
16081         (cond [(match_operand:SF 3 "mult_operator" "")
16082                  (const_string "fmul")
16083                (match_operand:SF 3 "div_operator" "")
16084                  (const_string "fdiv")
16085               ]
16086               (const_string "fop")))
16087    (set_attr "fp_int_src" "true")
16088    (set_attr "mode" "<MODE>")])
16089
16090 (define_insn "*fop_sf_3<mode>_i387"
16091   [(set (match_operand:SF 0 "register_operand" "=f,f")
16092         (match_operator:SF 3 "binary_fp_operator"
16093           [(match_operand:SF 1 "register_operand" "0,0")
16094            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16095   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16096   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16097   [(set (attr "type")
16098         (cond [(match_operand:SF 3 "mult_operator" "")
16099                  (const_string "fmul")
16100                (match_operand:SF 3 "div_operator" "")
16101                  (const_string "fdiv")
16102               ]
16103               (const_string "fop")))
16104    (set_attr "fp_int_src" "true")
16105    (set_attr "mode" "<MODE>")])
16106
16107 (define_insn "*fop_df_comm_mixed"
16108   [(set (match_operand:DF 0 "register_operand" "=f,x")
16109         (match_operator:DF 3 "binary_fp_operator"
16110           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16111            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16112   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16113    && COMMUTATIVE_ARITH_P (operands[3])
16114    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16115   "* return output_387_binary_op (insn, operands);"
16116   [(set (attr "type")
16117         (if_then_else (eq_attr "alternative" "1")
16118            (if_then_else (match_operand:DF 3 "mult_operator" "")
16119               (const_string "ssemul")
16120               (const_string "sseadd"))
16121            (if_then_else (match_operand:DF 3 "mult_operator" "")
16122               (const_string "fmul")
16123               (const_string "fop"))))
16124    (set_attr "mode" "DF")])
16125
16126 (define_insn "*fop_df_comm_sse"
16127   [(set (match_operand:DF 0 "register_operand" "=x")
16128         (match_operator:DF 3 "binary_fp_operator"
16129           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16130            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16131   "TARGET_SSE2 && TARGET_SSE_MATH
16132    && COMMUTATIVE_ARITH_P (operands[3])
16133    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134   "* return output_387_binary_op (insn, operands);"
16135   [(set (attr "type")
16136         (if_then_else (match_operand:DF 3 "mult_operator" "")
16137            (const_string "ssemul")
16138            (const_string "sseadd")))
16139    (set_attr "mode" "DF")])
16140
16141 (define_insn "*fop_df_comm_i387"
16142   [(set (match_operand:DF 0 "register_operand" "=f")
16143         (match_operator:DF 3 "binary_fp_operator"
16144                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16145                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16146   "TARGET_80387
16147    && COMMUTATIVE_ARITH_P (operands[3])
16148    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16149   "* return output_387_binary_op (insn, operands);"
16150   [(set (attr "type")
16151         (if_then_else (match_operand:DF 3 "mult_operator" "")
16152            (const_string "fmul")
16153            (const_string "fop")))
16154    (set_attr "mode" "DF")])
16155
16156 (define_insn "*fop_df_1_mixed"
16157   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16158         (match_operator:DF 3 "binary_fp_operator"
16159           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16160            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16161   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16162    && !COMMUTATIVE_ARITH_P (operands[3])
16163    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16164   "* return output_387_binary_op (insn, operands);"
16165   [(set (attr "type")
16166         (cond [(and (eq_attr "alternative" "2")
16167                     (match_operand:DF 3 "mult_operator" ""))
16168                  (const_string "ssemul")
16169                (and (eq_attr "alternative" "2")
16170                     (match_operand:DF 3 "div_operator" ""))
16171                  (const_string "ssediv")
16172                (eq_attr "alternative" "2")
16173                  (const_string "sseadd")
16174                (match_operand:DF 3 "mult_operator" "")
16175                  (const_string "fmul")
16176                (match_operand:DF 3 "div_operator" "")
16177                  (const_string "fdiv")
16178               ]
16179               (const_string "fop")))
16180    (set_attr "mode" "DF")])
16181
16182 (define_insn "*fop_df_1_sse"
16183   [(set (match_operand:DF 0 "register_operand" "=x")
16184         (match_operator:DF 3 "binary_fp_operator"
16185           [(match_operand:DF 1 "register_operand" "0")
16186            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16187   "TARGET_SSE2 && TARGET_SSE_MATH
16188    && !COMMUTATIVE_ARITH_P (operands[3])"
16189   "* return output_387_binary_op (insn, operands);"
16190   [(set_attr "mode" "DF")
16191    (set (attr "type")
16192         (cond [(match_operand:DF 3 "mult_operator" "")
16193                  (const_string "ssemul")
16194                (match_operand:DF 3 "div_operator" "")
16195                  (const_string "ssediv")
16196               ]
16197               (const_string "sseadd")))])
16198
16199 ;; This pattern is not fully shadowed by the pattern above.
16200 (define_insn "*fop_df_1_i387"
16201   [(set (match_operand:DF 0 "register_operand" "=f,f")
16202         (match_operator:DF 3 "binary_fp_operator"
16203                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16204                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16205   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16206    && !COMMUTATIVE_ARITH_P (operands[3])
16207    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16208   "* return output_387_binary_op (insn, operands);"
16209   [(set (attr "type")
16210         (cond [(match_operand:DF 3 "mult_operator" "")
16211                  (const_string "fmul")
16212                (match_operand:DF 3 "div_operator" "")
16213                  (const_string "fdiv")
16214               ]
16215               (const_string "fop")))
16216    (set_attr "mode" "DF")])
16217
16218 ;; ??? Add SSE splitters for these!
16219 (define_insn "*fop_df_2<mode>_i387"
16220   [(set (match_operand:DF 0 "register_operand" "=f,f")
16221         (match_operator:DF 3 "binary_fp_operator"
16222            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16223             (match_operand:DF 2 "register_operand" "0,0")]))]
16224   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16225    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16226   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16227   [(set (attr "type")
16228         (cond [(match_operand:DF 3 "mult_operator" "")
16229                  (const_string "fmul")
16230                (match_operand:DF 3 "div_operator" "")
16231                  (const_string "fdiv")
16232               ]
16233               (const_string "fop")))
16234    (set_attr "fp_int_src" "true")
16235    (set_attr "mode" "<MODE>")])
16236
16237 (define_insn "*fop_df_3<mode>_i387"
16238   [(set (match_operand:DF 0 "register_operand" "=f,f")
16239         (match_operator:DF 3 "binary_fp_operator"
16240            [(match_operand:DF 1 "register_operand" "0,0")
16241             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16242   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16243    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16244   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16245   [(set (attr "type")
16246         (cond [(match_operand:DF 3 "mult_operator" "")
16247                  (const_string "fmul")
16248                (match_operand:DF 3 "div_operator" "")
16249                  (const_string "fdiv")
16250               ]
16251               (const_string "fop")))
16252    (set_attr "fp_int_src" "true")
16253    (set_attr "mode" "<MODE>")])
16254
16255 (define_insn "*fop_df_4_i387"
16256   [(set (match_operand:DF 0 "register_operand" "=f,f")
16257         (match_operator:DF 3 "binary_fp_operator"
16258            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16259             (match_operand:DF 2 "register_operand" "0,f")]))]
16260   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16262   "* return output_387_binary_op (insn, operands);"
16263   [(set (attr "type")
16264         (cond [(match_operand:DF 3 "mult_operator" "")
16265                  (const_string "fmul")
16266                (match_operand:DF 3 "div_operator" "")
16267                  (const_string "fdiv")
16268               ]
16269               (const_string "fop")))
16270    (set_attr "mode" "SF")])
16271
16272 (define_insn "*fop_df_5_i387"
16273   [(set (match_operand:DF 0 "register_operand" "=f,f")
16274         (match_operator:DF 3 "binary_fp_operator"
16275           [(match_operand:DF 1 "register_operand" "0,f")
16276            (float_extend:DF
16277             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16278   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16279   "* return output_387_binary_op (insn, operands);"
16280   [(set (attr "type")
16281         (cond [(match_operand:DF 3 "mult_operator" "")
16282                  (const_string "fmul")
16283                (match_operand:DF 3 "div_operator" "")
16284                  (const_string "fdiv")
16285               ]
16286               (const_string "fop")))
16287    (set_attr "mode" "SF")])
16288
16289 (define_insn "*fop_df_6_i387"
16290   [(set (match_operand:DF 0 "register_operand" "=f,f")
16291         (match_operator:DF 3 "binary_fp_operator"
16292           [(float_extend:DF
16293             (match_operand:SF 1 "register_operand" "0,f"))
16294            (float_extend:DF
16295             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16296   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16297   "* return output_387_binary_op (insn, operands);"
16298   [(set (attr "type")
16299         (cond [(match_operand:DF 3 "mult_operator" "")
16300                  (const_string "fmul")
16301                (match_operand:DF 3 "div_operator" "")
16302                  (const_string "fdiv")
16303               ]
16304               (const_string "fop")))
16305    (set_attr "mode" "SF")])
16306
16307 (define_insn "*fop_xf_comm_i387"
16308   [(set (match_operand:XF 0 "register_operand" "=f")
16309         (match_operator:XF 3 "binary_fp_operator"
16310                         [(match_operand:XF 1 "register_operand" "%0")
16311                          (match_operand:XF 2 "register_operand" "f")]))]
16312   "TARGET_80387
16313    && COMMUTATIVE_ARITH_P (operands[3])"
16314   "* return output_387_binary_op (insn, operands);"
16315   [(set (attr "type")
16316         (if_then_else (match_operand:XF 3 "mult_operator" "")
16317            (const_string "fmul")
16318            (const_string "fop")))
16319    (set_attr "mode" "XF")])
16320
16321 (define_insn "*fop_xf_1_i387"
16322   [(set (match_operand:XF 0 "register_operand" "=f,f")
16323         (match_operator:XF 3 "binary_fp_operator"
16324                         [(match_operand:XF 1 "register_operand" "0,f")
16325                          (match_operand:XF 2 "register_operand" "f,0")]))]
16326   "TARGET_80387
16327    && !COMMUTATIVE_ARITH_P (operands[3])"
16328   "* return output_387_binary_op (insn, operands);"
16329   [(set (attr "type")
16330         (cond [(match_operand:XF 3 "mult_operator" "")
16331                  (const_string "fmul")
16332                (match_operand:XF 3 "div_operator" "")
16333                  (const_string "fdiv")
16334               ]
16335               (const_string "fop")))
16336    (set_attr "mode" "XF")])
16337
16338 (define_insn "*fop_xf_2<mode>_i387"
16339   [(set (match_operand:XF 0 "register_operand" "=f,f")
16340         (match_operator:XF 3 "binary_fp_operator"
16341            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16342             (match_operand:XF 2 "register_operand" "0,0")]))]
16343   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16344   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16345   [(set (attr "type")
16346         (cond [(match_operand:XF 3 "mult_operator" "")
16347                  (const_string "fmul")
16348                (match_operand:XF 3 "div_operator" "")
16349                  (const_string "fdiv")
16350               ]
16351               (const_string "fop")))
16352    (set_attr "fp_int_src" "true")
16353    (set_attr "mode" "<MODE>")])
16354
16355 (define_insn "*fop_xf_3<mode>_i387"
16356   [(set (match_operand:XF 0 "register_operand" "=f,f")
16357         (match_operator:XF 3 "binary_fp_operator"
16358           [(match_operand:XF 1 "register_operand" "0,0")
16359            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16360   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16361   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16362   [(set (attr "type")
16363         (cond [(match_operand:XF 3 "mult_operator" "")
16364                  (const_string "fmul")
16365                (match_operand:XF 3 "div_operator" "")
16366                  (const_string "fdiv")
16367               ]
16368               (const_string "fop")))
16369    (set_attr "fp_int_src" "true")
16370    (set_attr "mode" "<MODE>")])
16371
16372 (define_insn "*fop_xf_4_i387"
16373   [(set (match_operand:XF 0 "register_operand" "=f,f")
16374         (match_operator:XF 3 "binary_fp_operator"
16375            [(float_extend:XF
16376               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16377             (match_operand:XF 2 "register_operand" "0,f")]))]
16378   "TARGET_80387"
16379   "* return output_387_binary_op (insn, operands);"
16380   [(set (attr "type")
16381         (cond [(match_operand:XF 3 "mult_operator" "")
16382                  (const_string "fmul")
16383                (match_operand:XF 3 "div_operator" "")
16384                  (const_string "fdiv")
16385               ]
16386               (const_string "fop")))
16387    (set_attr "mode" "SF")])
16388
16389 (define_insn "*fop_xf_5_i387"
16390   [(set (match_operand:XF 0 "register_operand" "=f,f")
16391         (match_operator:XF 3 "binary_fp_operator"
16392           [(match_operand:XF 1 "register_operand" "0,f")
16393            (float_extend:XF
16394              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16395   "TARGET_80387"
16396   "* return output_387_binary_op (insn, operands);"
16397   [(set (attr "type")
16398         (cond [(match_operand:XF 3 "mult_operator" "")
16399                  (const_string "fmul")
16400                (match_operand:XF 3 "div_operator" "")
16401                  (const_string "fdiv")
16402               ]
16403               (const_string "fop")))
16404    (set_attr "mode" "SF")])
16405
16406 (define_insn "*fop_xf_6_i387"
16407   [(set (match_operand:XF 0 "register_operand" "=f,f")
16408         (match_operator:XF 3 "binary_fp_operator"
16409           [(float_extend:XF
16410              (match_operand:MODEF 1 "register_operand" "0,f"))
16411            (float_extend:XF
16412              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16413   "TARGET_80387"
16414   "* return output_387_binary_op (insn, operands);"
16415   [(set (attr "type")
16416         (cond [(match_operand:XF 3 "mult_operator" "")
16417                  (const_string "fmul")
16418                (match_operand:XF 3 "div_operator" "")
16419                  (const_string "fdiv")
16420               ]
16421               (const_string "fop")))
16422    (set_attr "mode" "SF")])
16423
16424 (define_split
16425   [(set (match_operand 0 "register_operand" "")
16426         (match_operator 3 "binary_fp_operator"
16427            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16428             (match_operand 2 "register_operand" "")]))]
16429   "reload_completed
16430    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16431   [(const_int 0)]
16432 {
16433   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16434   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16435   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16436                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16437                                           GET_MODE (operands[3]),
16438                                           operands[4],
16439                                           operands[2])));
16440   ix86_free_from_memory (GET_MODE (operands[1]));
16441   DONE;
16442 })
16443
16444 (define_split
16445   [(set (match_operand 0 "register_operand" "")
16446         (match_operator 3 "binary_fp_operator"
16447            [(match_operand 1 "register_operand" "")
16448             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16449   "reload_completed
16450    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16451   [(const_int 0)]
16452 {
16453   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16454   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16455   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16456                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16457                                           GET_MODE (operands[3]),
16458                                           operands[1],
16459                                           operands[4])));
16460   ix86_free_from_memory (GET_MODE (operands[2]));
16461   DONE;
16462 })
16463 \f
16464 ;; FPU special functions.
16465
16466 ;; This pattern implements a no-op XFmode truncation for
16467 ;; all fancy i386 XFmode math functions.
16468
16469 (define_insn "truncxf<mode>2_i387_noop_unspec"
16470   [(set (match_operand:MODEF 0 "register_operand" "=f")
16471         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16472         UNSPEC_TRUNC_NOOP))]
16473   "TARGET_USE_FANCY_MATH_387"
16474   "* return output_387_reg_move (insn, operands);"
16475   [(set_attr "type" "fmov")
16476    (set_attr "mode" "<MODE>")])
16477
16478 (define_insn "sqrtxf2"
16479   [(set (match_operand:XF 0 "register_operand" "=f")
16480         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16481   "TARGET_USE_FANCY_MATH_387"
16482   "fsqrt"
16483   [(set_attr "type" "fpspc")
16484    (set_attr "mode" "XF")
16485    (set_attr "athlon_decode" "direct")
16486    (set_attr "amdfam10_decode" "direct")])
16487
16488 (define_insn "sqrt_extend<mode>xf2_i387"
16489   [(set (match_operand:XF 0 "register_operand" "=f")
16490         (sqrt:XF
16491           (float_extend:XF
16492             (match_operand:MODEF 1 "register_operand" "0"))))]
16493   "TARGET_USE_FANCY_MATH_387"
16494   "fsqrt"
16495   [(set_attr "type" "fpspc")
16496    (set_attr "mode" "XF")
16497    (set_attr "athlon_decode" "direct")
16498    (set_attr "amdfam10_decode" "direct")])
16499
16500 (define_insn "*rsqrtsf2_sse"
16501   [(set (match_operand:SF 0 "register_operand" "=x")
16502         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16503                    UNSPEC_RSQRT))]
16504   "TARGET_SSE_MATH"
16505   "rsqrtss\t{%1, %0|%0, %1}"
16506   [(set_attr "type" "sse")
16507    (set_attr "mode" "SF")])
16508
16509 (define_expand "rsqrtsf2"
16510   [(set (match_operand:SF 0 "register_operand" "")
16511         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16512                    UNSPEC_RSQRT))]
16513   "TARGET_SSE_MATH"
16514 {
16515   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16516   DONE;
16517 })
16518
16519 (define_insn "*sqrt<mode>2_sse"
16520   [(set (match_operand:MODEF 0 "register_operand" "=x")
16521         (sqrt:MODEF
16522           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16523   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16524   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16525   [(set_attr "type" "sse")
16526    (set_attr "mode" "<MODE>")
16527    (set_attr "athlon_decode" "*")
16528    (set_attr "amdfam10_decode" "*")])
16529
16530 (define_expand "sqrt<mode>2"
16531   [(set (match_operand:MODEF 0 "register_operand" "")
16532         (sqrt:MODEF
16533           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16534   "TARGET_USE_FANCY_MATH_387
16535    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16536 {
16537   if (<MODE>mode == SFmode
16538       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16539       && flag_finite_math_only && !flag_trapping_math
16540       && flag_unsafe_math_optimizations)
16541     {
16542       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16543       DONE;
16544     }
16545
16546   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16547     {
16548       rtx op0 = gen_reg_rtx (XFmode);
16549       rtx op1 = force_reg (<MODE>mode, operands[1]);
16550
16551       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16552       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16553       DONE;
16554    }
16555 })
16556
16557 (define_insn "fpremxf4_i387"
16558   [(set (match_operand:XF 0 "register_operand" "=f")
16559         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16560                     (match_operand:XF 3 "register_operand" "1")]
16561                    UNSPEC_FPREM_F))
16562    (set (match_operand:XF 1 "register_operand" "=u")
16563         (unspec:XF [(match_dup 2) (match_dup 3)]
16564                    UNSPEC_FPREM_U))
16565    (set (reg:CCFP FPSR_REG)
16566         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16567                      UNSPEC_C2_FLAG))]
16568   "TARGET_USE_FANCY_MATH_387"
16569   "fprem"
16570   [(set_attr "type" "fpspc")
16571    (set_attr "mode" "XF")])
16572
16573 (define_expand "fmodxf3"
16574   [(use (match_operand:XF 0 "register_operand" ""))
16575    (use (match_operand:XF 1 "register_operand" ""))
16576    (use (match_operand:XF 2 "register_operand" ""))]
16577   "TARGET_USE_FANCY_MATH_387"
16578 {
16579   rtx label = gen_label_rtx ();
16580
16581   rtx op2;
16582
16583   if (rtx_equal_p (operands[1], operands[2]))
16584     {
16585       op2 = gen_reg_rtx (XFmode);
16586       emit_move_insn (op2, operands[2]);
16587     }
16588   else
16589     op2 = operands[2];
16590
16591   emit_label (label);
16592   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16593   ix86_emit_fp_unordered_jump (label);
16594   LABEL_NUSES (label) = 1;
16595
16596   emit_move_insn (operands[0], operands[1]);
16597   DONE;
16598 })
16599
16600 (define_expand "fmod<mode>3"
16601   [(use (match_operand:MODEF 0 "register_operand" ""))
16602    (use (match_operand:MODEF 1 "general_operand" ""))
16603    (use (match_operand:MODEF 2 "general_operand" ""))]
16604   "TARGET_USE_FANCY_MATH_387"
16605 {
16606   rtx label = gen_label_rtx ();
16607
16608   rtx op1 = gen_reg_rtx (XFmode);
16609   rtx op2 = gen_reg_rtx (XFmode);
16610
16611   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16612   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16613
16614   emit_label (label);
16615   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16616   ix86_emit_fp_unordered_jump (label);
16617   LABEL_NUSES (label) = 1;
16618
16619   /* Truncate the result properly for strict SSE math.  */
16620   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16621       && !TARGET_MIX_SSE_I387)
16622     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16623   else
16624     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16625
16626   DONE;
16627 })
16628
16629 (define_insn "fprem1xf4_i387"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16632                     (match_operand:XF 3 "register_operand" "1")]
16633                    UNSPEC_FPREM1_F))
16634    (set (match_operand:XF 1 "register_operand" "=u")
16635         (unspec:XF [(match_dup 2) (match_dup 3)]
16636                    UNSPEC_FPREM1_U))
16637    (set (reg:CCFP FPSR_REG)
16638         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16639                      UNSPEC_C2_FLAG))]
16640   "TARGET_USE_FANCY_MATH_387"
16641   "fprem1"
16642   [(set_attr "type" "fpspc")
16643    (set_attr "mode" "XF")])
16644
16645 (define_expand "remainderxf3"
16646   [(use (match_operand:XF 0 "register_operand" ""))
16647    (use (match_operand:XF 1 "register_operand" ""))
16648    (use (match_operand:XF 2 "register_operand" ""))]
16649   "TARGET_USE_FANCY_MATH_387"
16650 {
16651   rtx label = gen_label_rtx ();
16652
16653   rtx op2;
16654
16655   if (rtx_equal_p (operands[1], operands[2]))
16656     {
16657       op2 = gen_reg_rtx (XFmode);
16658       emit_move_insn (op2, operands[2]);
16659     }
16660   else
16661     op2 = operands[2];
16662
16663   emit_label (label);
16664   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16665   ix86_emit_fp_unordered_jump (label);
16666   LABEL_NUSES (label) = 1;
16667
16668   emit_move_insn (operands[0], operands[1]);
16669   DONE;
16670 })
16671
16672 (define_expand "remainder<mode>3"
16673   [(use (match_operand:MODEF 0 "register_operand" ""))
16674    (use (match_operand:MODEF 1 "general_operand" ""))
16675    (use (match_operand:MODEF 2 "general_operand" ""))]
16676   "TARGET_USE_FANCY_MATH_387"
16677 {
16678   rtx label = gen_label_rtx ();
16679
16680   rtx op1 = gen_reg_rtx (XFmode);
16681   rtx op2 = gen_reg_rtx (XFmode);
16682
16683   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16684   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16685
16686   emit_label (label);
16687
16688   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16689   ix86_emit_fp_unordered_jump (label);
16690   LABEL_NUSES (label) = 1;
16691
16692   /* Truncate the result properly for strict SSE math.  */
16693   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16694       && !TARGET_MIX_SSE_I387)
16695     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16696   else
16697     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16698
16699   DONE;
16700 })
16701
16702 (define_insn "*sinxf2_i387"
16703   [(set (match_operand:XF 0 "register_operand" "=f")
16704         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16705   "TARGET_USE_FANCY_MATH_387
16706    && flag_unsafe_math_optimizations"
16707   "fsin"
16708   [(set_attr "type" "fpspc")
16709    (set_attr "mode" "XF")])
16710
16711 (define_insn "*sin_extend<mode>xf2_i387"
16712   [(set (match_operand:XF 0 "register_operand" "=f")
16713         (unspec:XF [(float_extend:XF
16714                       (match_operand:MODEF 1 "register_operand" "0"))]
16715                    UNSPEC_SIN))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16718        || TARGET_MIX_SSE_I387)
16719    && flag_unsafe_math_optimizations"
16720   "fsin"
16721   [(set_attr "type" "fpspc")
16722    (set_attr "mode" "XF")])
16723
16724 (define_insn "*cosxf2_i387"
16725   [(set (match_operand:XF 0 "register_operand" "=f")
16726         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16727   "TARGET_USE_FANCY_MATH_387
16728    && flag_unsafe_math_optimizations"
16729   "fcos"
16730   [(set_attr "type" "fpspc")
16731    (set_attr "mode" "XF")])
16732
16733 (define_insn "*cos_extend<mode>xf2_i387"
16734   [(set (match_operand:XF 0 "register_operand" "=f")
16735         (unspec:XF [(float_extend:XF
16736                       (match_operand:MODEF 1 "register_operand" "0"))]
16737                    UNSPEC_COS))]
16738   "TARGET_USE_FANCY_MATH_387
16739    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16740        || TARGET_MIX_SSE_I387)
16741    && flag_unsafe_math_optimizations"
16742   "fcos"
16743   [(set_attr "type" "fpspc")
16744    (set_attr "mode" "XF")])
16745
16746 ;; When sincos pattern is defined, sin and cos builtin functions will be
16747 ;; expanded to sincos pattern with one of its outputs left unused.
16748 ;; CSE pass will figure out if two sincos patterns can be combined,
16749 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16750 ;; depending on the unused output.
16751
16752 (define_insn "sincosxf3"
16753   [(set (match_operand:XF 0 "register_operand" "=f")
16754         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16755                    UNSPEC_SINCOS_COS))
16756    (set (match_operand:XF 1 "register_operand" "=u")
16757         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16758   "TARGET_USE_FANCY_MATH_387
16759    && flag_unsafe_math_optimizations"
16760   "fsincos"
16761   [(set_attr "type" "fpspc")
16762    (set_attr "mode" "XF")])
16763
16764 (define_split
16765   [(set (match_operand:XF 0 "register_operand" "")
16766         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16767                    UNSPEC_SINCOS_COS))
16768    (set (match_operand:XF 1 "register_operand" "")
16769         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16770   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16771    && !(reload_completed || reload_in_progress)"
16772   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16773   "")
16774
16775 (define_split
16776   [(set (match_operand:XF 0 "register_operand" "")
16777         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16778                    UNSPEC_SINCOS_COS))
16779    (set (match_operand:XF 1 "register_operand" "")
16780         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16781   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16782    && !(reload_completed || reload_in_progress)"
16783   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16784   "")
16785
16786 (define_insn "sincos_extend<mode>xf3_i387"
16787   [(set (match_operand:XF 0 "register_operand" "=f")
16788         (unspec:XF [(float_extend:XF
16789                       (match_operand:MODEF 2 "register_operand" "0"))]
16790                    UNSPEC_SINCOS_COS))
16791    (set (match_operand:XF 1 "register_operand" "=u")
16792         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16793   "TARGET_USE_FANCY_MATH_387
16794    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16795        || TARGET_MIX_SSE_I387)
16796    && flag_unsafe_math_optimizations"
16797   "fsincos"
16798   [(set_attr "type" "fpspc")
16799    (set_attr "mode" "XF")])
16800
16801 (define_split
16802   [(set (match_operand:XF 0 "register_operand" "")
16803         (unspec:XF [(float_extend:XF
16804                       (match_operand:MODEF 2 "register_operand" ""))]
16805                    UNSPEC_SINCOS_COS))
16806    (set (match_operand:XF 1 "register_operand" "")
16807         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16808   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16809    && !(reload_completed || reload_in_progress)"
16810   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16811   "")
16812
16813 (define_split
16814   [(set (match_operand:XF 0 "register_operand" "")
16815         (unspec:XF [(float_extend:XF
16816                       (match_operand:MODEF 2 "register_operand" ""))]
16817                    UNSPEC_SINCOS_COS))
16818    (set (match_operand:XF 1 "register_operand" "")
16819         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16820   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16821    && !(reload_completed || reload_in_progress)"
16822   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16823   "")
16824
16825 (define_expand "sincos<mode>3"
16826   [(use (match_operand:MODEF 0 "register_operand" ""))
16827    (use (match_operand:MODEF 1 "register_operand" ""))
16828    (use (match_operand:MODEF 2 "register_operand" ""))]
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 {
16834   rtx op0 = gen_reg_rtx (XFmode);
16835   rtx op1 = gen_reg_rtx (XFmode);
16836
16837   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16838   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16839   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16840   DONE;
16841 })
16842
16843 (define_insn "fptanxf4_i387"
16844   [(set (match_operand:XF 0 "register_operand" "=f")
16845         (match_operand:XF 3 "const_double_operand" "F"))
16846    (set (match_operand:XF 1 "register_operand" "=u")
16847         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16848                    UNSPEC_TAN))]
16849   "TARGET_USE_FANCY_MATH_387
16850    && flag_unsafe_math_optimizations
16851    && standard_80387_constant_p (operands[3]) == 2"
16852   "fptan"
16853   [(set_attr "type" "fpspc")
16854    (set_attr "mode" "XF")])
16855
16856 (define_insn "fptan_extend<mode>xf4_i387"
16857   [(set (match_operand:MODEF 0 "register_operand" "=f")
16858         (match_operand:MODEF 3 "const_double_operand" "F"))
16859    (set (match_operand:XF 1 "register_operand" "=u")
16860         (unspec:XF [(float_extend:XF
16861                       (match_operand:MODEF 2 "register_operand" "0"))]
16862                    UNSPEC_TAN))]
16863   "TARGET_USE_FANCY_MATH_387
16864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865        || TARGET_MIX_SSE_I387)
16866    && flag_unsafe_math_optimizations
16867    && standard_80387_constant_p (operands[3]) == 2"
16868   "fptan"
16869   [(set_attr "type" "fpspc")
16870    (set_attr "mode" "XF")])
16871
16872 (define_expand "tanxf2"
16873   [(use (match_operand:XF 0 "register_operand" ""))
16874    (use (match_operand:XF 1 "register_operand" ""))]
16875   "TARGET_USE_FANCY_MATH_387
16876    && flag_unsafe_math_optimizations"
16877 {
16878   rtx one = gen_reg_rtx (XFmode);
16879   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16880
16881   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16882   DONE;
16883 })
16884
16885 (define_expand "tan<mode>2"
16886   [(use (match_operand:MODEF 0 "register_operand" ""))
16887    (use (match_operand:MODEF 1 "register_operand" ""))]
16888   "TARGET_USE_FANCY_MATH_387
16889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890        || TARGET_MIX_SSE_I387)
16891    && flag_unsafe_math_optimizations"
16892 {
16893   rtx op0 = gen_reg_rtx (XFmode);
16894
16895   rtx one = gen_reg_rtx (<MODE>mode);
16896   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16897
16898   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16899                                              operands[1], op2));
16900   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16901   DONE;
16902 })
16903
16904 (define_insn "*fpatanxf3_i387"
16905   [(set (match_operand:XF 0 "register_operand" "=f")
16906         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16907                     (match_operand:XF 2 "register_operand" "u")]
16908                    UNSPEC_FPATAN))
16909    (clobber (match_scratch:XF 3 "=2"))]
16910   "TARGET_USE_FANCY_MATH_387
16911    && flag_unsafe_math_optimizations"
16912   "fpatan"
16913   [(set_attr "type" "fpspc")
16914    (set_attr "mode" "XF")])
16915
16916 (define_insn "fpatan_extend<mode>xf3_i387"
16917   [(set (match_operand:XF 0 "register_operand" "=f")
16918         (unspec:XF [(float_extend:XF
16919                       (match_operand:MODEF 1 "register_operand" "0"))
16920                     (float_extend:XF
16921                       (match_operand:MODEF 2 "register_operand" "u"))]
16922                    UNSPEC_FPATAN))
16923    (clobber (match_scratch:XF 3 "=2"))]
16924   "TARGET_USE_FANCY_MATH_387
16925    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926        || TARGET_MIX_SSE_I387)
16927    && flag_unsafe_math_optimizations"
16928   "fpatan"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_expand "atan2xf3"
16933   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16934                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16935                                (match_operand:XF 1 "register_operand" "")]
16936                               UNSPEC_FPATAN))
16937               (clobber (match_scratch:XF 3 ""))])]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16940   "")
16941
16942 (define_expand "atan2<mode>3"
16943   [(use (match_operand:MODEF 0 "register_operand" ""))
16944    (use (match_operand:MODEF 1 "register_operand" ""))
16945    (use (match_operand:MODEF 2 "register_operand" ""))]
16946   "TARGET_USE_FANCY_MATH_387
16947    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16948        || TARGET_MIX_SSE_I387)
16949    && flag_unsafe_math_optimizations"
16950 {
16951   rtx op0 = gen_reg_rtx (XFmode);
16952
16953   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16954   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16955   DONE;
16956 })
16957
16958 (define_expand "atanxf2"
16959   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16960                    (unspec:XF [(match_dup 2)
16961                                (match_operand:XF 1 "register_operand" "")]
16962                               UNSPEC_FPATAN))
16963               (clobber (match_scratch:XF 3 ""))])]
16964   "TARGET_USE_FANCY_MATH_387
16965    && flag_unsafe_math_optimizations"
16966 {
16967   operands[2] = gen_reg_rtx (XFmode);
16968   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16969 })
16970
16971 (define_expand "atan<mode>2"
16972   [(use (match_operand:MODEF 0 "register_operand" ""))
16973    (use (match_operand:MODEF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16976        || TARGET_MIX_SSE_I387)
16977    && flag_unsafe_math_optimizations"
16978 {
16979   rtx op0 = gen_reg_rtx (XFmode);
16980
16981   rtx op2 = gen_reg_rtx (<MODE>mode);
16982   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16983
16984   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16985   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16986   DONE;
16987 })
16988
16989 (define_expand "asinxf2"
16990   [(set (match_dup 2)
16991         (mult:XF (match_operand:XF 1 "register_operand" "")
16992                  (match_dup 1)))
16993    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16994    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16995    (parallel [(set (match_operand:XF 0 "register_operand" "")
16996                    (unspec:XF [(match_dup 5) (match_dup 1)]
16997                               UNSPEC_FPATAN))
16998               (clobber (match_scratch:XF 6 ""))])]
16999   "TARGET_USE_FANCY_MATH_387
17000    && flag_unsafe_math_optimizations && !optimize_size"
17001 {
17002   int i;
17003
17004   for (i = 2; i < 6; i++)
17005     operands[i] = gen_reg_rtx (XFmode);
17006
17007   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17008 })
17009
17010 (define_expand "asin<mode>2"
17011   [(use (match_operand:MODEF 0 "register_operand" ""))
17012    (use (match_operand:MODEF 1 "general_operand" ""))]
17013  "TARGET_USE_FANCY_MATH_387
17014    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17015        || TARGET_MIX_SSE_I387)
17016    && flag_unsafe_math_optimizations && !optimize_size"
17017 {
17018   rtx op0 = gen_reg_rtx (XFmode);
17019   rtx op1 = gen_reg_rtx (XFmode);
17020
17021   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17022   emit_insn (gen_asinxf2 (op0, op1));
17023   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17024   DONE;
17025 })
17026
17027 (define_expand "acosxf2"
17028   [(set (match_dup 2)
17029         (mult:XF (match_operand:XF 1 "register_operand" "")
17030                  (match_dup 1)))
17031    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17032    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17033    (parallel [(set (match_operand:XF 0 "register_operand" "")
17034                    (unspec:XF [(match_dup 1) (match_dup 5)]
17035                               UNSPEC_FPATAN))
17036               (clobber (match_scratch:XF 6 ""))])]
17037   "TARGET_USE_FANCY_MATH_387
17038    && flag_unsafe_math_optimizations && !optimize_size"
17039 {
17040   int i;
17041
17042   for (i = 2; i < 6; i++)
17043     operands[i] = gen_reg_rtx (XFmode);
17044
17045   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17046 })
17047
17048 (define_expand "acos<mode>2"
17049   [(use (match_operand:MODEF 0 "register_operand" ""))
17050    (use (match_operand:MODEF 1 "general_operand" ""))]
17051  "TARGET_USE_FANCY_MATH_387
17052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053        || TARGET_MIX_SSE_I387)
17054    && flag_unsafe_math_optimizations && !optimize_size"
17055 {
17056   rtx op0 = gen_reg_rtx (XFmode);
17057   rtx op1 = gen_reg_rtx (XFmode);
17058
17059   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17060   emit_insn (gen_acosxf2 (op0, op1));
17061   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17062   DONE;
17063 })
17064
17065 (define_insn "fyl2xxf3_i387"
17066   [(set (match_operand:XF 0 "register_operand" "=f")
17067         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17068                     (match_operand:XF 2 "register_operand" "u")]
17069                    UNSPEC_FYL2X))
17070    (clobber (match_scratch:XF 3 "=2"))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073   "fyl2x"
17074   [(set_attr "type" "fpspc")
17075    (set_attr "mode" "XF")])
17076
17077 (define_insn "fyl2x_extend<mode>xf3_i387"
17078   [(set (match_operand:XF 0 "register_operand" "=f")
17079         (unspec:XF [(float_extend:XF
17080                       (match_operand:MODEF 1 "register_operand" "0"))
17081                     (match_operand:XF 2 "register_operand" "u")]
17082                    UNSPEC_FYL2X))
17083    (clobber (match_scratch:XF 3 "=2"))]
17084   "TARGET_USE_FANCY_MATH_387
17085    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17086        || TARGET_MIX_SSE_I387)
17087    && flag_unsafe_math_optimizations"
17088   "fyl2x"
17089   [(set_attr "type" "fpspc")
17090    (set_attr "mode" "XF")])
17091
17092 (define_expand "logxf2"
17093   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17094                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17095                                (match_dup 2)] UNSPEC_FYL2X))
17096               (clobber (match_scratch:XF 3 ""))])]
17097   "TARGET_USE_FANCY_MATH_387
17098    && flag_unsafe_math_optimizations"
17099 {
17100   operands[2] = gen_reg_rtx (XFmode);
17101   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17102 })
17103
17104 (define_expand "log<mode>2"
17105   [(use (match_operand:MODEF 0 "register_operand" ""))
17106    (use (match_operand:MODEF 1 "register_operand" ""))]
17107   "TARGET_USE_FANCY_MATH_387
17108    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17109        || TARGET_MIX_SSE_I387)
17110    && flag_unsafe_math_optimizations"
17111 {
17112   rtx op0 = gen_reg_rtx (XFmode);
17113
17114   rtx op2 = gen_reg_rtx (XFmode);
17115   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17116
17117   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17119   DONE;
17120 })
17121
17122 (define_expand "log10xf2"
17123   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17124                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17125                                (match_dup 2)] UNSPEC_FYL2X))
17126               (clobber (match_scratch:XF 3 ""))])]
17127   "TARGET_USE_FANCY_MATH_387
17128    && flag_unsafe_math_optimizations"
17129 {
17130   operands[2] = gen_reg_rtx (XFmode);
17131   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17132 })
17133
17134 (define_expand "log10<mode>2"
17135   [(use (match_operand:MODEF 0 "register_operand" ""))
17136    (use (match_operand:MODEF 1 "register_operand" ""))]
17137   "TARGET_USE_FANCY_MATH_387
17138    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17139        || TARGET_MIX_SSE_I387)
17140    && flag_unsafe_math_optimizations"
17141 {
17142   rtx op0 = gen_reg_rtx (XFmode);
17143
17144   rtx op2 = gen_reg_rtx (XFmode);
17145   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17146
17147   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17148   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17149   DONE;
17150 })
17151
17152 (define_expand "log2xf2"
17153   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17154                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17155                                (match_dup 2)] UNSPEC_FYL2X))
17156               (clobber (match_scratch:XF 3 ""))])]
17157   "TARGET_USE_FANCY_MATH_387
17158    && flag_unsafe_math_optimizations"
17159 {
17160   operands[2] = gen_reg_rtx (XFmode);
17161   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17162 })
17163
17164 (define_expand "log2<mode>2"
17165   [(use (match_operand:MODEF 0 "register_operand" ""))
17166    (use (match_operand:MODEF 1 "register_operand" ""))]
17167   "TARGET_USE_FANCY_MATH_387
17168    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17169        || TARGET_MIX_SSE_I387)
17170    && flag_unsafe_math_optimizations"
17171 {
17172   rtx op0 = gen_reg_rtx (XFmode);
17173
17174   rtx op2 = gen_reg_rtx (XFmode);
17175   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17176
17177   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17178   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17179   DONE;
17180 })
17181
17182 (define_insn "fyl2xp1xf3_i387"
17183   [(set (match_operand:XF 0 "register_operand" "=f")
17184         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17185                     (match_operand:XF 2 "register_operand" "u")]
17186                    UNSPEC_FYL2XP1))
17187    (clobber (match_scratch:XF 3 "=2"))]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations"
17190   "fyl2xp1"
17191   [(set_attr "type" "fpspc")
17192    (set_attr "mode" "XF")])
17193
17194 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17195   [(set (match_operand:XF 0 "register_operand" "=f")
17196         (unspec:XF [(float_extend:XF
17197                       (match_operand:MODEF 1 "register_operand" "0"))
17198                     (match_operand:XF 2 "register_operand" "u")]
17199                    UNSPEC_FYL2XP1))
17200    (clobber (match_scratch:XF 3 "=2"))]
17201   "TARGET_USE_FANCY_MATH_387
17202    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203        || TARGET_MIX_SSE_I387)
17204    && flag_unsafe_math_optimizations"
17205   "fyl2xp1"
17206   [(set_attr "type" "fpspc")
17207    (set_attr "mode" "XF")])
17208
17209 (define_expand "log1pxf2"
17210   [(use (match_operand:XF 0 "register_operand" ""))
17211    (use (match_operand:XF 1 "register_operand" ""))]
17212   "TARGET_USE_FANCY_MATH_387
17213    && flag_unsafe_math_optimizations && !optimize_size"
17214 {
17215   ix86_emit_i387_log1p (operands[0], operands[1]);
17216   DONE;
17217 })
17218
17219 (define_expand "log1p<mode>2"
17220   [(use (match_operand:MODEF 0 "register_operand" ""))
17221    (use (match_operand:MODEF 1 "register_operand" ""))]
17222   "TARGET_USE_FANCY_MATH_387
17223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224        || TARGET_MIX_SSE_I387)
17225    && flag_unsafe_math_optimizations && !optimize_size"
17226 {
17227   rtx op0 = gen_reg_rtx (XFmode);
17228
17229   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17230
17231   ix86_emit_i387_log1p (op0, operands[1]);
17232   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17233   DONE;
17234 })
17235
17236 (define_insn "fxtractxf3_i387"
17237   [(set (match_operand:XF 0 "register_operand" "=f")
17238         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17239                    UNSPEC_XTRACT_FRACT))
17240    (set (match_operand:XF 1 "register_operand" "=u")
17241         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17242   "TARGET_USE_FANCY_MATH_387
17243    && flag_unsafe_math_optimizations"
17244   "fxtract"
17245   [(set_attr "type" "fpspc")
17246    (set_attr "mode" "XF")])
17247
17248 (define_insn "fxtract_extend<mode>xf3_i387"
17249   [(set (match_operand:XF 0 "register_operand" "=f")
17250         (unspec:XF [(float_extend:XF
17251                       (match_operand:MODEF 2 "register_operand" "0"))]
17252                    UNSPEC_XTRACT_FRACT))
17253    (set (match_operand:XF 1 "register_operand" "=u")
17254         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17255   "TARGET_USE_FANCY_MATH_387
17256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257        || TARGET_MIX_SSE_I387)
17258    && flag_unsafe_math_optimizations"
17259   "fxtract"
17260   [(set_attr "type" "fpspc")
17261    (set_attr "mode" "XF")])
17262
17263 (define_expand "logbxf2"
17264   [(parallel [(set (match_dup 2)
17265                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17266                               UNSPEC_XTRACT_FRACT))
17267               (set (match_operand:XF 0 "register_operand" "")
17268                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17269   "TARGET_USE_FANCY_MATH_387
17270    && flag_unsafe_math_optimizations"
17271 {
17272   operands[2] = gen_reg_rtx (XFmode);
17273 })
17274
17275 (define_expand "logb<mode>2"
17276   [(use (match_operand:MODEF 0 "register_operand" ""))
17277    (use (match_operand:MODEF 1 "register_operand" ""))]
17278   "TARGET_USE_FANCY_MATH_387
17279    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17280        || TARGET_MIX_SSE_I387)
17281    && flag_unsafe_math_optimizations"
17282 {
17283   rtx op0 = gen_reg_rtx (XFmode);
17284   rtx op1 = gen_reg_rtx (XFmode);
17285
17286   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17287   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17288   DONE;
17289 })
17290
17291 (define_expand "ilogbxf2"
17292   [(use (match_operand:SI 0 "register_operand" ""))
17293    (use (match_operand:XF 1 "register_operand" ""))]
17294   "TARGET_USE_FANCY_MATH_387
17295    && flag_unsafe_math_optimizations && !optimize_size"
17296 {
17297   rtx op0 = gen_reg_rtx (XFmode);
17298   rtx op1 = gen_reg_rtx (XFmode);
17299
17300   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17301   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17302   DONE;
17303 })
17304
17305 (define_expand "ilogb<mode>2"
17306   [(use (match_operand:SI 0 "register_operand" ""))
17307    (use (match_operand:MODEF 1 "register_operand" ""))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17310        || TARGET_MIX_SSE_I387)
17311    && flag_unsafe_math_optimizations && !optimize_size"
17312 {
17313   rtx op0 = gen_reg_rtx (XFmode);
17314   rtx op1 = gen_reg_rtx (XFmode);
17315
17316   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17317   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17318   DONE;
17319 })
17320
17321 (define_insn "*f2xm1xf2_i387"
17322   [(set (match_operand:XF 0 "register_operand" "=f")
17323         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17324                    UNSPEC_F2XM1))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && flag_unsafe_math_optimizations"
17327   "f2xm1"
17328   [(set_attr "type" "fpspc")
17329    (set_attr "mode" "XF")])
17330
17331 (define_insn "*fscalexf4_i387"
17332   [(set (match_operand:XF 0 "register_operand" "=f")
17333         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17334                     (match_operand:XF 3 "register_operand" "1")]
17335                    UNSPEC_FSCALE_FRACT))
17336    (set (match_operand:XF 1 "register_operand" "=u")
17337         (unspec:XF [(match_dup 2) (match_dup 3)]
17338                    UNSPEC_FSCALE_EXP))]
17339   "TARGET_USE_FANCY_MATH_387
17340    && flag_unsafe_math_optimizations"
17341   "fscale"
17342   [(set_attr "type" "fpspc")
17343    (set_attr "mode" "XF")])
17344
17345 (define_expand "expNcorexf3"
17346   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17347                                (match_operand:XF 2 "register_operand" "")))
17348    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17349    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17350    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17351    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17352    (parallel [(set (match_operand:XF 0 "register_operand" "")
17353                    (unspec:XF [(match_dup 8) (match_dup 4)]
17354                               UNSPEC_FSCALE_FRACT))
17355               (set (match_dup 9)
17356                    (unspec:XF [(match_dup 8) (match_dup 4)]
17357                               UNSPEC_FSCALE_EXP))])]
17358   "TARGET_USE_FANCY_MATH_387
17359    && flag_unsafe_math_optimizations && !optimize_size"
17360 {
17361   int i;
17362
17363   for (i = 3; i < 10; i++)
17364     operands[i] = gen_reg_rtx (XFmode);
17365
17366   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17367 })
17368
17369 (define_expand "expxf2"
17370   [(use (match_operand:XF 0 "register_operand" ""))
17371    (use (match_operand:XF 1 "register_operand" ""))]
17372   "TARGET_USE_FANCY_MATH_387
17373    && flag_unsafe_math_optimizations && !optimize_size"
17374 {
17375   rtx op2 = gen_reg_rtx (XFmode);
17376   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17377
17378   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17379   DONE;
17380 })
17381
17382 (define_expand "exp<mode>2"
17383   [(use (match_operand:MODEF 0 "register_operand" ""))
17384    (use (match_operand:MODEF 1 "general_operand" ""))]
17385  "TARGET_USE_FANCY_MATH_387
17386    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17387        || TARGET_MIX_SSE_I387)
17388    && flag_unsafe_math_optimizations && !optimize_size"
17389 {
17390   rtx op0 = gen_reg_rtx (XFmode);
17391   rtx op1 = gen_reg_rtx (XFmode);
17392
17393   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17394   emit_insn (gen_expxf2 (op0, op1));
17395   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17396   DONE;
17397 })
17398
17399 (define_expand "exp10xf2"
17400   [(use (match_operand:XF 0 "register_operand" ""))
17401    (use (match_operand:XF 1 "register_operand" ""))]
17402   "TARGET_USE_FANCY_MATH_387
17403    && flag_unsafe_math_optimizations && !optimize_size"
17404 {
17405   rtx op2 = gen_reg_rtx (XFmode);
17406   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17407
17408   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17409   DONE;
17410 })
17411
17412 (define_expand "exp10<mode>2"
17413   [(use (match_operand:MODEF 0 "register_operand" ""))
17414    (use (match_operand:MODEF 1 "general_operand" ""))]
17415  "TARGET_USE_FANCY_MATH_387
17416    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17417        || TARGET_MIX_SSE_I387)
17418    && flag_unsafe_math_optimizations && !optimize_size"
17419 {
17420   rtx op0 = gen_reg_rtx (XFmode);
17421   rtx op1 = gen_reg_rtx (XFmode);
17422
17423   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17424   emit_insn (gen_exp10xf2 (op0, op1));
17425   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17426   DONE;
17427 })
17428
17429 (define_expand "exp2xf2"
17430   [(use (match_operand:XF 0 "register_operand" ""))
17431    (use (match_operand:XF 1 "register_operand" ""))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && flag_unsafe_math_optimizations && !optimize_size"
17434 {
17435   rtx op2 = gen_reg_rtx (XFmode);
17436   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17437
17438   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17439   DONE;
17440 })
17441
17442 (define_expand "exp2<mode>2"
17443   [(use (match_operand:MODEF 0 "register_operand" ""))
17444    (use (match_operand:MODEF 1 "general_operand" ""))]
17445  "TARGET_USE_FANCY_MATH_387
17446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17447        || TARGET_MIX_SSE_I387)
17448    && flag_unsafe_math_optimizations && !optimize_size"
17449 {
17450   rtx op0 = gen_reg_rtx (XFmode);
17451   rtx op1 = gen_reg_rtx (XFmode);
17452
17453   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17454   emit_insn (gen_exp2xf2 (op0, op1));
17455   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17456   DONE;
17457 })
17458
17459 (define_expand "expm1xf2"
17460   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17461                                (match_dup 2)))
17462    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17463    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17464    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17465    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17466    (parallel [(set (match_dup 7)
17467                    (unspec:XF [(match_dup 6) (match_dup 4)]
17468                               UNSPEC_FSCALE_FRACT))
17469               (set (match_dup 8)
17470                    (unspec:XF [(match_dup 6) (match_dup 4)]
17471                               UNSPEC_FSCALE_EXP))])
17472    (parallel [(set (match_dup 10)
17473                    (unspec:XF [(match_dup 9) (match_dup 8)]
17474                               UNSPEC_FSCALE_FRACT))
17475               (set (match_dup 11)
17476                    (unspec:XF [(match_dup 9) (match_dup 8)]
17477                               UNSPEC_FSCALE_EXP))])
17478    (set (match_dup 12) (minus:XF (match_dup 10)
17479                                  (float_extend:XF (match_dup 13))))
17480    (set (match_operand:XF 0 "register_operand" "")
17481         (plus:XF (match_dup 12) (match_dup 7)))]
17482   "TARGET_USE_FANCY_MATH_387
17483    && flag_unsafe_math_optimizations && !optimize_size"
17484 {
17485   int i;
17486
17487   for (i = 2; i < 13; i++)
17488     operands[i] = gen_reg_rtx (XFmode);
17489
17490   operands[13]
17491     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17492
17493   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17494 })
17495
17496 (define_expand "expm1<mode>2"
17497   [(use (match_operand:MODEF 0 "register_operand" ""))
17498    (use (match_operand:MODEF 1 "general_operand" ""))]
17499  "TARGET_USE_FANCY_MATH_387
17500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501        || TARGET_MIX_SSE_I387)
17502    && flag_unsafe_math_optimizations && !optimize_size"
17503 {
17504   rtx op0 = gen_reg_rtx (XFmode);
17505   rtx op1 = gen_reg_rtx (XFmode);
17506
17507   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17508   emit_insn (gen_expm1xf2 (op0, op1));
17509   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17510   DONE;
17511 })
17512
17513 (define_expand "ldexpxf3"
17514   [(set (match_dup 3)
17515         (float:XF (match_operand:SI 2 "register_operand" "")))
17516    (parallel [(set (match_operand:XF 0 " register_operand" "")
17517                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17518                                (match_dup 3)]
17519                               UNSPEC_FSCALE_FRACT))
17520               (set (match_dup 4)
17521                    (unspec:XF [(match_dup 1) (match_dup 3)]
17522                               UNSPEC_FSCALE_EXP))])]
17523   "TARGET_USE_FANCY_MATH_387
17524    && flag_unsafe_math_optimizations && !optimize_size"
17525 {
17526   operands[3] = gen_reg_rtx (XFmode);
17527   operands[4] = gen_reg_rtx (XFmode);
17528 })
17529
17530 (define_expand "ldexp<mode>3"
17531   [(use (match_operand:MODEF 0 "register_operand" ""))
17532    (use (match_operand:MODEF 1 "general_operand" ""))
17533    (use (match_operand:SI 2 "register_operand" ""))]
17534  "TARGET_USE_FANCY_MATH_387
17535    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17536        || TARGET_MIX_SSE_I387)
17537    && flag_unsafe_math_optimizations && !optimize_size"
17538 {
17539   rtx op0 = gen_reg_rtx (XFmode);
17540   rtx op1 = gen_reg_rtx (XFmode);
17541
17542   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17543   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17544   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17545   DONE;
17546 })
17547
17548 (define_expand "scalbxf3"
17549   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17550                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17551                                (match_operand:XF 2 "register_operand" "")]
17552                               UNSPEC_FSCALE_FRACT))
17553               (set (match_dup 3)
17554                    (unspec:XF [(match_dup 1) (match_dup 2)]
17555                               UNSPEC_FSCALE_EXP))])]
17556   "TARGET_USE_FANCY_MATH_387
17557    && flag_unsafe_math_optimizations && !optimize_size"
17558 {
17559   operands[3] = gen_reg_rtx (XFmode);
17560 })
17561
17562 (define_expand "scalb<mode>3"
17563   [(use (match_operand:MODEF 0 "register_operand" ""))
17564    (use (match_operand:MODEF 1 "general_operand" ""))
17565    (use (match_operand:MODEF 2 "register_operand" ""))]
17566  "TARGET_USE_FANCY_MATH_387
17567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17568        || TARGET_MIX_SSE_I387)
17569    && flag_unsafe_math_optimizations && !optimize_size"
17570 {
17571   rtx op0 = gen_reg_rtx (XFmode);
17572   rtx op1 = gen_reg_rtx (XFmode);
17573   rtx op2 = gen_reg_rtx (XFmode);
17574
17575   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17576   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17577   emit_insn (gen_scalbxf3 (op0, op1, op2));
17578   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17579   DONE;
17580 })
17581 \f
17582
17583 (define_insn "sse4_1_round<mode>2"
17584   [(set (match_operand:MODEF 0 "register_operand" "=x")
17585         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17586                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17587                       UNSPEC_ROUND))]
17588   "TARGET_ROUND"
17589   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17590   [(set_attr "type" "ssecvt")
17591    (set_attr "prefix_extra" "1")
17592    (set_attr "mode" "<MODE>")])
17593
17594 (define_insn "rintxf2"
17595   [(set (match_operand:XF 0 "register_operand" "=f")
17596         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17597                    UNSPEC_FRNDINT))]
17598   "TARGET_USE_FANCY_MATH_387
17599    && flag_unsafe_math_optimizations"
17600   "frndint"
17601   [(set_attr "type" "fpspc")
17602    (set_attr "mode" "XF")])
17603
17604 (define_expand "rint<mode>2"
17605   [(use (match_operand:MODEF 0 "register_operand" ""))
17606    (use (match_operand:MODEF 1 "register_operand" ""))]
17607   "(TARGET_USE_FANCY_MATH_387
17608     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17609         || TARGET_MIX_SSE_I387)
17610     && flag_unsafe_math_optimizations)
17611    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17612        && !flag_trapping_math
17613        && (TARGET_ROUND || !optimize_size))"
17614 {
17615   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17616       && !flag_trapping_math
17617       && (TARGET_ROUND || !optimize_size))
17618     {
17619       if (TARGET_ROUND)
17620         emit_insn (gen_sse4_1_round<mode>2
17621                    (operands[0], operands[1], GEN_INT (0x04)));
17622       else
17623         ix86_expand_rint (operand0, operand1);
17624     }
17625   else
17626     {
17627       rtx op0 = gen_reg_rtx (XFmode);
17628       rtx op1 = gen_reg_rtx (XFmode);
17629
17630       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17631       emit_insn (gen_rintxf2 (op0, op1));
17632
17633       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17634     }
17635   DONE;
17636 })
17637
17638 (define_expand "round<mode>2"
17639   [(match_operand:MODEF 0 "register_operand" "")
17640    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17641   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17642    && !flag_trapping_math && !flag_rounding_math
17643    && !optimize_size"
17644 {
17645   if (TARGET_64BIT || (<MODE>mode != DFmode))
17646     ix86_expand_round (operand0, operand1);
17647   else
17648     ix86_expand_rounddf_32 (operand0, operand1);
17649   DONE;
17650 })
17651
17652 (define_insn_and_split "*fistdi2_1"
17653   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17654         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17655                    UNSPEC_FIST))]
17656   "TARGET_USE_FANCY_MATH_387
17657    && !(reload_completed || reload_in_progress)"
17658   "#"
17659   "&& 1"
17660   [(const_int 0)]
17661 {
17662   if (memory_operand (operands[0], VOIDmode))
17663     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17664   else
17665     {
17666       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17667       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17668                                          operands[2]));
17669     }
17670   DONE;
17671 }
17672   [(set_attr "type" "fpspc")
17673    (set_attr "mode" "DI")])
17674
17675 (define_insn "fistdi2"
17676   [(set (match_operand:DI 0 "memory_operand" "=m")
17677         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17678                    UNSPEC_FIST))
17679    (clobber (match_scratch:XF 2 "=&1f"))]
17680   "TARGET_USE_FANCY_MATH_387"
17681   "* return output_fix_trunc (insn, operands, 0);"
17682   [(set_attr "type" "fpspc")
17683    (set_attr "mode" "DI")])
17684
17685 (define_insn "fistdi2_with_temp"
17686   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17687         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17688                    UNSPEC_FIST))
17689    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17690    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17691   "TARGET_USE_FANCY_MATH_387"
17692   "#"
17693   [(set_attr "type" "fpspc")
17694    (set_attr "mode" "DI")])
17695
17696 (define_split
17697   [(set (match_operand:DI 0 "register_operand" "")
17698         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17699                    UNSPEC_FIST))
17700    (clobber (match_operand:DI 2 "memory_operand" ""))
17701    (clobber (match_scratch 3 ""))]
17702   "reload_completed"
17703   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17704               (clobber (match_dup 3))])
17705    (set (match_dup 0) (match_dup 2))]
17706   "")
17707
17708 (define_split
17709   [(set (match_operand:DI 0 "memory_operand" "")
17710         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17711                    UNSPEC_FIST))
17712    (clobber (match_operand:DI 2 "memory_operand" ""))
17713    (clobber (match_scratch 3 ""))]
17714   "reload_completed"
17715   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17716               (clobber (match_dup 3))])]
17717   "")
17718
17719 (define_insn_and_split "*fist<mode>2_1"
17720   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17721         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17722                            UNSPEC_FIST))]
17723   "TARGET_USE_FANCY_MATH_387
17724    && !(reload_completed || reload_in_progress)"
17725   "#"
17726   "&& 1"
17727   [(const_int 0)]
17728 {
17729   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17730   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17731                                         operands[2]));
17732   DONE;
17733 }
17734   [(set_attr "type" "fpspc")
17735    (set_attr "mode" "<MODE>")])
17736
17737 (define_insn "fist<mode>2"
17738   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17739         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17740                            UNSPEC_FIST))]
17741   "TARGET_USE_FANCY_MATH_387"
17742   "* return output_fix_trunc (insn, operands, 0);"
17743   [(set_attr "type" "fpspc")
17744    (set_attr "mode" "<MODE>")])
17745
17746 (define_insn "fist<mode>2_with_temp"
17747   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17748         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17749                            UNSPEC_FIST))
17750    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17751   "TARGET_USE_FANCY_MATH_387"
17752   "#"
17753   [(set_attr "type" "fpspc")
17754    (set_attr "mode" "<MODE>")])
17755
17756 (define_split
17757   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17758         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17759                            UNSPEC_FIST))
17760    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17761   "reload_completed"
17762   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17763    (set (match_dup 0) (match_dup 2))]
17764   "")
17765
17766 (define_split
17767   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17768         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17769                            UNSPEC_FIST))
17770    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17771   "reload_completed"
17772   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17773   "")
17774
17775 (define_expand "lrintxf<mode>2"
17776   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17777      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17778                       UNSPEC_FIST))]
17779   "TARGET_USE_FANCY_MATH_387"
17780   "")
17781
17782 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17783   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17784      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17785                         UNSPEC_FIX_NOTRUNC))]
17786   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17787    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17788   "")
17789
17790 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17791   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17792    (match_operand:MODEF 1 "register_operand" "")]
17793   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17794    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17795    && !flag_trapping_math && !flag_rounding_math
17796    && !optimize_size"
17797 {
17798   ix86_expand_lround (operand0, operand1);
17799   DONE;
17800 })
17801
17802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17803 (define_insn_and_split "frndintxf2_floor"
17804   [(set (match_operand:XF 0 "register_operand" "")
17805         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17806          UNSPEC_FRNDINT_FLOOR))
17807    (clobber (reg:CC FLAGS_REG))]
17808   "TARGET_USE_FANCY_MATH_387
17809    && flag_unsafe_math_optimizations
17810    && !(reload_completed || reload_in_progress)"
17811   "#"
17812   "&& 1"
17813   [(const_int 0)]
17814 {
17815   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17816
17817   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17818   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17819
17820   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17821                                         operands[2], operands[3]));
17822   DONE;
17823 }
17824   [(set_attr "type" "frndint")
17825    (set_attr "i387_cw" "floor")
17826    (set_attr "mode" "XF")])
17827
17828 (define_insn "frndintxf2_floor_i387"
17829   [(set (match_operand:XF 0 "register_operand" "=f")
17830         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17831          UNSPEC_FRNDINT_FLOOR))
17832    (use (match_operand:HI 2 "memory_operand" "m"))
17833    (use (match_operand:HI 3 "memory_operand" "m"))]
17834   "TARGET_USE_FANCY_MATH_387
17835    && flag_unsafe_math_optimizations"
17836   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17837   [(set_attr "type" "frndint")
17838    (set_attr "i387_cw" "floor")
17839    (set_attr "mode" "XF")])
17840
17841 (define_expand "floorxf2"
17842   [(use (match_operand:XF 0 "register_operand" ""))
17843    (use (match_operand:XF 1 "register_operand" ""))]
17844   "TARGET_USE_FANCY_MATH_387
17845    && flag_unsafe_math_optimizations && !optimize_size"
17846 {
17847   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17848   DONE;
17849 })
17850
17851 (define_expand "floor<mode>2"
17852   [(use (match_operand:MODEF 0 "register_operand" ""))
17853    (use (match_operand:MODEF 1 "register_operand" ""))]
17854   "(TARGET_USE_FANCY_MATH_387
17855     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17856         || TARGET_MIX_SSE_I387)
17857     && flag_unsafe_math_optimizations && !optimize_size)
17858    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17859        && !flag_trapping_math
17860        && (TARGET_ROUND || !optimize_size))"
17861 {
17862   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17863       && !flag_trapping_math
17864       && (TARGET_ROUND || !optimize_size))
17865     {
17866       if (TARGET_ROUND)
17867         emit_insn (gen_sse4_1_round<mode>2
17868                    (operands[0], operands[1], GEN_INT (0x01)));
17869       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17870         ix86_expand_floorceil (operand0, operand1, true);
17871       else
17872         ix86_expand_floorceildf_32 (operand0, operand1, true);
17873     }
17874   else
17875     {
17876       rtx op0 = gen_reg_rtx (XFmode);
17877       rtx op1 = gen_reg_rtx (XFmode);
17878
17879       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17880       emit_insn (gen_frndintxf2_floor (op0, op1));
17881
17882       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17883     }
17884   DONE;
17885 })
17886
17887 (define_insn_and_split "*fist<mode>2_floor_1"
17888   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17889         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17890          UNSPEC_FIST_FLOOR))
17891    (clobber (reg:CC FLAGS_REG))]
17892   "TARGET_USE_FANCY_MATH_387
17893    && flag_unsafe_math_optimizations
17894    && !(reload_completed || reload_in_progress)"
17895   "#"
17896   "&& 1"
17897   [(const_int 0)]
17898 {
17899   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17900
17901   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17902   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17903   if (memory_operand (operands[0], VOIDmode))
17904     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17905                                       operands[2], operands[3]));
17906   else
17907     {
17908       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17909       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17910                                                   operands[2], operands[3],
17911                                                   operands[4]));
17912     }
17913   DONE;
17914 }
17915   [(set_attr "type" "fistp")
17916    (set_attr "i387_cw" "floor")
17917    (set_attr "mode" "<MODE>")])
17918
17919 (define_insn "fistdi2_floor"
17920   [(set (match_operand:DI 0 "memory_operand" "=m")
17921         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17922          UNSPEC_FIST_FLOOR))
17923    (use (match_operand:HI 2 "memory_operand" "m"))
17924    (use (match_operand:HI 3 "memory_operand" "m"))
17925    (clobber (match_scratch:XF 4 "=&1f"))]
17926   "TARGET_USE_FANCY_MATH_387
17927    && flag_unsafe_math_optimizations"
17928   "* return output_fix_trunc (insn, operands, 0);"
17929   [(set_attr "type" "fistp")
17930    (set_attr "i387_cw" "floor")
17931    (set_attr "mode" "DI")])
17932
17933 (define_insn "fistdi2_floor_with_temp"
17934   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17935         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17936          UNSPEC_FIST_FLOOR))
17937    (use (match_operand:HI 2 "memory_operand" "m,m"))
17938    (use (match_operand:HI 3 "memory_operand" "m,m"))
17939    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17940    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && flag_unsafe_math_optimizations"
17943   "#"
17944   [(set_attr "type" "fistp")
17945    (set_attr "i387_cw" "floor")
17946    (set_attr "mode" "DI")])
17947
17948 (define_split
17949   [(set (match_operand:DI 0 "register_operand" "")
17950         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17951          UNSPEC_FIST_FLOOR))
17952    (use (match_operand:HI 2 "memory_operand" ""))
17953    (use (match_operand:HI 3 "memory_operand" ""))
17954    (clobber (match_operand:DI 4 "memory_operand" ""))
17955    (clobber (match_scratch 5 ""))]
17956   "reload_completed"
17957   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17958               (use (match_dup 2))
17959               (use (match_dup 3))
17960               (clobber (match_dup 5))])
17961    (set (match_dup 0) (match_dup 4))]
17962   "")
17963
17964 (define_split
17965   [(set (match_operand:DI 0 "memory_operand" "")
17966         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17967          UNSPEC_FIST_FLOOR))
17968    (use (match_operand:HI 2 "memory_operand" ""))
17969    (use (match_operand:HI 3 "memory_operand" ""))
17970    (clobber (match_operand:DI 4 "memory_operand" ""))
17971    (clobber (match_scratch 5 ""))]
17972   "reload_completed"
17973   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17974               (use (match_dup 2))
17975               (use (match_dup 3))
17976               (clobber (match_dup 5))])]
17977   "")
17978
17979 (define_insn "fist<mode>2_floor"
17980   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17981         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17982          UNSPEC_FIST_FLOOR))
17983    (use (match_operand:HI 2 "memory_operand" "m"))
17984    (use (match_operand:HI 3 "memory_operand" "m"))]
17985   "TARGET_USE_FANCY_MATH_387
17986    && flag_unsafe_math_optimizations"
17987   "* return output_fix_trunc (insn, operands, 0);"
17988   [(set_attr "type" "fistp")
17989    (set_attr "i387_cw" "floor")
17990    (set_attr "mode" "<MODE>")])
17991
17992 (define_insn "fist<mode>2_floor_with_temp"
17993   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17994         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17995          UNSPEC_FIST_FLOOR))
17996    (use (match_operand:HI 2 "memory_operand" "m,m"))
17997    (use (match_operand:HI 3 "memory_operand" "m,m"))
17998    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17999   "TARGET_USE_FANCY_MATH_387
18000    && flag_unsafe_math_optimizations"
18001   "#"
18002   [(set_attr "type" "fistp")
18003    (set_attr "i387_cw" "floor")
18004    (set_attr "mode" "<MODE>")])
18005
18006 (define_split
18007   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18008         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18009          UNSPEC_FIST_FLOOR))
18010    (use (match_operand:HI 2 "memory_operand" ""))
18011    (use (match_operand:HI 3 "memory_operand" ""))
18012    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18013   "reload_completed"
18014   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18015                                   UNSPEC_FIST_FLOOR))
18016               (use (match_dup 2))
18017               (use (match_dup 3))])
18018    (set (match_dup 0) (match_dup 4))]
18019   "")
18020
18021 (define_split
18022   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18023         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18024          UNSPEC_FIST_FLOOR))
18025    (use (match_operand:HI 2 "memory_operand" ""))
18026    (use (match_operand:HI 3 "memory_operand" ""))
18027    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18028   "reload_completed"
18029   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18030                                   UNSPEC_FIST_FLOOR))
18031               (use (match_dup 2))
18032               (use (match_dup 3))])]
18033   "")
18034
18035 (define_expand "lfloorxf<mode>2"
18036   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18037                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18038                     UNSPEC_FIST_FLOOR))
18039               (clobber (reg:CC FLAGS_REG))])]
18040   "TARGET_USE_FANCY_MATH_387
18041    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18042    && flag_unsafe_math_optimizations"
18043   "")
18044
18045 (define_expand "lfloor<mode>di2"
18046   [(match_operand:DI 0 "nonimmediate_operand" "")
18047    (match_operand:MODEF 1 "register_operand" "")]
18048   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18049    && !flag_trapping_math
18050    && !optimize_size"
18051 {
18052   ix86_expand_lfloorceil (operand0, operand1, true);
18053   DONE;
18054 })
18055
18056 (define_expand "lfloor<mode>si2"
18057   [(match_operand:SI 0 "nonimmediate_operand" "")
18058    (match_operand:MODEF 1 "register_operand" "")]
18059   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18060    && !flag_trapping_math
18061    && (!optimize_size || !TARGET_64BIT)"
18062 {
18063   ix86_expand_lfloorceil (operand0, operand1, true);
18064   DONE;
18065 })
18066
18067 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18068 (define_insn_and_split "frndintxf2_ceil"
18069   [(set (match_operand:XF 0 "register_operand" "")
18070         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18071          UNSPEC_FRNDINT_CEIL))
18072    (clobber (reg:CC FLAGS_REG))]
18073   "TARGET_USE_FANCY_MATH_387
18074    && flag_unsafe_math_optimizations
18075    && !(reload_completed || reload_in_progress)"
18076   "#"
18077   "&& 1"
18078   [(const_int 0)]
18079 {
18080   ix86_optimize_mode_switching[I387_CEIL] = 1;
18081
18082   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18083   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18084
18085   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18086                                        operands[2], operands[3]));
18087   DONE;
18088 }
18089   [(set_attr "type" "frndint")
18090    (set_attr "i387_cw" "ceil")
18091    (set_attr "mode" "XF")])
18092
18093 (define_insn "frndintxf2_ceil_i387"
18094   [(set (match_operand:XF 0 "register_operand" "=f")
18095         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18096          UNSPEC_FRNDINT_CEIL))
18097    (use (match_operand:HI 2 "memory_operand" "m"))
18098    (use (match_operand:HI 3 "memory_operand" "m"))]
18099   "TARGET_USE_FANCY_MATH_387
18100    && flag_unsafe_math_optimizations"
18101   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18102   [(set_attr "type" "frndint")
18103    (set_attr "i387_cw" "ceil")
18104    (set_attr "mode" "XF")])
18105
18106 (define_expand "ceilxf2"
18107   [(use (match_operand:XF 0 "register_operand" ""))
18108    (use (match_operand:XF 1 "register_operand" ""))]
18109   "TARGET_USE_FANCY_MATH_387
18110    && flag_unsafe_math_optimizations && !optimize_size"
18111 {
18112   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18113   DONE;
18114 })
18115
18116 (define_expand "ceil<mode>2"
18117   [(use (match_operand:MODEF 0 "register_operand" ""))
18118    (use (match_operand:MODEF 1 "register_operand" ""))]
18119   "(TARGET_USE_FANCY_MATH_387
18120     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18121         || TARGET_MIX_SSE_I387)
18122     && flag_unsafe_math_optimizations && !optimize_size)
18123    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18124        && !flag_trapping_math
18125        && (TARGET_ROUND || !optimize_size))"
18126 {
18127   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18128       && !flag_trapping_math
18129       && (TARGET_ROUND || !optimize_size))
18130     {
18131       if (TARGET_ROUND)
18132         emit_insn (gen_sse4_1_round<mode>2
18133                    (operands[0], operands[1], GEN_INT (0x02)));
18134       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18135         ix86_expand_floorceil (operand0, operand1, false);
18136       else
18137         ix86_expand_floorceildf_32 (operand0, operand1, false);
18138     }
18139   else
18140     {
18141       rtx op0 = gen_reg_rtx (XFmode);
18142       rtx op1 = gen_reg_rtx (XFmode);
18143
18144       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18145       emit_insn (gen_frndintxf2_ceil (op0, op1));
18146
18147       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18148     }
18149   DONE;
18150 })
18151
18152 (define_insn_and_split "*fist<mode>2_ceil_1"
18153   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18154         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18155          UNSPEC_FIST_CEIL))
18156    (clobber (reg:CC FLAGS_REG))]
18157   "TARGET_USE_FANCY_MATH_387
18158    && flag_unsafe_math_optimizations
18159    && !(reload_completed || reload_in_progress)"
18160   "#"
18161   "&& 1"
18162   [(const_int 0)]
18163 {
18164   ix86_optimize_mode_switching[I387_CEIL] = 1;
18165
18166   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18167   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18168   if (memory_operand (operands[0], VOIDmode))
18169     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18170                                      operands[2], operands[3]));
18171   else
18172     {
18173       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18174       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18175                                                  operands[2], operands[3],
18176                                                  operands[4]));
18177     }
18178   DONE;
18179 }
18180   [(set_attr "type" "fistp")
18181    (set_attr "i387_cw" "ceil")
18182    (set_attr "mode" "<MODE>")])
18183
18184 (define_insn "fistdi2_ceil"
18185   [(set (match_operand:DI 0 "memory_operand" "=m")
18186         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18187          UNSPEC_FIST_CEIL))
18188    (use (match_operand:HI 2 "memory_operand" "m"))
18189    (use (match_operand:HI 3 "memory_operand" "m"))
18190    (clobber (match_scratch:XF 4 "=&1f"))]
18191   "TARGET_USE_FANCY_MATH_387
18192    && flag_unsafe_math_optimizations"
18193   "* return output_fix_trunc (insn, operands, 0);"
18194   [(set_attr "type" "fistp")
18195    (set_attr "i387_cw" "ceil")
18196    (set_attr "mode" "DI")])
18197
18198 (define_insn "fistdi2_ceil_with_temp"
18199   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18200         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18201          UNSPEC_FIST_CEIL))
18202    (use (match_operand:HI 2 "memory_operand" "m,m"))
18203    (use (match_operand:HI 3 "memory_operand" "m,m"))
18204    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18205    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18206   "TARGET_USE_FANCY_MATH_387
18207    && flag_unsafe_math_optimizations"
18208   "#"
18209   [(set_attr "type" "fistp")
18210    (set_attr "i387_cw" "ceil")
18211    (set_attr "mode" "DI")])
18212
18213 (define_split
18214   [(set (match_operand:DI 0 "register_operand" "")
18215         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18216          UNSPEC_FIST_CEIL))
18217    (use (match_operand:HI 2 "memory_operand" ""))
18218    (use (match_operand:HI 3 "memory_operand" ""))
18219    (clobber (match_operand:DI 4 "memory_operand" ""))
18220    (clobber (match_scratch 5 ""))]
18221   "reload_completed"
18222   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18223               (use (match_dup 2))
18224               (use (match_dup 3))
18225               (clobber (match_dup 5))])
18226    (set (match_dup 0) (match_dup 4))]
18227   "")
18228
18229 (define_split
18230   [(set (match_operand:DI 0 "memory_operand" "")
18231         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18232          UNSPEC_FIST_CEIL))
18233    (use (match_operand:HI 2 "memory_operand" ""))
18234    (use (match_operand:HI 3 "memory_operand" ""))
18235    (clobber (match_operand:DI 4 "memory_operand" ""))
18236    (clobber (match_scratch 5 ""))]
18237   "reload_completed"
18238   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18239               (use (match_dup 2))
18240               (use (match_dup 3))
18241               (clobber (match_dup 5))])]
18242   "")
18243
18244 (define_insn "fist<mode>2_ceil"
18245   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18246         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18247          UNSPEC_FIST_CEIL))
18248    (use (match_operand:HI 2 "memory_operand" "m"))
18249    (use (match_operand:HI 3 "memory_operand" "m"))]
18250   "TARGET_USE_FANCY_MATH_387
18251    && flag_unsafe_math_optimizations"
18252   "* return output_fix_trunc (insn, operands, 0);"
18253   [(set_attr "type" "fistp")
18254    (set_attr "i387_cw" "ceil")
18255    (set_attr "mode" "<MODE>")])
18256
18257 (define_insn "fist<mode>2_ceil_with_temp"
18258   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18259         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18260          UNSPEC_FIST_CEIL))
18261    (use (match_operand:HI 2 "memory_operand" "m,m"))
18262    (use (match_operand:HI 3 "memory_operand" "m,m"))
18263    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18264   "TARGET_USE_FANCY_MATH_387
18265    && flag_unsafe_math_optimizations"
18266   "#"
18267   [(set_attr "type" "fistp")
18268    (set_attr "i387_cw" "ceil")
18269    (set_attr "mode" "<MODE>")])
18270
18271 (define_split
18272   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18273         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18274          UNSPEC_FIST_CEIL))
18275    (use (match_operand:HI 2 "memory_operand" ""))
18276    (use (match_operand:HI 3 "memory_operand" ""))
18277    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18278   "reload_completed"
18279   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18280                                   UNSPEC_FIST_CEIL))
18281               (use (match_dup 2))
18282               (use (match_dup 3))])
18283    (set (match_dup 0) (match_dup 4))]
18284   "")
18285
18286 (define_split
18287   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18288         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18289          UNSPEC_FIST_CEIL))
18290    (use (match_operand:HI 2 "memory_operand" ""))
18291    (use (match_operand:HI 3 "memory_operand" ""))
18292    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18293   "reload_completed"
18294   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18295                                   UNSPEC_FIST_CEIL))
18296               (use (match_dup 2))
18297               (use (match_dup 3))])]
18298   "")
18299
18300 (define_expand "lceilxf<mode>2"
18301   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18302                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18303                     UNSPEC_FIST_CEIL))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   "TARGET_USE_FANCY_MATH_387
18306    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18307    && flag_unsafe_math_optimizations"
18308   "")
18309
18310 (define_expand "lceil<mode>di2"
18311   [(match_operand:DI 0 "nonimmediate_operand" "")
18312    (match_operand:MODEF 1 "register_operand" "")]
18313   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18314    && !flag_trapping_math"
18315 {
18316   ix86_expand_lfloorceil (operand0, operand1, false);
18317   DONE;
18318 })
18319
18320 (define_expand "lceil<mode>si2"
18321   [(match_operand:SI 0 "nonimmediate_operand" "")
18322    (match_operand:MODEF 1 "register_operand" "")]
18323   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18324    && !flag_trapping_math"
18325 {
18326   ix86_expand_lfloorceil (operand0, operand1, false);
18327   DONE;
18328 })
18329
18330 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18331 (define_insn_and_split "frndintxf2_trunc"
18332   [(set (match_operand:XF 0 "register_operand" "")
18333         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18334          UNSPEC_FRNDINT_TRUNC))
18335    (clobber (reg:CC FLAGS_REG))]
18336   "TARGET_USE_FANCY_MATH_387
18337    && flag_unsafe_math_optimizations
18338    && !(reload_completed || reload_in_progress)"
18339   "#"
18340   "&& 1"
18341   [(const_int 0)]
18342 {
18343   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18344
18345   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18346   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18347
18348   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18349                                         operands[2], operands[3]));
18350   DONE;
18351 }
18352   [(set_attr "type" "frndint")
18353    (set_attr "i387_cw" "trunc")
18354    (set_attr "mode" "XF")])
18355
18356 (define_insn "frndintxf2_trunc_i387"
18357   [(set (match_operand:XF 0 "register_operand" "=f")
18358         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18359          UNSPEC_FRNDINT_TRUNC))
18360    (use (match_operand:HI 2 "memory_operand" "m"))
18361    (use (match_operand:HI 3 "memory_operand" "m"))]
18362   "TARGET_USE_FANCY_MATH_387
18363    && flag_unsafe_math_optimizations"
18364   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18365   [(set_attr "type" "frndint")
18366    (set_attr "i387_cw" "trunc")
18367    (set_attr "mode" "XF")])
18368
18369 (define_expand "btruncxf2"
18370   [(use (match_operand:XF 0 "register_operand" ""))
18371    (use (match_operand:XF 1 "register_operand" ""))]
18372   "TARGET_USE_FANCY_MATH_387
18373    && flag_unsafe_math_optimizations && !optimize_size"
18374 {
18375   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18376   DONE;
18377 })
18378
18379 (define_expand "btrunc<mode>2"
18380   [(use (match_operand:MODEF 0 "register_operand" ""))
18381    (use (match_operand:MODEF 1 "register_operand" ""))]
18382   "(TARGET_USE_FANCY_MATH_387
18383     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384         || TARGET_MIX_SSE_I387)
18385     && flag_unsafe_math_optimizations && !optimize_size)
18386    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18387        && !flag_trapping_math
18388        && (TARGET_ROUND || !optimize_size))"
18389 {
18390   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18391       && !flag_trapping_math
18392       && (TARGET_ROUND || !optimize_size))
18393     {
18394       if (TARGET_ROUND)
18395         emit_insn (gen_sse4_1_round<mode>2
18396                    (operands[0], operands[1], GEN_INT (0x03)));
18397       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18398         ix86_expand_trunc (operand0, operand1);
18399       else
18400         ix86_expand_truncdf_32 (operand0, operand1);
18401     }
18402   else
18403     {
18404       rtx op0 = gen_reg_rtx (XFmode);
18405       rtx op1 = gen_reg_rtx (XFmode);
18406
18407       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18408       emit_insn (gen_frndintxf2_trunc (op0, op1));
18409
18410       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18411     }
18412   DONE;
18413 })
18414
18415 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18416 (define_insn_and_split "frndintxf2_mask_pm"
18417   [(set (match_operand:XF 0 "register_operand" "")
18418         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18419          UNSPEC_FRNDINT_MASK_PM))
18420    (clobber (reg:CC FLAGS_REG))]
18421   "TARGET_USE_FANCY_MATH_387
18422    && flag_unsafe_math_optimizations
18423    && !(reload_completed || reload_in_progress)"
18424   "#"
18425   "&& 1"
18426   [(const_int 0)]
18427 {
18428   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18429
18430   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18431   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18432
18433   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18434                                           operands[2], operands[3]));
18435   DONE;
18436 }
18437   [(set_attr "type" "frndint")
18438    (set_attr "i387_cw" "mask_pm")
18439    (set_attr "mode" "XF")])
18440
18441 (define_insn "frndintxf2_mask_pm_i387"
18442   [(set (match_operand:XF 0 "register_operand" "=f")
18443         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18444          UNSPEC_FRNDINT_MASK_PM))
18445    (use (match_operand:HI 2 "memory_operand" "m"))
18446    (use (match_operand:HI 3 "memory_operand" "m"))]
18447   "TARGET_USE_FANCY_MATH_387
18448    && flag_unsafe_math_optimizations"
18449   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18450   [(set_attr "type" "frndint")
18451    (set_attr "i387_cw" "mask_pm")
18452    (set_attr "mode" "XF")])
18453
18454 (define_expand "nearbyintxf2"
18455   [(use (match_operand:XF 0 "register_operand" ""))
18456    (use (match_operand:XF 1 "register_operand" ""))]
18457   "TARGET_USE_FANCY_MATH_387
18458    && flag_unsafe_math_optimizations"
18459 {
18460   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18461
18462   DONE;
18463 })
18464
18465 (define_expand "nearbyint<mode>2"
18466   [(use (match_operand:MODEF 0 "register_operand" ""))
18467    (use (match_operand:MODEF 1 "register_operand" ""))]
18468   "TARGET_USE_FANCY_MATH_387
18469    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18470        || TARGET_MIX_SSE_I387)
18471    && flag_unsafe_math_optimizations"
18472 {
18473   rtx op0 = gen_reg_rtx (XFmode);
18474   rtx op1 = gen_reg_rtx (XFmode);
18475
18476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18477   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18478
18479   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18480   DONE;
18481 })
18482
18483 (define_insn "fxam<mode>2_i387"
18484   [(set (match_operand:HI 0 "register_operand" "=a")
18485         (unspec:HI
18486           [(match_operand:X87MODEF 1 "register_operand" "f")]
18487           UNSPEC_FXAM))]
18488   "TARGET_USE_FANCY_MATH_387"
18489   "fxam\n\tfnstsw\t%0"
18490   [(set_attr "type" "multi")
18491    (set_attr "unit" "i387")
18492    (set_attr "mode" "<MODE>")])
18493
18494 (define_expand "isinf<mode>2"
18495   [(use (match_operand:SI 0 "register_operand" ""))
18496    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18497   "TARGET_USE_FANCY_MATH_387
18498    && TARGET_C99_FUNCTIONS
18499    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18500 {
18501   rtx mask = GEN_INT (0x45);
18502   rtx val = GEN_INT (0x05);
18503
18504   rtx cond;
18505
18506   rtx scratch = gen_reg_rtx (HImode);
18507   rtx res = gen_reg_rtx (QImode);
18508
18509   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18510   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18511   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18512   cond = gen_rtx_fmt_ee (EQ, QImode,
18513                          gen_rtx_REG (CCmode, FLAGS_REG),
18514                          const0_rtx);
18515   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18516   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18517   DONE;
18518 })
18519
18520 (define_expand "signbit<mode>2"
18521   [(use (match_operand:SI 0 "register_operand" ""))
18522    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18523   "TARGET_USE_FANCY_MATH_387
18524    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18525 {
18526   rtx mask = GEN_INT (0x0200);
18527
18528   rtx scratch = gen_reg_rtx (HImode);
18529
18530   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18531   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18532   DONE;
18533 })
18534 \f
18535 ;; Block operation instructions
18536
18537 (define_expand "movmemsi"
18538   [(use (match_operand:BLK 0 "memory_operand" ""))
18539    (use (match_operand:BLK 1 "memory_operand" ""))
18540    (use (match_operand:SI 2 "nonmemory_operand" ""))
18541    (use (match_operand:SI 3 "const_int_operand" ""))
18542    (use (match_operand:SI 4 "const_int_operand" ""))
18543    (use (match_operand:SI 5 "const_int_operand" ""))]
18544   ""
18545 {
18546  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18547                          operands[4], operands[5]))
18548    DONE;
18549  else
18550    FAIL;
18551 })
18552
18553 (define_expand "movmemdi"
18554   [(use (match_operand:BLK 0 "memory_operand" ""))
18555    (use (match_operand:BLK 1 "memory_operand" ""))
18556    (use (match_operand:DI 2 "nonmemory_operand" ""))
18557    (use (match_operand:DI 3 "const_int_operand" ""))
18558    (use (match_operand:SI 4 "const_int_operand" ""))
18559    (use (match_operand:SI 5 "const_int_operand" ""))]
18560   "TARGET_64BIT"
18561 {
18562  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18563                          operands[4], operands[5]))
18564    DONE;
18565  else
18566    FAIL;
18567 })
18568
18569 ;; Most CPUs don't like single string operations
18570 ;; Handle this case here to simplify previous expander.
18571
18572 (define_expand "strmov"
18573   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18574    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18575    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18576               (clobber (reg:CC FLAGS_REG))])
18577    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18578               (clobber (reg:CC FLAGS_REG))])]
18579   ""
18580 {
18581   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18582
18583   /* If .md ever supports :P for Pmode, these can be directly
18584      in the pattern above.  */
18585   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18586   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18587
18588   /* Can't use this if the user has appropriated esi or edi.  */
18589   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18590       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18591     {
18592       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18593                                       operands[2], operands[3],
18594                                       operands[5], operands[6]));
18595       DONE;
18596     }
18597
18598   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18599 })
18600
18601 (define_expand "strmov_singleop"
18602   [(parallel [(set (match_operand 1 "memory_operand" "")
18603                    (match_operand 3 "memory_operand" ""))
18604               (set (match_operand 0 "register_operand" "")
18605                    (match_operand 4 "" ""))
18606               (set (match_operand 2 "register_operand" "")
18607                    (match_operand 5 "" ""))])]
18608   "TARGET_SINGLE_STRINGOP || optimize_size"
18609   "")
18610
18611 (define_insn "*strmovdi_rex_1"
18612   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18613         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18614    (set (match_operand:DI 0 "register_operand" "=D")
18615         (plus:DI (match_dup 2)
18616                  (const_int 8)))
18617    (set (match_operand:DI 1 "register_operand" "=S")
18618         (plus:DI (match_dup 3)
18619                  (const_int 8)))]
18620   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18621   "movsq"
18622   [(set_attr "type" "str")
18623    (set_attr "mode" "DI")
18624    (set_attr "memory" "both")])
18625
18626 (define_insn "*strmovsi_1"
18627   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18628         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18629    (set (match_operand:SI 0 "register_operand" "=D")
18630         (plus:SI (match_dup 2)
18631                  (const_int 4)))
18632    (set (match_operand:SI 1 "register_operand" "=S")
18633         (plus:SI (match_dup 3)
18634                  (const_int 4)))]
18635   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18636   "{movsl|movsd}"
18637   [(set_attr "type" "str")
18638    (set_attr "mode" "SI")
18639    (set_attr "memory" "both")])
18640
18641 (define_insn "*strmovsi_rex_1"
18642   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18643         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18644    (set (match_operand:DI 0 "register_operand" "=D")
18645         (plus:DI (match_dup 2)
18646                  (const_int 4)))
18647    (set (match_operand:DI 1 "register_operand" "=S")
18648         (plus:DI (match_dup 3)
18649                  (const_int 4)))]
18650   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18651   "{movsl|movsd}"
18652   [(set_attr "type" "str")
18653    (set_attr "mode" "SI")
18654    (set_attr "memory" "both")])
18655
18656 (define_insn "*strmovhi_1"
18657   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18658         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18659    (set (match_operand:SI 0 "register_operand" "=D")
18660         (plus:SI (match_dup 2)
18661                  (const_int 2)))
18662    (set (match_operand:SI 1 "register_operand" "=S")
18663         (plus:SI (match_dup 3)
18664                  (const_int 2)))]
18665   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666   "movsw"
18667   [(set_attr "type" "str")
18668    (set_attr "memory" "both")
18669    (set_attr "mode" "HI")])
18670
18671 (define_insn "*strmovhi_rex_1"
18672   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18673         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18674    (set (match_operand:DI 0 "register_operand" "=D")
18675         (plus:DI (match_dup 2)
18676                  (const_int 2)))
18677    (set (match_operand:DI 1 "register_operand" "=S")
18678         (plus:DI (match_dup 3)
18679                  (const_int 2)))]
18680   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18681   "movsw"
18682   [(set_attr "type" "str")
18683    (set_attr "memory" "both")
18684    (set_attr "mode" "HI")])
18685
18686 (define_insn "*strmovqi_1"
18687   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18688         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18689    (set (match_operand:SI 0 "register_operand" "=D")
18690         (plus:SI (match_dup 2)
18691                  (const_int 1)))
18692    (set (match_operand:SI 1 "register_operand" "=S")
18693         (plus:SI (match_dup 3)
18694                  (const_int 1)))]
18695   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18696   "movsb"
18697   [(set_attr "type" "str")
18698    (set_attr "memory" "both")
18699    (set_attr "mode" "QI")])
18700
18701 (define_insn "*strmovqi_rex_1"
18702   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18703         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18704    (set (match_operand:DI 0 "register_operand" "=D")
18705         (plus:DI (match_dup 2)
18706                  (const_int 1)))
18707    (set (match_operand:DI 1 "register_operand" "=S")
18708         (plus:DI (match_dup 3)
18709                  (const_int 1)))]
18710   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18711   "movsb"
18712   [(set_attr "type" "str")
18713    (set_attr "memory" "both")
18714    (set_attr "mode" "QI")])
18715
18716 (define_expand "rep_mov"
18717   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18718               (set (match_operand 0 "register_operand" "")
18719                    (match_operand 5 "" ""))
18720               (set (match_operand 2 "register_operand" "")
18721                    (match_operand 6 "" ""))
18722               (set (match_operand 1 "memory_operand" "")
18723                    (match_operand 3 "memory_operand" ""))
18724               (use (match_dup 4))])]
18725   ""
18726   "")
18727
18728 (define_insn "*rep_movdi_rex64"
18729   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18730    (set (match_operand:DI 0 "register_operand" "=D")
18731         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18732                             (const_int 3))
18733                  (match_operand:DI 3 "register_operand" "0")))
18734    (set (match_operand:DI 1 "register_operand" "=S")
18735         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18736                  (match_operand:DI 4 "register_operand" "1")))
18737    (set (mem:BLK (match_dup 3))
18738         (mem:BLK (match_dup 4)))
18739    (use (match_dup 5))]
18740   "TARGET_64BIT"
18741   "rep movsq"
18742   [(set_attr "type" "str")
18743    (set_attr "prefix_rep" "1")
18744    (set_attr "memory" "both")
18745    (set_attr "mode" "DI")])
18746
18747 (define_insn "*rep_movsi"
18748   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18749    (set (match_operand:SI 0 "register_operand" "=D")
18750         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18751                             (const_int 2))
18752                  (match_operand:SI 3 "register_operand" "0")))
18753    (set (match_operand:SI 1 "register_operand" "=S")
18754         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18755                  (match_operand:SI 4 "register_operand" "1")))
18756    (set (mem:BLK (match_dup 3))
18757         (mem:BLK (match_dup 4)))
18758    (use (match_dup 5))]
18759   "!TARGET_64BIT"
18760   "rep movs{l|d}"
18761   [(set_attr "type" "str")
18762    (set_attr "prefix_rep" "1")
18763    (set_attr "memory" "both")
18764    (set_attr "mode" "SI")])
18765
18766 (define_insn "*rep_movsi_rex64"
18767   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18768    (set (match_operand:DI 0 "register_operand" "=D")
18769         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18770                             (const_int 2))
18771                  (match_operand:DI 3 "register_operand" "0")))
18772    (set (match_operand:DI 1 "register_operand" "=S")
18773         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18774                  (match_operand:DI 4 "register_operand" "1")))
18775    (set (mem:BLK (match_dup 3))
18776         (mem:BLK (match_dup 4)))
18777    (use (match_dup 5))]
18778   "TARGET_64BIT"
18779   "rep movs{l|d}"
18780   [(set_attr "type" "str")
18781    (set_attr "prefix_rep" "1")
18782    (set_attr "memory" "both")
18783    (set_attr "mode" "SI")])
18784
18785 (define_insn "*rep_movqi"
18786   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18787    (set (match_operand:SI 0 "register_operand" "=D")
18788         (plus:SI (match_operand:SI 3 "register_operand" "0")
18789                  (match_operand:SI 5 "register_operand" "2")))
18790    (set (match_operand:SI 1 "register_operand" "=S")
18791         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18792    (set (mem:BLK (match_dup 3))
18793         (mem:BLK (match_dup 4)))
18794    (use (match_dup 5))]
18795   "!TARGET_64BIT"
18796   "rep movsb"
18797   [(set_attr "type" "str")
18798    (set_attr "prefix_rep" "1")
18799    (set_attr "memory" "both")
18800    (set_attr "mode" "SI")])
18801
18802 (define_insn "*rep_movqi_rex64"
18803   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18804    (set (match_operand:DI 0 "register_operand" "=D")
18805         (plus:DI (match_operand:DI 3 "register_operand" "0")
18806                  (match_operand:DI 5 "register_operand" "2")))
18807    (set (match_operand:DI 1 "register_operand" "=S")
18808         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18809    (set (mem:BLK (match_dup 3))
18810         (mem:BLK (match_dup 4)))
18811    (use (match_dup 5))]
18812   "TARGET_64BIT"
18813   "rep movsb"
18814   [(set_attr "type" "str")
18815    (set_attr "prefix_rep" "1")
18816    (set_attr "memory" "both")
18817    (set_attr "mode" "SI")])
18818
18819 (define_expand "setmemsi"
18820    [(use (match_operand:BLK 0 "memory_operand" ""))
18821     (use (match_operand:SI 1 "nonmemory_operand" ""))
18822     (use (match_operand 2 "const_int_operand" ""))
18823     (use (match_operand 3 "const_int_operand" ""))
18824     (use (match_operand:SI 4 "const_int_operand" ""))
18825     (use (match_operand:SI 5 "const_int_operand" ""))]
18826   ""
18827 {
18828  if (ix86_expand_setmem (operands[0], operands[1],
18829                          operands[2], operands[3],
18830                          operands[4], operands[5]))
18831    DONE;
18832  else
18833    FAIL;
18834 })
18835
18836 (define_expand "setmemdi"
18837    [(use (match_operand:BLK 0 "memory_operand" ""))
18838     (use (match_operand:DI 1 "nonmemory_operand" ""))
18839     (use (match_operand 2 "const_int_operand" ""))
18840     (use (match_operand 3 "const_int_operand" ""))
18841     (use (match_operand 4 "const_int_operand" ""))
18842     (use (match_operand 5 "const_int_operand" ""))]
18843   "TARGET_64BIT"
18844 {
18845  if (ix86_expand_setmem (operands[0], operands[1],
18846                          operands[2], operands[3],
18847                          operands[4], operands[5]))
18848    DONE;
18849  else
18850    FAIL;
18851 })
18852
18853 ;; Most CPUs don't like single string operations
18854 ;; Handle this case here to simplify previous expander.
18855
18856 (define_expand "strset"
18857   [(set (match_operand 1 "memory_operand" "")
18858         (match_operand 2 "register_operand" ""))
18859    (parallel [(set (match_operand 0 "register_operand" "")
18860                    (match_dup 3))
18861               (clobber (reg:CC FLAGS_REG))])]
18862   ""
18863 {
18864   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18865     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18866
18867   /* If .md ever supports :P for Pmode, this can be directly
18868      in the pattern above.  */
18869   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18870                               GEN_INT (GET_MODE_SIZE (GET_MODE
18871                                                       (operands[2]))));
18872   if (TARGET_SINGLE_STRINGOP || optimize_size)
18873     {
18874       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18875                                       operands[3]));
18876       DONE;
18877     }
18878 })
18879
18880 (define_expand "strset_singleop"
18881   [(parallel [(set (match_operand 1 "memory_operand" "")
18882                    (match_operand 2 "register_operand" ""))
18883               (set (match_operand 0 "register_operand" "")
18884                    (match_operand 3 "" ""))])]
18885   "TARGET_SINGLE_STRINGOP || optimize_size"
18886   "")
18887
18888 (define_insn "*strsetdi_rex_1"
18889   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18890         (match_operand:DI 2 "register_operand" "a"))
18891    (set (match_operand:DI 0 "register_operand" "=D")
18892         (plus:DI (match_dup 1)
18893                  (const_int 8)))]
18894   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18895   "stosq"
18896   [(set_attr "type" "str")
18897    (set_attr "memory" "store")
18898    (set_attr "mode" "DI")])
18899
18900 (define_insn "*strsetsi_1"
18901   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18902         (match_operand:SI 2 "register_operand" "a"))
18903    (set (match_operand:SI 0 "register_operand" "=D")
18904         (plus:SI (match_dup 1)
18905                  (const_int 4)))]
18906   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18907   "{stosl|stosd}"
18908   [(set_attr "type" "str")
18909    (set_attr "memory" "store")
18910    (set_attr "mode" "SI")])
18911
18912 (define_insn "*strsetsi_rex_1"
18913   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18914         (match_operand:SI 2 "register_operand" "a"))
18915    (set (match_operand:DI 0 "register_operand" "=D")
18916         (plus:DI (match_dup 1)
18917                  (const_int 4)))]
18918   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18919   "{stosl|stosd}"
18920   [(set_attr "type" "str")
18921    (set_attr "memory" "store")
18922    (set_attr "mode" "SI")])
18923
18924 (define_insn "*strsethi_1"
18925   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18926         (match_operand:HI 2 "register_operand" "a"))
18927    (set (match_operand:SI 0 "register_operand" "=D")
18928         (plus:SI (match_dup 1)
18929                  (const_int 2)))]
18930   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18931   "stosw"
18932   [(set_attr "type" "str")
18933    (set_attr "memory" "store")
18934    (set_attr "mode" "HI")])
18935
18936 (define_insn "*strsethi_rex_1"
18937   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18938         (match_operand:HI 2 "register_operand" "a"))
18939    (set (match_operand:DI 0 "register_operand" "=D")
18940         (plus:DI (match_dup 1)
18941                  (const_int 2)))]
18942   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18943   "stosw"
18944   [(set_attr "type" "str")
18945    (set_attr "memory" "store")
18946    (set_attr "mode" "HI")])
18947
18948 (define_insn "*strsetqi_1"
18949   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18950         (match_operand:QI 2 "register_operand" "a"))
18951    (set (match_operand:SI 0 "register_operand" "=D")
18952         (plus:SI (match_dup 1)
18953                  (const_int 1)))]
18954   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18955   "stosb"
18956   [(set_attr "type" "str")
18957    (set_attr "memory" "store")
18958    (set_attr "mode" "QI")])
18959
18960 (define_insn "*strsetqi_rex_1"
18961   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18962         (match_operand:QI 2 "register_operand" "a"))
18963    (set (match_operand:DI 0 "register_operand" "=D")
18964         (plus:DI (match_dup 1)
18965                  (const_int 1)))]
18966   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18967   "stosb"
18968   [(set_attr "type" "str")
18969    (set_attr "memory" "store")
18970    (set_attr "mode" "QI")])
18971
18972 (define_expand "rep_stos"
18973   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18974               (set (match_operand 0 "register_operand" "")
18975                    (match_operand 4 "" ""))
18976               (set (match_operand 2 "memory_operand" "") (const_int 0))
18977               (use (match_operand 3 "register_operand" ""))
18978               (use (match_dup 1))])]
18979   ""
18980   "")
18981
18982 (define_insn "*rep_stosdi_rex64"
18983   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18984    (set (match_operand:DI 0 "register_operand" "=D")
18985         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18986                             (const_int 3))
18987                  (match_operand:DI 3 "register_operand" "0")))
18988    (set (mem:BLK (match_dup 3))
18989         (const_int 0))
18990    (use (match_operand:DI 2 "register_operand" "a"))
18991    (use (match_dup 4))]
18992   "TARGET_64BIT"
18993   "rep stosq"
18994   [(set_attr "type" "str")
18995    (set_attr "prefix_rep" "1")
18996    (set_attr "memory" "store")
18997    (set_attr "mode" "DI")])
18998
18999 (define_insn "*rep_stossi"
19000   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19001    (set (match_operand:SI 0 "register_operand" "=D")
19002         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19003                             (const_int 2))
19004                  (match_operand:SI 3 "register_operand" "0")))
19005    (set (mem:BLK (match_dup 3))
19006         (const_int 0))
19007    (use (match_operand:SI 2 "register_operand" "a"))
19008    (use (match_dup 4))]
19009   "!TARGET_64BIT"
19010   "rep stos{l|d}"
19011   [(set_attr "type" "str")
19012    (set_attr "prefix_rep" "1")
19013    (set_attr "memory" "store")
19014    (set_attr "mode" "SI")])
19015
19016 (define_insn "*rep_stossi_rex64"
19017   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19018    (set (match_operand:DI 0 "register_operand" "=D")
19019         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19020                             (const_int 2))
19021                  (match_operand:DI 3 "register_operand" "0")))
19022    (set (mem:BLK (match_dup 3))
19023         (const_int 0))
19024    (use (match_operand:SI 2 "register_operand" "a"))
19025    (use (match_dup 4))]
19026   "TARGET_64BIT"
19027   "rep stos{l|d}"
19028   [(set_attr "type" "str")
19029    (set_attr "prefix_rep" "1")
19030    (set_attr "memory" "store")
19031    (set_attr "mode" "SI")])
19032
19033 (define_insn "*rep_stosqi"
19034   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19035    (set (match_operand:SI 0 "register_operand" "=D")
19036         (plus:SI (match_operand:SI 3 "register_operand" "0")
19037                  (match_operand:SI 4 "register_operand" "1")))
19038    (set (mem:BLK (match_dup 3))
19039         (const_int 0))
19040    (use (match_operand:QI 2 "register_operand" "a"))
19041    (use (match_dup 4))]
19042   "!TARGET_64BIT"
19043   "rep stosb"
19044   [(set_attr "type" "str")
19045    (set_attr "prefix_rep" "1")
19046    (set_attr "memory" "store")
19047    (set_attr "mode" "QI")])
19048
19049 (define_insn "*rep_stosqi_rex64"
19050   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19051    (set (match_operand:DI 0 "register_operand" "=D")
19052         (plus:DI (match_operand:DI 3 "register_operand" "0")
19053                  (match_operand:DI 4 "register_operand" "1")))
19054    (set (mem:BLK (match_dup 3))
19055         (const_int 0))
19056    (use (match_operand:QI 2 "register_operand" "a"))
19057    (use (match_dup 4))]
19058   "TARGET_64BIT"
19059   "rep stosb"
19060   [(set_attr "type" "str")
19061    (set_attr "prefix_rep" "1")
19062    (set_attr "memory" "store")
19063    (set_attr "mode" "QI")])
19064
19065 (define_expand "cmpstrnsi"
19066   [(set (match_operand:SI 0 "register_operand" "")
19067         (compare:SI (match_operand:BLK 1 "general_operand" "")
19068                     (match_operand:BLK 2 "general_operand" "")))
19069    (use (match_operand 3 "general_operand" ""))
19070    (use (match_operand 4 "immediate_operand" ""))]
19071   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19072 {
19073   rtx addr1, addr2, out, outlow, count, countreg, align;
19074
19075   /* Can't use this if the user has appropriated esi or edi.  */
19076   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19077     FAIL;
19078
19079   out = operands[0];
19080   if (!REG_P (out))
19081     out = gen_reg_rtx (SImode);
19082
19083   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19084   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19085   if (addr1 != XEXP (operands[1], 0))
19086     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19087   if (addr2 != XEXP (operands[2], 0))
19088     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19089
19090   count = operands[3];
19091   countreg = ix86_zero_extend_to_Pmode (count);
19092
19093   /* %%% Iff we are testing strict equality, we can use known alignment
19094      to good advantage.  This may be possible with combine, particularly
19095      once cc0 is dead.  */
19096   align = operands[4];
19097
19098   if (CONST_INT_P (count))
19099     {
19100       if (INTVAL (count) == 0)
19101         {
19102           emit_move_insn (operands[0], const0_rtx);
19103           DONE;
19104         }
19105       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19106                                      operands[1], operands[2]));
19107     }
19108   else
19109     {
19110       if (TARGET_64BIT)
19111         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19112       else
19113         emit_insn (gen_cmpsi_1 (countreg, countreg));
19114       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19115                                   operands[1], operands[2]));
19116     }
19117
19118   outlow = gen_lowpart (QImode, out);
19119   emit_insn (gen_cmpintqi (outlow));
19120   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19121
19122   if (operands[0] != out)
19123     emit_move_insn (operands[0], out);
19124
19125   DONE;
19126 })
19127
19128 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19129
19130 (define_expand "cmpintqi"
19131   [(set (match_dup 1)
19132         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19133    (set (match_dup 2)
19134         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19135    (parallel [(set (match_operand:QI 0 "register_operand" "")
19136                    (minus:QI (match_dup 1)
19137                              (match_dup 2)))
19138               (clobber (reg:CC FLAGS_REG))])]
19139   ""
19140   "operands[1] = gen_reg_rtx (QImode);
19141    operands[2] = gen_reg_rtx (QImode);")
19142
19143 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19144 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19145
19146 (define_expand "cmpstrnqi_nz_1"
19147   [(parallel [(set (reg:CC FLAGS_REG)
19148                    (compare:CC (match_operand 4 "memory_operand" "")
19149                                (match_operand 5 "memory_operand" "")))
19150               (use (match_operand 2 "register_operand" ""))
19151               (use (match_operand:SI 3 "immediate_operand" ""))
19152               (clobber (match_operand 0 "register_operand" ""))
19153               (clobber (match_operand 1 "register_operand" ""))
19154               (clobber (match_dup 2))])]
19155   ""
19156   "")
19157
19158 (define_insn "*cmpstrnqi_nz_1"
19159   [(set (reg:CC FLAGS_REG)
19160         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19161                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19162    (use (match_operand:SI 6 "register_operand" "2"))
19163    (use (match_operand:SI 3 "immediate_operand" "i"))
19164    (clobber (match_operand:SI 0 "register_operand" "=S"))
19165    (clobber (match_operand:SI 1 "register_operand" "=D"))
19166    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19167   "!TARGET_64BIT"
19168   "repz cmpsb"
19169   [(set_attr "type" "str")
19170    (set_attr "mode" "QI")
19171    (set_attr "prefix_rep" "1")])
19172
19173 (define_insn "*cmpstrnqi_nz_rex_1"
19174   [(set (reg:CC FLAGS_REG)
19175         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19176                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19177    (use (match_operand:DI 6 "register_operand" "2"))
19178    (use (match_operand:SI 3 "immediate_operand" "i"))
19179    (clobber (match_operand:DI 0 "register_operand" "=S"))
19180    (clobber (match_operand:DI 1 "register_operand" "=D"))
19181    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19182   "TARGET_64BIT"
19183   "repz cmpsb"
19184   [(set_attr "type" "str")
19185    (set_attr "mode" "QI")
19186    (set_attr "prefix_rep" "1")])
19187
19188 ;; The same, but the count is not known to not be zero.
19189
19190 (define_expand "cmpstrnqi_1"
19191   [(parallel [(set (reg:CC FLAGS_REG)
19192                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19193                                      (const_int 0))
19194                   (compare:CC (match_operand 4 "memory_operand" "")
19195                               (match_operand 5 "memory_operand" ""))
19196                   (const_int 0)))
19197               (use (match_operand:SI 3 "immediate_operand" ""))
19198               (use (reg:CC FLAGS_REG))
19199               (clobber (match_operand 0 "register_operand" ""))
19200               (clobber (match_operand 1 "register_operand" ""))
19201               (clobber (match_dup 2))])]
19202   ""
19203   "")
19204
19205 (define_insn "*cmpstrnqi_1"
19206   [(set (reg:CC FLAGS_REG)
19207         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19208                              (const_int 0))
19209           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19210                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19211           (const_int 0)))
19212    (use (match_operand:SI 3 "immediate_operand" "i"))
19213    (use (reg:CC FLAGS_REG))
19214    (clobber (match_operand:SI 0 "register_operand" "=S"))
19215    (clobber (match_operand:SI 1 "register_operand" "=D"))
19216    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19217   "!TARGET_64BIT"
19218   "repz cmpsb"
19219   [(set_attr "type" "str")
19220    (set_attr "mode" "QI")
19221    (set_attr "prefix_rep" "1")])
19222
19223 (define_insn "*cmpstrnqi_rex_1"
19224   [(set (reg:CC FLAGS_REG)
19225         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19226                              (const_int 0))
19227           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19228                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19229           (const_int 0)))
19230    (use (match_operand:SI 3 "immediate_operand" "i"))
19231    (use (reg:CC FLAGS_REG))
19232    (clobber (match_operand:DI 0 "register_operand" "=S"))
19233    (clobber (match_operand:DI 1 "register_operand" "=D"))
19234    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19235   "TARGET_64BIT"
19236   "repz cmpsb"
19237   [(set_attr "type" "str")
19238    (set_attr "mode" "QI")
19239    (set_attr "prefix_rep" "1")])
19240
19241 (define_expand "strlensi"
19242   [(set (match_operand:SI 0 "register_operand" "")
19243         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19244                     (match_operand:QI 2 "immediate_operand" "")
19245                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19246   ""
19247 {
19248  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19249    DONE;
19250  else
19251    FAIL;
19252 })
19253
19254 (define_expand "strlendi"
19255   [(set (match_operand:DI 0 "register_operand" "")
19256         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19257                     (match_operand:QI 2 "immediate_operand" "")
19258                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19259   ""
19260 {
19261  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19262    DONE;
19263  else
19264    FAIL;
19265 })
19266
19267 (define_expand "strlenqi_1"
19268   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19269               (clobber (match_operand 1 "register_operand" ""))
19270               (clobber (reg:CC FLAGS_REG))])]
19271   ""
19272   "")
19273
19274 (define_insn "*strlenqi_1"
19275   [(set (match_operand:SI 0 "register_operand" "=&c")
19276         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19277                     (match_operand:QI 2 "register_operand" "a")
19278                     (match_operand:SI 3 "immediate_operand" "i")
19279                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19280    (clobber (match_operand:SI 1 "register_operand" "=D"))
19281    (clobber (reg:CC FLAGS_REG))]
19282   "!TARGET_64BIT"
19283   "repnz scasb"
19284   [(set_attr "type" "str")
19285    (set_attr "mode" "QI")
19286    (set_attr "prefix_rep" "1")])
19287
19288 (define_insn "*strlenqi_rex_1"
19289   [(set (match_operand:DI 0 "register_operand" "=&c")
19290         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19291                     (match_operand:QI 2 "register_operand" "a")
19292                     (match_operand:DI 3 "immediate_operand" "i")
19293                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19294    (clobber (match_operand:DI 1 "register_operand" "=D"))
19295    (clobber (reg:CC FLAGS_REG))]
19296   "TARGET_64BIT"
19297   "repnz scasb"
19298   [(set_attr "type" "str")
19299    (set_attr "mode" "QI")
19300    (set_attr "prefix_rep" "1")])
19301
19302 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19303 ;; handled in combine, but it is not currently up to the task.
19304 ;; When used for their truth value, the cmpstrn* expanders generate
19305 ;; code like this:
19306 ;;
19307 ;;   repz cmpsb
19308 ;;   seta       %al
19309 ;;   setb       %dl
19310 ;;   cmpb       %al, %dl
19311 ;;   jcc        label
19312 ;;
19313 ;; The intermediate three instructions are unnecessary.
19314
19315 ;; This one handles cmpstrn*_nz_1...
19316 (define_peephole2
19317   [(parallel[
19318      (set (reg:CC FLAGS_REG)
19319           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19320                       (mem:BLK (match_operand 5 "register_operand" ""))))
19321      (use (match_operand 6 "register_operand" ""))
19322      (use (match_operand:SI 3 "immediate_operand" ""))
19323      (clobber (match_operand 0 "register_operand" ""))
19324      (clobber (match_operand 1 "register_operand" ""))
19325      (clobber (match_operand 2 "register_operand" ""))])
19326    (set (match_operand:QI 7 "register_operand" "")
19327         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19328    (set (match_operand:QI 8 "register_operand" "")
19329         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19330    (set (reg FLAGS_REG)
19331         (compare (match_dup 7) (match_dup 8)))
19332   ]
19333   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19334   [(parallel[
19335      (set (reg:CC FLAGS_REG)
19336           (compare:CC (mem:BLK (match_dup 4))
19337                       (mem:BLK (match_dup 5))))
19338      (use (match_dup 6))
19339      (use (match_dup 3))
19340      (clobber (match_dup 0))
19341      (clobber (match_dup 1))
19342      (clobber (match_dup 2))])]
19343   "")
19344
19345 ;; ...and this one handles cmpstrn*_1.
19346 (define_peephole2
19347   [(parallel[
19348      (set (reg:CC FLAGS_REG)
19349           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19350                                (const_int 0))
19351             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19352                         (mem:BLK (match_operand 5 "register_operand" "")))
19353             (const_int 0)))
19354      (use (match_operand:SI 3 "immediate_operand" ""))
19355      (use (reg:CC FLAGS_REG))
19356      (clobber (match_operand 0 "register_operand" ""))
19357      (clobber (match_operand 1 "register_operand" ""))
19358      (clobber (match_operand 2 "register_operand" ""))])
19359    (set (match_operand:QI 7 "register_operand" "")
19360         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19361    (set (match_operand:QI 8 "register_operand" "")
19362         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19363    (set (reg FLAGS_REG)
19364         (compare (match_dup 7) (match_dup 8)))
19365   ]
19366   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19367   [(parallel[
19368      (set (reg:CC FLAGS_REG)
19369           (if_then_else:CC (ne (match_dup 6)
19370                                (const_int 0))
19371             (compare:CC (mem:BLK (match_dup 4))
19372                         (mem:BLK (match_dup 5)))
19373             (const_int 0)))
19374      (use (match_dup 3))
19375      (use (reg:CC FLAGS_REG))
19376      (clobber (match_dup 0))
19377      (clobber (match_dup 1))
19378      (clobber (match_dup 2))])]
19379   "")
19380
19381
19382 \f
19383 ;; Conditional move instructions.
19384
19385 (define_expand "movdicc"
19386   [(set (match_operand:DI 0 "register_operand" "")
19387         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19388                          (match_operand:DI 2 "general_operand" "")
19389                          (match_operand:DI 3 "general_operand" "")))]
19390   "TARGET_64BIT"
19391   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19392
19393 (define_insn "x86_movdicc_0_m1_rex64"
19394   [(set (match_operand:DI 0 "register_operand" "=r")
19395         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19396           (const_int -1)
19397           (const_int 0)))
19398    (clobber (reg:CC FLAGS_REG))]
19399   "TARGET_64BIT"
19400   "sbb{q}\t%0, %0"
19401   ; Since we don't have the proper number of operands for an alu insn,
19402   ; fill in all the blanks.
19403   [(set_attr "type" "alu")
19404    (set_attr "pent_pair" "pu")
19405    (set_attr "memory" "none")
19406    (set_attr "imm_disp" "false")
19407    (set_attr "mode" "DI")
19408    (set_attr "length_immediate" "0")])
19409
19410 (define_insn "*movdicc_c_rex64"
19411   [(set (match_operand:DI 0 "register_operand" "=r,r")
19412         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19413                                 [(reg FLAGS_REG) (const_int 0)])
19414                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19415                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19416   "TARGET_64BIT && TARGET_CMOVE
19417    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19418   "@
19419    cmov%O2%C1\t{%2, %0|%0, %2}
19420    cmov%O2%c1\t{%3, %0|%0, %3}"
19421   [(set_attr "type" "icmov")
19422    (set_attr "mode" "DI")])
19423
19424 (define_expand "movsicc"
19425   [(set (match_operand:SI 0 "register_operand" "")
19426         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19427                          (match_operand:SI 2 "general_operand" "")
19428                          (match_operand:SI 3 "general_operand" "")))]
19429   ""
19430   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19431
19432 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19433 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19434 ;; So just document what we're doing explicitly.
19435
19436 (define_insn "x86_movsicc_0_m1"
19437   [(set (match_operand:SI 0 "register_operand" "=r")
19438         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19439           (const_int -1)
19440           (const_int 0)))
19441    (clobber (reg:CC FLAGS_REG))]
19442   ""
19443   "sbb{l}\t%0, %0"
19444   ; Since we don't have the proper number of operands for an alu insn,
19445   ; fill in all the blanks.
19446   [(set_attr "type" "alu")
19447    (set_attr "pent_pair" "pu")
19448    (set_attr "memory" "none")
19449    (set_attr "imm_disp" "false")
19450    (set_attr "mode" "SI")
19451    (set_attr "length_immediate" "0")])
19452
19453 (define_insn "*movsicc_noc"
19454   [(set (match_operand:SI 0 "register_operand" "=r,r")
19455         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19456                                 [(reg FLAGS_REG) (const_int 0)])
19457                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19458                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19459   "TARGET_CMOVE
19460    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19461   "@
19462    cmov%O2%C1\t{%2, %0|%0, %2}
19463    cmov%O2%c1\t{%3, %0|%0, %3}"
19464   [(set_attr "type" "icmov")
19465    (set_attr "mode" "SI")])
19466
19467 (define_expand "movhicc"
19468   [(set (match_operand:HI 0 "register_operand" "")
19469         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19470                          (match_operand:HI 2 "general_operand" "")
19471                          (match_operand:HI 3 "general_operand" "")))]
19472   "TARGET_HIMODE_MATH"
19473   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19474
19475 (define_insn "*movhicc_noc"
19476   [(set (match_operand:HI 0 "register_operand" "=r,r")
19477         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19478                                 [(reg FLAGS_REG) (const_int 0)])
19479                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19480                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19481   "TARGET_CMOVE
19482    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19483   "@
19484    cmov%O2%C1\t{%2, %0|%0, %2}
19485    cmov%O2%c1\t{%3, %0|%0, %3}"
19486   [(set_attr "type" "icmov")
19487    (set_attr "mode" "HI")])
19488
19489 (define_expand "movqicc"
19490   [(set (match_operand:QI 0 "register_operand" "")
19491         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19492                          (match_operand:QI 2 "general_operand" "")
19493                          (match_operand:QI 3 "general_operand" "")))]
19494   "TARGET_QIMODE_MATH"
19495   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19496
19497 (define_insn_and_split "*movqicc_noc"
19498   [(set (match_operand:QI 0 "register_operand" "=r,r")
19499         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19500                                 [(match_operand 4 "flags_reg_operand" "")
19501                                  (const_int 0)])
19502                       (match_operand:QI 2 "register_operand" "r,0")
19503                       (match_operand:QI 3 "register_operand" "0,r")))]
19504   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19505   "#"
19506   "&& reload_completed"
19507   [(set (match_dup 0)
19508         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19509                       (match_dup 2)
19510                       (match_dup 3)))]
19511   "operands[0] = gen_lowpart (SImode, operands[0]);
19512    operands[2] = gen_lowpart (SImode, operands[2]);
19513    operands[3] = gen_lowpart (SImode, operands[3]);"
19514   [(set_attr "type" "icmov")
19515    (set_attr "mode" "SI")])
19516
19517 (define_expand "movsfcc"
19518   [(set (match_operand:SF 0 "register_operand" "")
19519         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19520                          (match_operand:SF 2 "register_operand" "")
19521                          (match_operand:SF 3 "register_operand" "")))]
19522   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19523   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19524
19525 (define_insn "*movsfcc_1_387"
19526   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19527         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19528                                 [(reg FLAGS_REG) (const_int 0)])
19529                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19530                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19531   "TARGET_80387 && TARGET_CMOVE
19532    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19533   "@
19534    fcmov%F1\t{%2, %0|%0, %2}
19535    fcmov%f1\t{%3, %0|%0, %3}
19536    cmov%O2%C1\t{%2, %0|%0, %2}
19537    cmov%O2%c1\t{%3, %0|%0, %3}"
19538   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19539    (set_attr "mode" "SF,SF,SI,SI")])
19540
19541 (define_expand "movdfcc"
19542   [(set (match_operand:DF 0 "register_operand" "")
19543         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19544                          (match_operand:DF 2 "register_operand" "")
19545                          (match_operand:DF 3 "register_operand" "")))]
19546   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19547   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19548
19549 (define_insn "*movdfcc_1"
19550   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19551         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19552                                 [(reg FLAGS_REG) (const_int 0)])
19553                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19554                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19555   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19556    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19557   "@
19558    fcmov%F1\t{%2, %0|%0, %2}
19559    fcmov%f1\t{%3, %0|%0, %3}
19560    #
19561    #"
19562   [(set_attr "type" "fcmov,fcmov,multi,multi")
19563    (set_attr "mode" "DF")])
19564
19565 (define_insn "*movdfcc_1_rex64"
19566   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19567         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19568                                 [(reg FLAGS_REG) (const_int 0)])
19569                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19570                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19571   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19572    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19573   "@
19574    fcmov%F1\t{%2, %0|%0, %2}
19575    fcmov%f1\t{%3, %0|%0, %3}
19576    cmov%O2%C1\t{%2, %0|%0, %2}
19577    cmov%O2%c1\t{%3, %0|%0, %3}"
19578   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19579    (set_attr "mode" "DF")])
19580
19581 (define_split
19582   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19583         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19584                                 [(match_operand 4 "flags_reg_operand" "")
19585                                  (const_int 0)])
19586                       (match_operand:DF 2 "nonimmediate_operand" "")
19587                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19588   "!TARGET_64BIT && reload_completed"
19589   [(set (match_dup 2)
19590         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19591                       (match_dup 5)
19592                       (match_dup 7)))
19593    (set (match_dup 3)
19594         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19595                       (match_dup 6)
19596                       (match_dup 8)))]
19597   "split_di (operands+2, 1, operands+5, operands+6);
19598    split_di (operands+3, 1, operands+7, operands+8);
19599    split_di (operands, 1, operands+2, operands+3);")
19600
19601 (define_expand "movxfcc"
19602   [(set (match_operand:XF 0 "register_operand" "")
19603         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19604                          (match_operand:XF 2 "register_operand" "")
19605                          (match_operand:XF 3 "register_operand" "")))]
19606   "TARGET_80387 && TARGET_CMOVE"
19607   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19608
19609 (define_insn "*movxfcc_1"
19610   [(set (match_operand:XF 0 "register_operand" "=f,f")
19611         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19612                                 [(reg FLAGS_REG) (const_int 0)])
19613                       (match_operand:XF 2 "register_operand" "f,0")
19614                       (match_operand:XF 3 "register_operand" "0,f")))]
19615   "TARGET_80387 && TARGET_CMOVE"
19616   "@
19617    fcmov%F1\t{%2, %0|%0, %2}
19618    fcmov%f1\t{%3, %0|%0, %3}"
19619   [(set_attr "type" "fcmov")
19620    (set_attr "mode" "XF")])
19621
19622 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19623 ;; the scalar versions to have only XMM registers as operands.
19624
19625 ;; SSE5 conditional move
19626 (define_insn "*sse5_pcmov_<mode>"
19627   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19628         (if_then_else:MODEF
19629           (match_operand:MODEF 1 "register_operand" "x,0")
19630           (match_operand:MODEF 2 "register_operand" "0,x")
19631           (match_operand:MODEF 3 "register_operand" "x,x")))]
19632   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19633   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19634   [(set_attr "type" "sse4arg")])
19635
19636 ;; These versions of the min/max patterns are intentionally ignorant of
19637 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19638 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19639 ;; are undefined in this condition, we're certain this is correct.
19640
19641 (define_insn "sminsf3"
19642   [(set (match_operand:SF 0 "register_operand" "=x")
19643         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19644                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19645   "TARGET_SSE_MATH"
19646   "minss\t{%2, %0|%0, %2}"
19647   [(set_attr "type" "sseadd")
19648    (set_attr "mode" "SF")])
19649
19650 (define_insn "smaxsf3"
19651   [(set (match_operand:SF 0 "register_operand" "=x")
19652         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19653                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19654   "TARGET_SSE_MATH"
19655   "maxss\t{%2, %0|%0, %2}"
19656   [(set_attr "type" "sseadd")
19657    (set_attr "mode" "SF")])
19658
19659 (define_insn "smindf3"
19660   [(set (match_operand:DF 0 "register_operand" "=x")
19661         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19662                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19663   "TARGET_SSE2 && TARGET_SSE_MATH"
19664   "minsd\t{%2, %0|%0, %2}"
19665   [(set_attr "type" "sseadd")
19666    (set_attr "mode" "DF")])
19667
19668 (define_insn "smaxdf3"
19669   [(set (match_operand:DF 0 "register_operand" "=x")
19670         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19671                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19672   "TARGET_SSE2 && TARGET_SSE_MATH"
19673   "maxsd\t{%2, %0|%0, %2}"
19674   [(set_attr "type" "sseadd")
19675    (set_attr "mode" "DF")])
19676
19677 ;; These versions of the min/max patterns implement exactly the operations
19678 ;;   min = (op1 < op2 ? op1 : op2)
19679 ;;   max = (!(op1 < op2) ? op1 : op2)
19680 ;; Their operands are not commutative, and thus they may be used in the
19681 ;; presence of -0.0 and NaN.
19682
19683 (define_insn "*ieee_sminsf3"
19684   [(set (match_operand:SF 0 "register_operand" "=x")
19685         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19686                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19687                    UNSPEC_IEEE_MIN))]
19688   "TARGET_SSE_MATH"
19689   "minss\t{%2, %0|%0, %2}"
19690   [(set_attr "type" "sseadd")
19691    (set_attr "mode" "SF")])
19692
19693 (define_insn "*ieee_smaxsf3"
19694   [(set (match_operand:SF 0 "register_operand" "=x")
19695         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19696                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19697                    UNSPEC_IEEE_MAX))]
19698   "TARGET_SSE_MATH"
19699   "maxss\t{%2, %0|%0, %2}"
19700   [(set_attr "type" "sseadd")
19701    (set_attr "mode" "SF")])
19702
19703 (define_insn "*ieee_smindf3"
19704   [(set (match_operand:DF 0 "register_operand" "=x")
19705         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19706                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19707                    UNSPEC_IEEE_MIN))]
19708   "TARGET_SSE2 && TARGET_SSE_MATH"
19709   "minsd\t{%2, %0|%0, %2}"
19710   [(set_attr "type" "sseadd")
19711    (set_attr "mode" "DF")])
19712
19713 (define_insn "*ieee_smaxdf3"
19714   [(set (match_operand:DF 0 "register_operand" "=x")
19715         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19716                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19717                    UNSPEC_IEEE_MAX))]
19718   "TARGET_SSE2 && TARGET_SSE_MATH"
19719   "maxsd\t{%2, %0|%0, %2}"
19720   [(set_attr "type" "sseadd")
19721    (set_attr "mode" "DF")])
19722
19723 ;; Make two stack loads independent:
19724 ;;   fld aa              fld aa
19725 ;;   fld %st(0)     ->   fld bb
19726 ;;   fmul bb             fmul %st(1), %st
19727 ;;
19728 ;; Actually we only match the last two instructions for simplicity.
19729 (define_peephole2
19730   [(set (match_operand 0 "fp_register_operand" "")
19731         (match_operand 1 "fp_register_operand" ""))
19732    (set (match_dup 0)
19733         (match_operator 2 "binary_fp_operator"
19734            [(match_dup 0)
19735             (match_operand 3 "memory_operand" "")]))]
19736   "REGNO (operands[0]) != REGNO (operands[1])"
19737   [(set (match_dup 0) (match_dup 3))
19738    (set (match_dup 0) (match_dup 4))]
19739
19740   ;; The % modifier is not operational anymore in peephole2's, so we have to
19741   ;; swap the operands manually in the case of addition and multiplication.
19742   "if (COMMUTATIVE_ARITH_P (operands[2]))
19743      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19744                                  operands[0], operands[1]);
19745    else
19746      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19747                                  operands[1], operands[0]);")
19748
19749 ;; Conditional addition patterns
19750 (define_expand "addqicc"
19751   [(match_operand:QI 0 "register_operand" "")
19752    (match_operand 1 "comparison_operator" "")
19753    (match_operand:QI 2 "register_operand" "")
19754    (match_operand:QI 3 "const_int_operand" "")]
19755   ""
19756   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19757
19758 (define_expand "addhicc"
19759   [(match_operand:HI 0 "register_operand" "")
19760    (match_operand 1 "comparison_operator" "")
19761    (match_operand:HI 2 "register_operand" "")
19762    (match_operand:HI 3 "const_int_operand" "")]
19763   ""
19764   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19765
19766 (define_expand "addsicc"
19767   [(match_operand:SI 0 "register_operand" "")
19768    (match_operand 1 "comparison_operator" "")
19769    (match_operand:SI 2 "register_operand" "")
19770    (match_operand:SI 3 "const_int_operand" "")]
19771   ""
19772   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19773
19774 (define_expand "adddicc"
19775   [(match_operand:DI 0 "register_operand" "")
19776    (match_operand 1 "comparison_operator" "")
19777    (match_operand:DI 2 "register_operand" "")
19778    (match_operand:DI 3 "const_int_operand" "")]
19779   "TARGET_64BIT"
19780   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19781
19782 \f
19783 ;; Misc patterns (?)
19784
19785 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19786 ;; Otherwise there will be nothing to keep
19787 ;;
19788 ;; [(set (reg ebp) (reg esp))]
19789 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19790 ;;  (clobber (eflags)]
19791 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19792 ;;
19793 ;; in proper program order.
19794 (define_insn "pro_epilogue_adjust_stack_1"
19795   [(set (match_operand:SI 0 "register_operand" "=r,r")
19796         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19797                  (match_operand:SI 2 "immediate_operand" "i,i")))
19798    (clobber (reg:CC FLAGS_REG))
19799    (clobber (mem:BLK (scratch)))]
19800   "!TARGET_64BIT"
19801 {
19802   switch (get_attr_type (insn))
19803     {
19804     case TYPE_IMOV:
19805       return "mov{l}\t{%1, %0|%0, %1}";
19806
19807     case TYPE_ALU:
19808       if (CONST_INT_P (operands[2])
19809           && (INTVAL (operands[2]) == 128
19810               || (INTVAL (operands[2]) < 0
19811                   && INTVAL (operands[2]) != -128)))
19812         {
19813           operands[2] = GEN_INT (-INTVAL (operands[2]));
19814           return "sub{l}\t{%2, %0|%0, %2}";
19815         }
19816       return "add{l}\t{%2, %0|%0, %2}";
19817
19818     case TYPE_LEA:
19819       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19820       return "lea{l}\t{%a2, %0|%0, %a2}";
19821
19822     default:
19823       gcc_unreachable ();
19824     }
19825 }
19826   [(set (attr "type")
19827         (cond [(eq_attr "alternative" "0")
19828                  (const_string "alu")
19829                (match_operand:SI 2 "const0_operand" "")
19830                  (const_string "imov")
19831               ]
19832               (const_string "lea")))
19833    (set_attr "mode" "SI")])
19834
19835 (define_insn "pro_epilogue_adjust_stack_rex64"
19836   [(set (match_operand:DI 0 "register_operand" "=r,r")
19837         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19838                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19839    (clobber (reg:CC FLAGS_REG))
19840    (clobber (mem:BLK (scratch)))]
19841   "TARGET_64BIT"
19842 {
19843   switch (get_attr_type (insn))
19844     {
19845     case TYPE_IMOV:
19846       return "mov{q}\t{%1, %0|%0, %1}";
19847
19848     case TYPE_ALU:
19849       if (CONST_INT_P (operands[2])
19850           /* Avoid overflows.  */
19851           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19852           && (INTVAL (operands[2]) == 128
19853               || (INTVAL (operands[2]) < 0
19854                   && INTVAL (operands[2]) != -128)))
19855         {
19856           operands[2] = GEN_INT (-INTVAL (operands[2]));
19857           return "sub{q}\t{%2, %0|%0, %2}";
19858         }
19859       return "add{q}\t{%2, %0|%0, %2}";
19860
19861     case TYPE_LEA:
19862       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19863       return "lea{q}\t{%a2, %0|%0, %a2}";
19864
19865     default:
19866       gcc_unreachable ();
19867     }
19868 }
19869   [(set (attr "type")
19870         (cond [(eq_attr "alternative" "0")
19871                  (const_string "alu")
19872                (match_operand:DI 2 "const0_operand" "")
19873                  (const_string "imov")
19874               ]
19875               (const_string "lea")))
19876    (set_attr "mode" "DI")])
19877
19878 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19879   [(set (match_operand:DI 0 "register_operand" "=r,r")
19880         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19881                  (match_operand:DI 3 "immediate_operand" "i,i")))
19882    (use (match_operand:DI 2 "register_operand" "r,r"))
19883    (clobber (reg:CC FLAGS_REG))
19884    (clobber (mem:BLK (scratch)))]
19885   "TARGET_64BIT"
19886 {
19887   switch (get_attr_type (insn))
19888     {
19889     case TYPE_ALU:
19890       return "add{q}\t{%2, %0|%0, %2}";
19891
19892     case TYPE_LEA:
19893       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19894       return "lea{q}\t{%a2, %0|%0, %a2}";
19895
19896     default:
19897       gcc_unreachable ();
19898     }
19899 }
19900   [(set_attr "type" "alu,lea")
19901    (set_attr "mode" "DI")])
19902
19903 (define_insn "allocate_stack_worker_32"
19904   [(set (match_operand:SI 0 "register_operand" "+a")
19905         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19906    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19907    (clobber (reg:CC FLAGS_REG))]
19908   "!TARGET_64BIT && TARGET_STACK_PROBE"
19909   "call\t__alloca"
19910   [(set_attr "type" "multi")
19911    (set_attr "length" "5")])
19912
19913 (define_insn "allocate_stack_worker_64"
19914   [(set (match_operand:DI 0 "register_operand" "=a")
19915         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19916    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19917    (clobber (reg:DI R10_REG))
19918    (clobber (reg:DI R11_REG))
19919    (clobber (reg:CC FLAGS_REG))]
19920   "TARGET_64BIT && TARGET_STACK_PROBE"
19921   "call\t___chkstk"
19922   [(set_attr "type" "multi")
19923    (set_attr "length" "5")])
19924
19925 (define_expand "allocate_stack"
19926   [(match_operand 0 "register_operand" "")
19927    (match_operand 1 "general_operand" "")]
19928   "TARGET_STACK_PROBE"
19929 {
19930   rtx x;
19931
19932 #ifndef CHECK_STACK_LIMIT
19933 #define CHECK_STACK_LIMIT 0
19934 #endif
19935
19936   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19937       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19938     {
19939       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19940                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19941       if (x != stack_pointer_rtx)
19942         emit_move_insn (stack_pointer_rtx, x);
19943     }
19944   else
19945     {
19946       x = copy_to_mode_reg (Pmode, operands[1]);
19947       if (TARGET_64BIT)
19948         x = gen_allocate_stack_worker_64 (x);
19949       else
19950         x = gen_allocate_stack_worker_32 (x);
19951       emit_insn (x);
19952     }
19953
19954   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19955   DONE;
19956 })
19957
19958 (define_expand "builtin_setjmp_receiver"
19959   [(label_ref (match_operand 0 "" ""))]
19960   "!TARGET_64BIT && flag_pic"
19961 {
19962   if (TARGET_MACHO)
19963     {
19964       rtx xops[3];
19965       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19966       rtx label_rtx = gen_label_rtx ();
19967       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19968       xops[0] = xops[1] = picreg;
19969       xops[2] = gen_rtx_CONST (SImode,
19970                   gen_rtx_MINUS (SImode,
19971                     gen_rtx_LABEL_REF (SImode, label_rtx),
19972                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19973       ix86_expand_binary_operator (MINUS, SImode, xops);
19974     }
19975   else
19976     emit_insn (gen_set_got (pic_offset_table_rtx));
19977   DONE;
19978 })
19979 \f
19980 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19981
19982 (define_split
19983   [(set (match_operand 0 "register_operand" "")
19984         (match_operator 3 "promotable_binary_operator"
19985            [(match_operand 1 "register_operand" "")
19986             (match_operand 2 "aligned_operand" "")]))
19987    (clobber (reg:CC FLAGS_REG))]
19988   "! TARGET_PARTIAL_REG_STALL && reload_completed
19989    && ((GET_MODE (operands[0]) == HImode
19990         && ((!optimize_size && !TARGET_FAST_PREFIX)
19991             /* ??? next two lines just !satisfies_constraint_K (...) */
19992             || !CONST_INT_P (operands[2])
19993             || satisfies_constraint_K (operands[2])))
19994        || (GET_MODE (operands[0]) == QImode
19995            && (TARGET_PROMOTE_QImode || optimize_size)))"
19996   [(parallel [(set (match_dup 0)
19997                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19998               (clobber (reg:CC FLAGS_REG))])]
19999   "operands[0] = gen_lowpart (SImode, operands[0]);
20000    operands[1] = gen_lowpart (SImode, operands[1]);
20001    if (GET_CODE (operands[3]) != ASHIFT)
20002      operands[2] = gen_lowpart (SImode, operands[2]);
20003    PUT_MODE (operands[3], SImode);")
20004
20005 ; Promote the QImode tests, as i386 has encoding of the AND
20006 ; instruction with 32-bit sign-extended immediate and thus the
20007 ; instruction size is unchanged, except in the %eax case for
20008 ; which it is increased by one byte, hence the ! optimize_size.
20009 (define_split
20010   [(set (match_operand 0 "flags_reg_operand" "")
20011         (match_operator 2 "compare_operator"
20012           [(and (match_operand 3 "aligned_operand" "")
20013                 (match_operand 4 "const_int_operand" ""))
20014            (const_int 0)]))
20015    (set (match_operand 1 "register_operand" "")
20016         (and (match_dup 3) (match_dup 4)))]
20017   "! TARGET_PARTIAL_REG_STALL && reload_completed
20018    && ! optimize_size
20019    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20020        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20021    /* Ensure that the operand will remain sign-extended immediate.  */
20022    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20023   [(parallel [(set (match_dup 0)
20024                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20025                                     (const_int 0)]))
20026               (set (match_dup 1)
20027                    (and:SI (match_dup 3) (match_dup 4)))])]
20028 {
20029   operands[4]
20030     = gen_int_mode (INTVAL (operands[4])
20031                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20032   operands[1] = gen_lowpart (SImode, operands[1]);
20033   operands[3] = gen_lowpart (SImode, operands[3]);
20034 })
20035
20036 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20037 ; the TEST instruction with 32-bit sign-extended immediate and thus
20038 ; the instruction size would at least double, which is not what we
20039 ; want even with ! optimize_size.
20040 (define_split
20041   [(set (match_operand 0 "flags_reg_operand" "")
20042         (match_operator 1 "compare_operator"
20043           [(and (match_operand:HI 2 "aligned_operand" "")
20044                 (match_operand:HI 3 "const_int_operand" ""))
20045            (const_int 0)]))]
20046   "! TARGET_PARTIAL_REG_STALL && reload_completed
20047    && ! TARGET_FAST_PREFIX
20048    && ! optimize_size
20049    /* Ensure that the operand will remain sign-extended immediate.  */
20050    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20051   [(set (match_dup 0)
20052         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20053                          (const_int 0)]))]
20054 {
20055   operands[3]
20056     = gen_int_mode (INTVAL (operands[3])
20057                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20058   operands[2] = gen_lowpart (SImode, operands[2]);
20059 })
20060
20061 (define_split
20062   [(set (match_operand 0 "register_operand" "")
20063         (neg (match_operand 1 "register_operand" "")))
20064    (clobber (reg:CC FLAGS_REG))]
20065   "! TARGET_PARTIAL_REG_STALL && reload_completed
20066    && (GET_MODE (operands[0]) == HImode
20067        || (GET_MODE (operands[0]) == QImode
20068            && (TARGET_PROMOTE_QImode || optimize_size)))"
20069   [(parallel [(set (match_dup 0)
20070                    (neg:SI (match_dup 1)))
20071               (clobber (reg:CC FLAGS_REG))])]
20072   "operands[0] = gen_lowpart (SImode, operands[0]);
20073    operands[1] = gen_lowpart (SImode, operands[1]);")
20074
20075 (define_split
20076   [(set (match_operand 0 "register_operand" "")
20077         (not (match_operand 1 "register_operand" "")))]
20078   "! TARGET_PARTIAL_REG_STALL && reload_completed
20079    && (GET_MODE (operands[0]) == HImode
20080        || (GET_MODE (operands[0]) == QImode
20081            && (TARGET_PROMOTE_QImode || optimize_size)))"
20082   [(set (match_dup 0)
20083         (not:SI (match_dup 1)))]
20084   "operands[0] = gen_lowpart (SImode, operands[0]);
20085    operands[1] = gen_lowpart (SImode, operands[1]);")
20086
20087 (define_split
20088   [(set (match_operand 0 "register_operand" "")
20089         (if_then_else (match_operator 1 "comparison_operator"
20090                                 [(reg FLAGS_REG) (const_int 0)])
20091                       (match_operand 2 "register_operand" "")
20092                       (match_operand 3 "register_operand" "")))]
20093   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20094    && (GET_MODE (operands[0]) == HImode
20095        || (GET_MODE (operands[0]) == QImode
20096            && (TARGET_PROMOTE_QImode || optimize_size)))"
20097   [(set (match_dup 0)
20098         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20099   "operands[0] = gen_lowpart (SImode, operands[0]);
20100    operands[2] = gen_lowpart (SImode, operands[2]);
20101    operands[3] = gen_lowpart (SImode, operands[3]);")
20102
20103 \f
20104 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20105 ;; transform a complex memory operation into two memory to register operations.
20106
20107 ;; Don't push memory operands
20108 (define_peephole2
20109   [(set (match_operand:SI 0 "push_operand" "")
20110         (match_operand:SI 1 "memory_operand" ""))
20111    (match_scratch:SI 2 "r")]
20112   "!optimize_size && !TARGET_PUSH_MEMORY
20113    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20114   [(set (match_dup 2) (match_dup 1))
20115    (set (match_dup 0) (match_dup 2))]
20116   "")
20117
20118 (define_peephole2
20119   [(set (match_operand:DI 0 "push_operand" "")
20120         (match_operand:DI 1 "memory_operand" ""))
20121    (match_scratch:DI 2 "r")]
20122   "!optimize_size && !TARGET_PUSH_MEMORY
20123    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20124   [(set (match_dup 2) (match_dup 1))
20125    (set (match_dup 0) (match_dup 2))]
20126   "")
20127
20128 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20129 ;; SImode pushes.
20130 (define_peephole2
20131   [(set (match_operand:SF 0 "push_operand" "")
20132         (match_operand:SF 1 "memory_operand" ""))
20133    (match_scratch:SF 2 "r")]
20134   "!optimize_size && !TARGET_PUSH_MEMORY
20135    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20136   [(set (match_dup 2) (match_dup 1))
20137    (set (match_dup 0) (match_dup 2))]
20138   "")
20139
20140 (define_peephole2
20141   [(set (match_operand:HI 0 "push_operand" "")
20142         (match_operand:HI 1 "memory_operand" ""))
20143    (match_scratch:HI 2 "r")]
20144   "!optimize_size && !TARGET_PUSH_MEMORY
20145    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20146   [(set (match_dup 2) (match_dup 1))
20147    (set (match_dup 0) (match_dup 2))]
20148   "")
20149
20150 (define_peephole2
20151   [(set (match_operand:QI 0 "push_operand" "")
20152         (match_operand:QI 1 "memory_operand" ""))
20153    (match_scratch:QI 2 "q")]
20154   "!optimize_size && !TARGET_PUSH_MEMORY
20155    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20156   [(set (match_dup 2) (match_dup 1))
20157    (set (match_dup 0) (match_dup 2))]
20158   "")
20159
20160 ;; Don't move an immediate directly to memory when the instruction
20161 ;; gets too big.
20162 (define_peephole2
20163   [(match_scratch:SI 1 "r")
20164    (set (match_operand:SI 0 "memory_operand" "")
20165         (const_int 0))]
20166   "! optimize_size
20167    && ! TARGET_USE_MOV0
20168    && TARGET_SPLIT_LONG_MOVES
20169    && get_attr_length (insn) >= ix86_cost->large_insn
20170    && peep2_regno_dead_p (0, FLAGS_REG)"
20171   [(parallel [(set (match_dup 1) (const_int 0))
20172               (clobber (reg:CC FLAGS_REG))])
20173    (set (match_dup 0) (match_dup 1))]
20174   "")
20175
20176 (define_peephole2
20177   [(match_scratch:HI 1 "r")
20178    (set (match_operand:HI 0 "memory_operand" "")
20179         (const_int 0))]
20180   "! optimize_size
20181    && ! TARGET_USE_MOV0
20182    && TARGET_SPLIT_LONG_MOVES
20183    && get_attr_length (insn) >= ix86_cost->large_insn
20184    && peep2_regno_dead_p (0, FLAGS_REG)"
20185   [(parallel [(set (match_dup 2) (const_int 0))
20186               (clobber (reg:CC FLAGS_REG))])
20187    (set (match_dup 0) (match_dup 1))]
20188   "operands[2] = gen_lowpart (SImode, operands[1]);")
20189
20190 (define_peephole2
20191   [(match_scratch:QI 1 "q")
20192    (set (match_operand:QI 0 "memory_operand" "")
20193         (const_int 0))]
20194   "! optimize_size
20195    && ! TARGET_USE_MOV0
20196    && TARGET_SPLIT_LONG_MOVES
20197    && get_attr_length (insn) >= ix86_cost->large_insn
20198    && peep2_regno_dead_p (0, FLAGS_REG)"
20199   [(parallel [(set (match_dup 2) (const_int 0))
20200               (clobber (reg:CC FLAGS_REG))])
20201    (set (match_dup 0) (match_dup 1))]
20202   "operands[2] = gen_lowpart (SImode, operands[1]);")
20203
20204 (define_peephole2
20205   [(match_scratch:SI 2 "r")
20206    (set (match_operand:SI 0 "memory_operand" "")
20207         (match_operand:SI 1 "immediate_operand" ""))]
20208   "! optimize_size
20209    && TARGET_SPLIT_LONG_MOVES
20210    && get_attr_length (insn) >= ix86_cost->large_insn"
20211   [(set (match_dup 2) (match_dup 1))
20212    (set (match_dup 0) (match_dup 2))]
20213   "")
20214
20215 (define_peephole2
20216   [(match_scratch:HI 2 "r")
20217    (set (match_operand:HI 0 "memory_operand" "")
20218         (match_operand:HI 1 "immediate_operand" ""))]
20219   "! optimize_size
20220    && TARGET_SPLIT_LONG_MOVES
20221    && get_attr_length (insn) >= ix86_cost->large_insn"
20222   [(set (match_dup 2) (match_dup 1))
20223    (set (match_dup 0) (match_dup 2))]
20224   "")
20225
20226 (define_peephole2
20227   [(match_scratch:QI 2 "q")
20228    (set (match_operand:QI 0 "memory_operand" "")
20229         (match_operand:QI 1 "immediate_operand" ""))]
20230   "! optimize_size
20231    && TARGET_SPLIT_LONG_MOVES
20232    && get_attr_length (insn) >= ix86_cost->large_insn"
20233   [(set (match_dup 2) (match_dup 1))
20234    (set (match_dup 0) (match_dup 2))]
20235   "")
20236
20237 ;; Don't compare memory with zero, load and use a test instead.
20238 (define_peephole2
20239   [(set (match_operand 0 "flags_reg_operand" "")
20240         (match_operator 1 "compare_operator"
20241           [(match_operand:SI 2 "memory_operand" "")
20242            (const_int 0)]))
20243    (match_scratch:SI 3 "r")]
20244   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20245   [(set (match_dup 3) (match_dup 2))
20246    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20247   "")
20248
20249 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20250 ;; Don't split NOTs with a displacement operand, because resulting XOR
20251 ;; will not be pairable anyway.
20252 ;;
20253 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20254 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20255 ;; so this split helps here as well.
20256 ;;
20257 ;; Note: Can't do this as a regular split because we can't get proper
20258 ;; lifetime information then.
20259
20260 (define_peephole2
20261   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20262         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20263   "!optimize_size
20264    && ((TARGET_NOT_UNPAIRABLE
20265         && (!MEM_P (operands[0])
20266             || !memory_displacement_operand (operands[0], SImode)))
20267        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20268    && peep2_regno_dead_p (0, FLAGS_REG)"
20269   [(parallel [(set (match_dup 0)
20270                    (xor:SI (match_dup 1) (const_int -1)))
20271               (clobber (reg:CC FLAGS_REG))])]
20272   "")
20273
20274 (define_peephole2
20275   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20276         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20277   "!optimize_size
20278    && ((TARGET_NOT_UNPAIRABLE
20279         && (!MEM_P (operands[0])
20280             || !memory_displacement_operand (operands[0], HImode)))
20281        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20282    && peep2_regno_dead_p (0, FLAGS_REG)"
20283   [(parallel [(set (match_dup 0)
20284                    (xor:HI (match_dup 1) (const_int -1)))
20285               (clobber (reg:CC FLAGS_REG))])]
20286   "")
20287
20288 (define_peephole2
20289   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20290         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20291   "!optimize_size
20292    && ((TARGET_NOT_UNPAIRABLE
20293         && (!MEM_P (operands[0])
20294             || !memory_displacement_operand (operands[0], QImode)))
20295        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20296    && peep2_regno_dead_p (0, FLAGS_REG)"
20297   [(parallel [(set (match_dup 0)
20298                    (xor:QI (match_dup 1) (const_int -1)))
20299               (clobber (reg:CC FLAGS_REG))])]
20300   "")
20301
20302 ;; Non pairable "test imm, reg" instructions can be translated to
20303 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20304 ;; byte opcode instead of two, have a short form for byte operands),
20305 ;; so do it for other CPUs as well.  Given that the value was dead,
20306 ;; this should not create any new dependencies.  Pass on the sub-word
20307 ;; versions if we're concerned about partial register stalls.
20308
20309 (define_peephole2
20310   [(set (match_operand 0 "flags_reg_operand" "")
20311         (match_operator 1 "compare_operator"
20312           [(and:SI (match_operand:SI 2 "register_operand" "")
20313                    (match_operand:SI 3 "immediate_operand" ""))
20314            (const_int 0)]))]
20315   "ix86_match_ccmode (insn, CCNOmode)
20316    && (true_regnum (operands[2]) != AX_REG
20317        || satisfies_constraint_K (operands[3]))
20318    && peep2_reg_dead_p (1, operands[2])"
20319   [(parallel
20320      [(set (match_dup 0)
20321            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20322                             (const_int 0)]))
20323       (set (match_dup 2)
20324            (and:SI (match_dup 2) (match_dup 3)))])]
20325   "")
20326
20327 ;; We don't need to handle HImode case, because it will be promoted to SImode
20328 ;; on ! TARGET_PARTIAL_REG_STALL
20329
20330 (define_peephole2
20331   [(set (match_operand 0 "flags_reg_operand" "")
20332         (match_operator 1 "compare_operator"
20333           [(and:QI (match_operand:QI 2 "register_operand" "")
20334                    (match_operand:QI 3 "immediate_operand" ""))
20335            (const_int 0)]))]
20336   "! TARGET_PARTIAL_REG_STALL
20337    && ix86_match_ccmode (insn, CCNOmode)
20338    && true_regnum (operands[2]) != AX_REG
20339    && peep2_reg_dead_p (1, operands[2])"
20340   [(parallel
20341      [(set (match_dup 0)
20342            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20343                             (const_int 0)]))
20344       (set (match_dup 2)
20345            (and:QI (match_dup 2) (match_dup 3)))])]
20346   "")
20347
20348 (define_peephole2
20349   [(set (match_operand 0 "flags_reg_operand" "")
20350         (match_operator 1 "compare_operator"
20351           [(and:SI
20352              (zero_extract:SI
20353                (match_operand 2 "ext_register_operand" "")
20354                (const_int 8)
20355                (const_int 8))
20356              (match_operand 3 "const_int_operand" ""))
20357            (const_int 0)]))]
20358   "! TARGET_PARTIAL_REG_STALL
20359    && ix86_match_ccmode (insn, CCNOmode)
20360    && true_regnum (operands[2]) != AX_REG
20361    && peep2_reg_dead_p (1, operands[2])"
20362   [(parallel [(set (match_dup 0)
20363                    (match_op_dup 1
20364                      [(and:SI
20365                         (zero_extract:SI
20366                           (match_dup 2)
20367                           (const_int 8)
20368                           (const_int 8))
20369                         (match_dup 3))
20370                       (const_int 0)]))
20371               (set (zero_extract:SI (match_dup 2)
20372                                     (const_int 8)
20373                                     (const_int 8))
20374                    (and:SI
20375                      (zero_extract:SI
20376                        (match_dup 2)
20377                        (const_int 8)
20378                        (const_int 8))
20379                      (match_dup 3)))])]
20380   "")
20381
20382 ;; Don't do logical operations with memory inputs.
20383 (define_peephole2
20384   [(match_scratch:SI 2 "r")
20385    (parallel [(set (match_operand:SI 0 "register_operand" "")
20386                    (match_operator:SI 3 "arith_or_logical_operator"
20387                      [(match_dup 0)
20388                       (match_operand:SI 1 "memory_operand" "")]))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "! optimize_size && ! TARGET_READ_MODIFY"
20391   [(set (match_dup 2) (match_dup 1))
20392    (parallel [(set (match_dup 0)
20393                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20394               (clobber (reg:CC FLAGS_REG))])]
20395   "")
20396
20397 (define_peephole2
20398   [(match_scratch:SI 2 "r")
20399    (parallel [(set (match_operand:SI 0 "register_operand" "")
20400                    (match_operator:SI 3 "arith_or_logical_operator"
20401                      [(match_operand:SI 1 "memory_operand" "")
20402                       (match_dup 0)]))
20403               (clobber (reg:CC FLAGS_REG))])]
20404   "! optimize_size && ! TARGET_READ_MODIFY"
20405   [(set (match_dup 2) (match_dup 1))
20406    (parallel [(set (match_dup 0)
20407                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20408               (clobber (reg:CC FLAGS_REG))])]
20409   "")
20410
20411 ; Don't do logical operations with memory outputs
20412 ;
20413 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20414 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20415 ; the same decoder scheduling characteristics as the original.
20416
20417 (define_peephole2
20418   [(match_scratch:SI 2 "r")
20419    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20420                    (match_operator:SI 3 "arith_or_logical_operator"
20421                      [(match_dup 0)
20422                       (match_operand:SI 1 "nonmemory_operand" "")]))
20423               (clobber (reg:CC FLAGS_REG))])]
20424   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20425   [(set (match_dup 2) (match_dup 0))
20426    (parallel [(set (match_dup 2)
20427                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20428               (clobber (reg:CC FLAGS_REG))])
20429    (set (match_dup 0) (match_dup 2))]
20430   "")
20431
20432 (define_peephole2
20433   [(match_scratch:SI 2 "r")
20434    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20435                    (match_operator:SI 3 "arith_or_logical_operator"
20436                      [(match_operand:SI 1 "nonmemory_operand" "")
20437                       (match_dup 0)]))
20438               (clobber (reg:CC FLAGS_REG))])]
20439   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20440   [(set (match_dup 2) (match_dup 0))
20441    (parallel [(set (match_dup 2)
20442                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20443               (clobber (reg:CC FLAGS_REG))])
20444    (set (match_dup 0) (match_dup 2))]
20445   "")
20446
20447 ;; Attempt to always use XOR for zeroing registers.
20448 (define_peephole2
20449   [(set (match_operand 0 "register_operand" "")
20450         (match_operand 1 "const0_operand" ""))]
20451   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20452    && (! TARGET_USE_MOV0 || optimize_size)
20453    && GENERAL_REG_P (operands[0])
20454    && peep2_regno_dead_p (0, FLAGS_REG)"
20455   [(parallel [(set (match_dup 0) (const_int 0))
20456               (clobber (reg:CC FLAGS_REG))])]
20457 {
20458   operands[0] = gen_lowpart (word_mode, operands[0]);
20459 })
20460
20461 (define_peephole2
20462   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20463         (const_int 0))]
20464   "(GET_MODE (operands[0]) == QImode
20465     || GET_MODE (operands[0]) == HImode)
20466    && (! TARGET_USE_MOV0 || optimize_size)
20467    && peep2_regno_dead_p (0, FLAGS_REG)"
20468   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20469               (clobber (reg:CC FLAGS_REG))])])
20470
20471 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20472 (define_peephole2
20473   [(set (match_operand 0 "register_operand" "")
20474         (const_int -1))]
20475   "(GET_MODE (operands[0]) == HImode
20476     || GET_MODE (operands[0]) == SImode
20477     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20478    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20479    && peep2_regno_dead_p (0, FLAGS_REG)"
20480   [(parallel [(set (match_dup 0) (const_int -1))
20481               (clobber (reg:CC FLAGS_REG))])]
20482   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20483                               operands[0]);")
20484
20485 ;; Attempt to convert simple leas to adds. These can be created by
20486 ;; move expanders.
20487 (define_peephole2
20488   [(set (match_operand:SI 0 "register_operand" "")
20489         (plus:SI (match_dup 0)
20490                  (match_operand:SI 1 "nonmemory_operand" "")))]
20491   "peep2_regno_dead_p (0, FLAGS_REG)"
20492   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20493               (clobber (reg:CC FLAGS_REG))])]
20494   "")
20495
20496 (define_peephole2
20497   [(set (match_operand:SI 0 "register_operand" "")
20498         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20499                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20500   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20501   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20502               (clobber (reg:CC FLAGS_REG))])]
20503   "operands[2] = gen_lowpart (SImode, operands[2]);")
20504
20505 (define_peephole2
20506   [(set (match_operand:DI 0 "register_operand" "")
20507         (plus:DI (match_dup 0)
20508                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20509   "peep2_regno_dead_p (0, FLAGS_REG)"
20510   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20511               (clobber (reg:CC FLAGS_REG))])]
20512   "")
20513
20514 (define_peephole2
20515   [(set (match_operand:SI 0 "register_operand" "")
20516         (mult:SI (match_dup 0)
20517                  (match_operand:SI 1 "const_int_operand" "")))]
20518   "exact_log2 (INTVAL (operands[1])) >= 0
20519    && peep2_regno_dead_p (0, FLAGS_REG)"
20520   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20521               (clobber (reg:CC FLAGS_REG))])]
20522   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20523
20524 (define_peephole2
20525   [(set (match_operand:DI 0 "register_operand" "")
20526         (mult:DI (match_dup 0)
20527                  (match_operand:DI 1 "const_int_operand" "")))]
20528   "exact_log2 (INTVAL (operands[1])) >= 0
20529    && peep2_regno_dead_p (0, FLAGS_REG)"
20530   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20531               (clobber (reg:CC FLAGS_REG))])]
20532   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20533
20534 (define_peephole2
20535   [(set (match_operand:SI 0 "register_operand" "")
20536         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20537                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20538   "exact_log2 (INTVAL (operands[2])) >= 0
20539    && REGNO (operands[0]) == REGNO (operands[1])
20540    && peep2_regno_dead_p (0, FLAGS_REG)"
20541   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20542               (clobber (reg:CC FLAGS_REG))])]
20543   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20544
20545 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20546 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20547 ;; many CPUs it is also faster, since special hardware to avoid esp
20548 ;; dependencies is present.
20549
20550 ;; While some of these conversions may be done using splitters, we use peepholes
20551 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20552
20553 ;; Convert prologue esp subtractions to push.
20554 ;; We need register to push.  In order to keep verify_flow_info happy we have
20555 ;; two choices
20556 ;; - use scratch and clobber it in order to avoid dependencies
20557 ;; - use already live register
20558 ;; We can't use the second way right now, since there is no reliable way how to
20559 ;; verify that given register is live.  First choice will also most likely in
20560 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20561 ;; call clobbered registers are dead.  We may want to use base pointer as an
20562 ;; alternative when no register is available later.
20563
20564 (define_peephole2
20565   [(match_scratch:SI 0 "r")
20566    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20567               (clobber (reg:CC FLAGS_REG))
20568               (clobber (mem:BLK (scratch)))])]
20569   "optimize_size || !TARGET_SUB_ESP_4"
20570   [(clobber (match_dup 0))
20571    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20572               (clobber (mem:BLK (scratch)))])])
20573
20574 (define_peephole2
20575   [(match_scratch:SI 0 "r")
20576    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20577               (clobber (reg:CC FLAGS_REG))
20578               (clobber (mem:BLK (scratch)))])]
20579   "optimize_size || !TARGET_SUB_ESP_8"
20580   [(clobber (match_dup 0))
20581    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20582    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20583               (clobber (mem:BLK (scratch)))])])
20584
20585 ;; Convert esp subtractions to push.
20586 (define_peephole2
20587   [(match_scratch:SI 0 "r")
20588    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20589               (clobber (reg:CC FLAGS_REG))])]
20590   "optimize_size || !TARGET_SUB_ESP_4"
20591   [(clobber (match_dup 0))
20592    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20593
20594 (define_peephole2
20595   [(match_scratch:SI 0 "r")
20596    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20597               (clobber (reg:CC FLAGS_REG))])]
20598   "optimize_size || !TARGET_SUB_ESP_8"
20599   [(clobber (match_dup 0))
20600    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20601    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20602
20603 ;; Convert epilogue deallocator to pop.
20604 (define_peephole2
20605   [(match_scratch:SI 0 "r")
20606    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607               (clobber (reg:CC FLAGS_REG))
20608               (clobber (mem:BLK (scratch)))])]
20609   "optimize_size || !TARGET_ADD_ESP_4"
20610   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20611               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20612               (clobber (mem:BLK (scratch)))])]
20613   "")
20614
20615 ;; Two pops case is tricky, since pop causes dependency on destination register.
20616 ;; We use two registers if available.
20617 (define_peephole2
20618   [(match_scratch:SI 0 "r")
20619    (match_scratch:SI 1 "r")
20620    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20621               (clobber (reg:CC FLAGS_REG))
20622               (clobber (mem:BLK (scratch)))])]
20623   "optimize_size || !TARGET_ADD_ESP_8"
20624   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20625               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20626               (clobber (mem:BLK (scratch)))])
20627    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20628               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20629   "")
20630
20631 (define_peephole2
20632   [(match_scratch:SI 0 "r")
20633    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20634               (clobber (reg:CC FLAGS_REG))
20635               (clobber (mem:BLK (scratch)))])]
20636   "optimize_size"
20637   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20638               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20639               (clobber (mem:BLK (scratch)))])
20640    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20641               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20642   "")
20643
20644 ;; Convert esp additions to pop.
20645 (define_peephole2
20646   [(match_scratch:SI 0 "r")
20647    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20648               (clobber (reg:CC FLAGS_REG))])]
20649   ""
20650   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20651               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20652   "")
20653
20654 ;; Two pops case is tricky, since pop causes dependency on destination register.
20655 ;; We use two registers if available.
20656 (define_peephole2
20657   [(match_scratch:SI 0 "r")
20658    (match_scratch:SI 1 "r")
20659    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20660               (clobber (reg:CC FLAGS_REG))])]
20661   ""
20662   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20663               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20664    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20665               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20666   "")
20667
20668 (define_peephole2
20669   [(match_scratch:SI 0 "r")
20670    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20671               (clobber (reg:CC FLAGS_REG))])]
20672   "optimize_size"
20673   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20674               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20675    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20676               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20677   "")
20678 \f
20679 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20680 ;; required and register dies.  Similarly for 128 to plus -128.
20681 (define_peephole2
20682   [(set (match_operand 0 "flags_reg_operand" "")
20683         (match_operator 1 "compare_operator"
20684           [(match_operand 2 "register_operand" "")
20685            (match_operand 3 "const_int_operand" "")]))]
20686   "(INTVAL (operands[3]) == -1
20687     || INTVAL (operands[3]) == 1
20688     || INTVAL (operands[3]) == 128)
20689    && ix86_match_ccmode (insn, CCGCmode)
20690    && peep2_reg_dead_p (1, operands[2])"
20691   [(parallel [(set (match_dup 0)
20692                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20693               (clobber (match_dup 2))])]
20694   "")
20695 \f
20696 (define_peephole2
20697   [(match_scratch:DI 0 "r")
20698    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20699               (clobber (reg:CC FLAGS_REG))
20700               (clobber (mem:BLK (scratch)))])]
20701   "optimize_size || !TARGET_SUB_ESP_4"
20702   [(clobber (match_dup 0))
20703    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20704               (clobber (mem:BLK (scratch)))])])
20705
20706 (define_peephole2
20707   [(match_scratch:DI 0 "r")
20708    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20709               (clobber (reg:CC FLAGS_REG))
20710               (clobber (mem:BLK (scratch)))])]
20711   "optimize_size || !TARGET_SUB_ESP_8"
20712   [(clobber (match_dup 0))
20713    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20714    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20715               (clobber (mem:BLK (scratch)))])])
20716
20717 ;; Convert esp subtractions to push.
20718 (define_peephole2
20719   [(match_scratch:DI 0 "r")
20720    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20721               (clobber (reg:CC FLAGS_REG))])]
20722   "optimize_size || !TARGET_SUB_ESP_4"
20723   [(clobber (match_dup 0))
20724    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20725
20726 (define_peephole2
20727   [(match_scratch:DI 0 "r")
20728    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20729               (clobber (reg:CC FLAGS_REG))])]
20730   "optimize_size || !TARGET_SUB_ESP_8"
20731   [(clobber (match_dup 0))
20732    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20733    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20734
20735 ;; Convert epilogue deallocator to pop.
20736 (define_peephole2
20737   [(match_scratch:DI 0 "r")
20738    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739               (clobber (reg:CC FLAGS_REG))
20740               (clobber (mem:BLK (scratch)))])]
20741   "optimize_size || !TARGET_ADD_ESP_4"
20742   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20743               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20744               (clobber (mem:BLK (scratch)))])]
20745   "")
20746
20747 ;; Two pops case is tricky, since pop causes dependency on destination register.
20748 ;; We use two registers if available.
20749 (define_peephole2
20750   [(match_scratch:DI 0 "r")
20751    (match_scratch:DI 1 "r")
20752    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20753               (clobber (reg:CC FLAGS_REG))
20754               (clobber (mem:BLK (scratch)))])]
20755   "optimize_size || !TARGET_ADD_ESP_8"
20756   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20757               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20758               (clobber (mem:BLK (scratch)))])
20759    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20760               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20761   "")
20762
20763 (define_peephole2
20764   [(match_scratch:DI 0 "r")
20765    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20766               (clobber (reg:CC FLAGS_REG))
20767               (clobber (mem:BLK (scratch)))])]
20768   "optimize_size"
20769   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20770               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20771               (clobber (mem:BLK (scratch)))])
20772    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20773               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20774   "")
20775
20776 ;; Convert esp additions to pop.
20777 (define_peephole2
20778   [(match_scratch:DI 0 "r")
20779    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20780               (clobber (reg:CC FLAGS_REG))])]
20781   ""
20782   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20783               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20784   "")
20785
20786 ;; Two pops case is tricky, since pop causes dependency on destination register.
20787 ;; We use two registers if available.
20788 (define_peephole2
20789   [(match_scratch:DI 0 "r")
20790    (match_scratch:DI 1 "r")
20791    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20792               (clobber (reg:CC FLAGS_REG))])]
20793   ""
20794   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20795               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20796    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20797               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20798   "")
20799
20800 (define_peephole2
20801   [(match_scratch:DI 0 "r")
20802    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20803               (clobber (reg:CC FLAGS_REG))])]
20804   "optimize_size"
20805   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20806               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20807    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20808               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20809   "")
20810 \f
20811 ;; Convert imul by three, five and nine into lea
20812 (define_peephole2
20813   [(parallel
20814     [(set (match_operand:SI 0 "register_operand" "")
20815           (mult:SI (match_operand:SI 1 "register_operand" "")
20816                    (match_operand:SI 2 "const_int_operand" "")))
20817      (clobber (reg:CC FLAGS_REG))])]
20818   "INTVAL (operands[2]) == 3
20819    || INTVAL (operands[2]) == 5
20820    || INTVAL (operands[2]) == 9"
20821   [(set (match_dup 0)
20822         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20823                  (match_dup 1)))]
20824   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20825
20826 (define_peephole2
20827   [(parallel
20828     [(set (match_operand:SI 0 "register_operand" "")
20829           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20830                    (match_operand:SI 2 "const_int_operand" "")))
20831      (clobber (reg:CC FLAGS_REG))])]
20832   "!optimize_size
20833    && (INTVAL (operands[2]) == 3
20834        || INTVAL (operands[2]) == 5
20835        || INTVAL (operands[2]) == 9)"
20836   [(set (match_dup 0) (match_dup 1))
20837    (set (match_dup 0)
20838         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20839                  (match_dup 0)))]
20840   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20841
20842 (define_peephole2
20843   [(parallel
20844     [(set (match_operand:DI 0 "register_operand" "")
20845           (mult:DI (match_operand:DI 1 "register_operand" "")
20846                    (match_operand:DI 2 "const_int_operand" "")))
20847      (clobber (reg:CC FLAGS_REG))])]
20848   "TARGET_64BIT
20849    && (INTVAL (operands[2]) == 3
20850        || INTVAL (operands[2]) == 5
20851        || INTVAL (operands[2]) == 9)"
20852   [(set (match_dup 0)
20853         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20854                  (match_dup 1)))]
20855   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20856
20857 (define_peephole2
20858   [(parallel
20859     [(set (match_operand:DI 0 "register_operand" "")
20860           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20861                    (match_operand:DI 2 "const_int_operand" "")))
20862      (clobber (reg:CC FLAGS_REG))])]
20863   "TARGET_64BIT
20864    && !optimize_size
20865    && (INTVAL (operands[2]) == 3
20866        || INTVAL (operands[2]) == 5
20867        || INTVAL (operands[2]) == 9)"
20868   [(set (match_dup 0) (match_dup 1))
20869    (set (match_dup 0)
20870         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20871                  (match_dup 0)))]
20872   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20873
20874 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20875 ;; imul $32bit_imm, reg, reg is direct decoded.
20876 (define_peephole2
20877   [(match_scratch:DI 3 "r")
20878    (parallel [(set (match_operand:DI 0 "register_operand" "")
20879                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20880                             (match_operand:DI 2 "immediate_operand" "")))
20881               (clobber (reg:CC FLAGS_REG))])]
20882   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20883    && !satisfies_constraint_K (operands[2])"
20884   [(set (match_dup 3) (match_dup 1))
20885    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20886               (clobber (reg:CC FLAGS_REG))])]
20887 "")
20888
20889 (define_peephole2
20890   [(match_scratch:SI 3 "r")
20891    (parallel [(set (match_operand:SI 0 "register_operand" "")
20892                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20893                             (match_operand:SI 2 "immediate_operand" "")))
20894               (clobber (reg:CC FLAGS_REG))])]
20895   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20896    && !satisfies_constraint_K (operands[2])"
20897   [(set (match_dup 3) (match_dup 1))
20898    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20899               (clobber (reg:CC FLAGS_REG))])]
20900 "")
20901
20902 (define_peephole2
20903   [(match_scratch:SI 3 "r")
20904    (parallel [(set (match_operand:DI 0 "register_operand" "")
20905                    (zero_extend:DI
20906                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20907                               (match_operand:SI 2 "immediate_operand" ""))))
20908               (clobber (reg:CC FLAGS_REG))])]
20909   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20910    && !satisfies_constraint_K (operands[2])"
20911   [(set (match_dup 3) (match_dup 1))
20912    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20913               (clobber (reg:CC FLAGS_REG))])]
20914 "")
20915
20916 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20917 ;; Convert it into imul reg, reg
20918 ;; It would be better to force assembler to encode instruction using long
20919 ;; immediate, but there is apparently no way to do so.
20920 (define_peephole2
20921   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20922                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20923                             (match_operand:DI 2 "const_int_operand" "")))
20924               (clobber (reg:CC FLAGS_REG))])
20925    (match_scratch:DI 3 "r")]
20926   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20927    && satisfies_constraint_K (operands[2])"
20928   [(set (match_dup 3) (match_dup 2))
20929    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20930               (clobber (reg:CC FLAGS_REG))])]
20931 {
20932   if (!rtx_equal_p (operands[0], operands[1]))
20933     emit_move_insn (operands[0], operands[1]);
20934 })
20935
20936 (define_peephole2
20937   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20938                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20939                             (match_operand:SI 2 "const_int_operand" "")))
20940               (clobber (reg:CC FLAGS_REG))])
20941    (match_scratch:SI 3 "r")]
20942   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20943    && satisfies_constraint_K (operands[2])"
20944   [(set (match_dup 3) (match_dup 2))
20945    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20946               (clobber (reg:CC FLAGS_REG))])]
20947 {
20948   if (!rtx_equal_p (operands[0], operands[1]))
20949     emit_move_insn (operands[0], operands[1]);
20950 })
20951
20952 (define_peephole2
20953   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20954                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20955                             (match_operand:HI 2 "immediate_operand" "")))
20956               (clobber (reg:CC FLAGS_REG))])
20957    (match_scratch:HI 3 "r")]
20958   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20959   [(set (match_dup 3) (match_dup 2))
20960    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20961               (clobber (reg:CC FLAGS_REG))])]
20962 {
20963   if (!rtx_equal_p (operands[0], operands[1]))
20964     emit_move_insn (operands[0], operands[1]);
20965 })
20966
20967 ;; After splitting up read-modify operations, array accesses with memory
20968 ;; operands might end up in form:
20969 ;;  sall    $2, %eax
20970 ;;  movl    4(%esp), %edx
20971 ;;  addl    %edx, %eax
20972 ;; instead of pre-splitting:
20973 ;;  sall    $2, %eax
20974 ;;  addl    4(%esp), %eax
20975 ;; Turn it into:
20976 ;;  movl    4(%esp), %edx
20977 ;;  leal    (%edx,%eax,4), %eax
20978
20979 (define_peephole2
20980   [(parallel [(set (match_operand 0 "register_operand" "")
20981                    (ashift (match_operand 1 "register_operand" "")
20982                            (match_operand 2 "const_int_operand" "")))
20983                (clobber (reg:CC FLAGS_REG))])
20984    (set (match_operand 3 "register_operand")
20985         (match_operand 4 "x86_64_general_operand" ""))
20986    (parallel [(set (match_operand 5 "register_operand" "")
20987                    (plus (match_operand 6 "register_operand" "")
20988                          (match_operand 7 "register_operand" "")))
20989                    (clobber (reg:CC FLAGS_REG))])]
20990   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20991    /* Validate MODE for lea.  */
20992    && ((!TARGET_PARTIAL_REG_STALL
20993         && (GET_MODE (operands[0]) == QImode
20994             || GET_MODE (operands[0]) == HImode))
20995        || GET_MODE (operands[0]) == SImode
20996        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20997    /* We reorder load and the shift.  */
20998    && !rtx_equal_p (operands[1], operands[3])
20999    && !reg_overlap_mentioned_p (operands[0], operands[4])
21000    /* Last PLUS must consist of operand 0 and 3.  */
21001    && !rtx_equal_p (operands[0], operands[3])
21002    && (rtx_equal_p (operands[3], operands[6])
21003        || rtx_equal_p (operands[3], operands[7]))
21004    && (rtx_equal_p (operands[0], operands[6])
21005        || rtx_equal_p (operands[0], operands[7]))
21006    /* The intermediate operand 0 must die or be same as output.  */
21007    && (rtx_equal_p (operands[0], operands[5])
21008        || peep2_reg_dead_p (3, operands[0]))"
21009   [(set (match_dup 3) (match_dup 4))
21010    (set (match_dup 0) (match_dup 1))]
21011 {
21012   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21013   int scale = 1 << INTVAL (operands[2]);
21014   rtx index = gen_lowpart (Pmode, operands[1]);
21015   rtx base = gen_lowpart (Pmode, operands[3]);
21016   rtx dest = gen_lowpart (mode, operands[5]);
21017
21018   operands[1] = gen_rtx_PLUS (Pmode, base,
21019                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21020   if (mode != Pmode)
21021     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21022   operands[0] = dest;
21023 })
21024 \f
21025 ;; Call-value patterns last so that the wildcard operand does not
21026 ;; disrupt insn-recog's switch tables.
21027
21028 (define_insn "*call_value_pop_0"
21029   [(set (match_operand 0 "" "")
21030         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21031               (match_operand:SI 2 "" "")))
21032    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21033                             (match_operand:SI 3 "immediate_operand" "")))]
21034   "!TARGET_64BIT"
21035 {
21036   if (SIBLING_CALL_P (insn))
21037     return "jmp\t%P1";
21038   else
21039     return "call\t%P1";
21040 }
21041   [(set_attr "type" "callv")])
21042
21043 (define_insn "*call_value_pop_1"
21044   [(set (match_operand 0 "" "")
21045         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21046               (match_operand:SI 2 "" "")))
21047    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21048                             (match_operand:SI 3 "immediate_operand" "i")))]
21049   "!TARGET_64BIT"
21050 {
21051   if (constant_call_address_operand (operands[1], Pmode))
21052     {
21053       if (SIBLING_CALL_P (insn))
21054         return "jmp\t%P1";
21055       else
21056         return "call\t%P1";
21057     }
21058   if (SIBLING_CALL_P (insn))
21059     return "jmp\t%A1";
21060   else
21061     return "call\t%A1";
21062 }
21063   [(set_attr "type" "callv")])
21064
21065 (define_insn "*call_value_0"
21066   [(set (match_operand 0 "" "")
21067         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21068               (match_operand:SI 2 "" "")))]
21069   "!TARGET_64BIT"
21070 {
21071   if (SIBLING_CALL_P (insn))
21072     return "jmp\t%P1";
21073   else
21074     return "call\t%P1";
21075 }
21076   [(set_attr "type" "callv")])
21077
21078 (define_insn "*call_value_0_rex64"
21079   [(set (match_operand 0 "" "")
21080         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21081               (match_operand:DI 2 "const_int_operand" "")))]
21082   "TARGET_64BIT"
21083 {
21084   if (SIBLING_CALL_P (insn))
21085     return "jmp\t%P1";
21086   else
21087     return "call\t%P1";
21088 }
21089   [(set_attr "type" "callv")])
21090
21091 (define_insn "*call_value_1"
21092   [(set (match_operand 0 "" "")
21093         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21094               (match_operand:SI 2 "" "")))]
21095   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21096 {
21097   if (constant_call_address_operand (operands[1], Pmode))
21098     return "call\t%P1";
21099   return "call\t%A1";
21100 }
21101   [(set_attr "type" "callv")])
21102
21103 (define_insn "*sibcall_value_1"
21104   [(set (match_operand 0 "" "")
21105         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21106               (match_operand:SI 2 "" "")))]
21107   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21108 {
21109   if (constant_call_address_operand (operands[1], Pmode))
21110     return "jmp\t%P1";
21111   return "jmp\t%A1";
21112 }
21113   [(set_attr "type" "callv")])
21114
21115 (define_insn "*call_value_1_rex64"
21116   [(set (match_operand 0 "" "")
21117         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21118               (match_operand:DI 2 "" "")))]
21119   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21120    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21121 {
21122   if (constant_call_address_operand (operands[1], Pmode))
21123     return "call\t%P1";
21124   return "call\t%A1";
21125 }
21126   [(set_attr "type" "callv")])
21127
21128 (define_insn "*call_value_1_rex64_large"
21129   [(set (match_operand 0 "" "")
21130         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21131               (match_operand:DI 2 "" "")))]
21132   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21133   "call\t%A1"
21134   [(set_attr "type" "callv")])
21135
21136 (define_insn "*sibcall_value_1_rex64"
21137   [(set (match_operand 0 "" "")
21138         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21139               (match_operand:DI 2 "" "")))]
21140   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21141   "jmp\t%P1"
21142   [(set_attr "type" "callv")])
21143
21144 (define_insn "*sibcall_value_1_rex64_v"
21145   [(set (match_operand 0 "" "")
21146         (call (mem:QI (reg:DI R11_REG))
21147               (match_operand:DI 1 "" "")))]
21148   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21149   "jmp\t{*%%}r11"
21150   [(set_attr "type" "callv")])
21151 \f
21152 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21153 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21154 ;; caught for use by garbage collectors and the like.  Using an insn that
21155 ;; maps to SIGILL makes it more likely the program will rightfully die.
21156 ;; Keeping with tradition, "6" is in honor of #UD.
21157 (define_insn "trap"
21158   [(trap_if (const_int 1) (const_int 6))]
21159   ""
21160   { return ASM_SHORT "0x0b0f"; }
21161   [(set_attr "length" "2")])
21162
21163 (define_expand "sse_prologue_save"
21164   [(parallel [(set (match_operand:BLK 0 "" "")
21165                    (unspec:BLK [(reg:DI 21)
21166                                 (reg:DI 22)
21167                                 (reg:DI 23)
21168                                 (reg:DI 24)
21169                                 (reg:DI 25)
21170                                 (reg:DI 26)
21171                                 (reg:DI 27)
21172                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21173               (use (match_operand:DI 1 "register_operand" ""))
21174               (use (match_operand:DI 2 "immediate_operand" ""))
21175               (use (label_ref:DI (match_operand 3 "" "")))])]
21176   "TARGET_64BIT"
21177   "")
21178
21179 (define_insn "*sse_prologue_save_insn"
21180   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21181                           (match_operand:DI 4 "const_int_operand" "n")))
21182         (unspec:BLK [(reg:DI 21)
21183                      (reg:DI 22)
21184                      (reg:DI 23)
21185                      (reg:DI 24)
21186                      (reg:DI 25)
21187                      (reg:DI 26)
21188                      (reg:DI 27)
21189                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21190    (use (match_operand:DI 1 "register_operand" "r"))
21191    (use (match_operand:DI 2 "const_int_operand" "i"))
21192    (use (label_ref:DI (match_operand 3 "" "X")))]
21193   "TARGET_64BIT
21194    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21195    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21196   "*
21197 {
21198   int i;
21199   operands[0] = gen_rtx_MEM (Pmode,
21200                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21201   output_asm_insn (\"jmp\\t%A1\", operands);
21202   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21203     {
21204       operands[4] = adjust_address (operands[0], DImode, i*16);
21205       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21206       PUT_MODE (operands[4], TImode);
21207       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21208         output_asm_insn (\"rex\", operands);
21209       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21210     }
21211   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21212                              CODE_LABEL_NUMBER (operands[3]));
21213   return \"\";
21214 }
21215   "
21216   [(set_attr "type" "other")
21217    (set_attr "length_immediate" "0")
21218    (set_attr "length_address" "0")
21219    (set_attr "length" "135")
21220    (set_attr "memory" "store")
21221    (set_attr "modrm" "0")
21222    (set_attr "mode" "DI")])
21223
21224 (define_expand "prefetch"
21225   [(prefetch (match_operand 0 "address_operand" "")
21226              (match_operand:SI 1 "const_int_operand" "")
21227              (match_operand:SI 2 "const_int_operand" ""))]
21228   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21229 {
21230   int rw = INTVAL (operands[1]);
21231   int locality = INTVAL (operands[2]);
21232
21233   gcc_assert (rw == 0 || rw == 1);
21234   gcc_assert (locality >= 0 && locality <= 3);
21235   gcc_assert (GET_MODE (operands[0]) == Pmode
21236               || GET_MODE (operands[0]) == VOIDmode);
21237
21238   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21239      supported by SSE counterpart or the SSE prefetch is not available
21240      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21241      of locality.  */
21242   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21243     operands[2] = GEN_INT (3);
21244   else
21245     operands[1] = const0_rtx;
21246 })
21247
21248 (define_insn "*prefetch_sse"
21249   [(prefetch (match_operand:SI 0 "address_operand" "p")
21250              (const_int 0)
21251              (match_operand:SI 1 "const_int_operand" ""))]
21252   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21253 {
21254   static const char * const patterns[4] = {
21255    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21256   };
21257
21258   int locality = INTVAL (operands[1]);
21259   gcc_assert (locality >= 0 && locality <= 3);
21260
21261   return patterns[locality];
21262 }
21263   [(set_attr "type" "sse")
21264    (set_attr "memory" "none")])
21265
21266 (define_insn "*prefetch_sse_rex"
21267   [(prefetch (match_operand:DI 0 "address_operand" "p")
21268              (const_int 0)
21269              (match_operand:SI 1 "const_int_operand" ""))]
21270   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21271 {
21272   static const char * const patterns[4] = {
21273    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21274   };
21275
21276   int locality = INTVAL (operands[1]);
21277   gcc_assert (locality >= 0 && locality <= 3);
21278
21279   return patterns[locality];
21280 }
21281   [(set_attr "type" "sse")
21282    (set_attr "memory" "none")])
21283
21284 (define_insn "*prefetch_3dnow"
21285   [(prefetch (match_operand:SI 0 "address_operand" "p")
21286              (match_operand:SI 1 "const_int_operand" "n")
21287              (const_int 3))]
21288   "TARGET_3DNOW && !TARGET_64BIT"
21289 {
21290   if (INTVAL (operands[1]) == 0)
21291     return "prefetch\t%a0";
21292   else
21293     return "prefetchw\t%a0";
21294 }
21295   [(set_attr "type" "mmx")
21296    (set_attr "memory" "none")])
21297
21298 (define_insn "*prefetch_3dnow_rex"
21299   [(prefetch (match_operand:DI 0 "address_operand" "p")
21300              (match_operand:SI 1 "const_int_operand" "n")
21301              (const_int 3))]
21302   "TARGET_3DNOW && TARGET_64BIT"
21303 {
21304   if (INTVAL (operands[1]) == 0)
21305     return "prefetch\t%a0";
21306   else
21307     return "prefetchw\t%a0";
21308 }
21309   [(set_attr "type" "mmx")
21310    (set_attr "memory" "none")])
21311
21312 (define_expand "stack_protect_set"
21313   [(match_operand 0 "memory_operand" "")
21314    (match_operand 1 "memory_operand" "")]
21315   ""
21316 {
21317 #ifdef TARGET_THREAD_SSP_OFFSET
21318   if (TARGET_64BIT)
21319     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21320                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21321   else
21322     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21323                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21324 #else
21325   if (TARGET_64BIT)
21326     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21327   else
21328     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21329 #endif
21330   DONE;
21331 })
21332
21333 (define_insn "stack_protect_set_si"
21334   [(set (match_operand:SI 0 "memory_operand" "=m")
21335         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21336    (set (match_scratch:SI 2 "=&r") (const_int 0))
21337    (clobber (reg:CC FLAGS_REG))]
21338   ""
21339   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21340   [(set_attr "type" "multi")])
21341
21342 (define_insn "stack_protect_set_di"
21343   [(set (match_operand:DI 0 "memory_operand" "=m")
21344         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21345    (set (match_scratch:DI 2 "=&r") (const_int 0))
21346    (clobber (reg:CC FLAGS_REG))]
21347   "TARGET_64BIT"
21348   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21349   [(set_attr "type" "multi")])
21350
21351 (define_insn "stack_tls_protect_set_si"
21352   [(set (match_operand:SI 0 "memory_operand" "=m")
21353         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21354    (set (match_scratch:SI 2 "=&r") (const_int 0))
21355    (clobber (reg:CC FLAGS_REG))]
21356   ""
21357   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21358   [(set_attr "type" "multi")])
21359
21360 (define_insn "stack_tls_protect_set_di"
21361   [(set (match_operand:DI 0 "memory_operand" "=m")
21362         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21363    (set (match_scratch:DI 2 "=&r") (const_int 0))
21364    (clobber (reg:CC FLAGS_REG))]
21365   "TARGET_64BIT"
21366   {
21367      /* The kernel uses a different segment register for performance reasons; a
21368         system call would not have to trash the userspace segment register,
21369         which would be expensive */
21370      if (ix86_cmodel != CM_KERNEL)
21371         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21372      else
21373         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21374   }
21375   [(set_attr "type" "multi")])
21376
21377 (define_expand "stack_protect_test"
21378   [(match_operand 0 "memory_operand" "")
21379    (match_operand 1 "memory_operand" "")
21380    (match_operand 2 "" "")]
21381   ""
21382 {
21383   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21384   ix86_compare_op0 = operands[0];
21385   ix86_compare_op1 = operands[1];
21386   ix86_compare_emitted = flags;
21387
21388 #ifdef TARGET_THREAD_SSP_OFFSET
21389   if (TARGET_64BIT)
21390     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21391                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21392   else
21393     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21394                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21395 #else
21396   if (TARGET_64BIT)
21397     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21398   else
21399     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21400 #endif
21401   emit_jump_insn (gen_beq (operands[2]));
21402   DONE;
21403 })
21404
21405 (define_insn "stack_protect_test_si"
21406   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21407         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21408                      (match_operand:SI 2 "memory_operand" "m")]
21409                     UNSPEC_SP_TEST))
21410    (clobber (match_scratch:SI 3 "=&r"))]
21411   ""
21412   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21413   [(set_attr "type" "multi")])
21414
21415 (define_insn "stack_protect_test_di"
21416   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21417         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21418                      (match_operand:DI 2 "memory_operand" "m")]
21419                     UNSPEC_SP_TEST))
21420    (clobber (match_scratch:DI 3 "=&r"))]
21421   "TARGET_64BIT"
21422   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21423   [(set_attr "type" "multi")])
21424
21425 (define_insn "stack_tls_protect_test_si"
21426   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21427         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21428                      (match_operand:SI 2 "const_int_operand" "i")]
21429                     UNSPEC_SP_TLS_TEST))
21430    (clobber (match_scratch:SI 3 "=r"))]
21431   ""
21432   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21433   [(set_attr "type" "multi")])
21434
21435 (define_insn "stack_tls_protect_test_di"
21436   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21437         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21438                      (match_operand:DI 2 "const_int_operand" "i")]
21439                     UNSPEC_SP_TLS_TEST))
21440    (clobber (match_scratch:DI 3 "=r"))]
21441   "TARGET_64BIT"
21442   {
21443      /* The kernel uses a different segment register for performance reasons; a
21444         system call would not have to trash the userspace segment register,
21445         which would be expensive */
21446      if (ix86_cmodel != CM_KERNEL)
21447         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21448      else
21449         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21450   }
21451   [(set_attr "type" "multi")])
21452
21453 (define_mode_iterator CRC32MODE [QI HI SI])
21454 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21455 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21456
21457 (define_insn "sse4_2_crc32<mode>"
21458   [(set (match_operand:SI 0 "register_operand" "=r")
21459         (unspec:SI
21460           [(match_operand:SI 1 "register_operand" "0")
21461            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21462           UNSPEC_CRC32))]
21463   "TARGET_SSE4_2"
21464   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21465   [(set_attr "type" "sselog1")
21466    (set_attr "prefix_rep" "1")
21467    (set_attr "prefix_extra" "1")
21468    (set_attr "mode" "SI")])
21469
21470 (define_insn "sse4_2_crc32di"
21471   [(set (match_operand:DI 0 "register_operand" "=r")
21472         (unspec:DI
21473           [(match_operand:DI 1 "register_operand" "0")
21474            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21475           UNSPEC_CRC32))]
21476   "TARGET_SSE4_2 && TARGET_64BIT"
21477   "crc32q\t{%2, %0|%0, %2}"
21478   [(set_attr "type" "sselog1")
21479    (set_attr "prefix_rep" "1")
21480    (set_attr "prefix_extra" "1")
21481    (set_attr "mode" "DI")])
21482
21483 (include "mmx.md")
21484 (include "sse.md")
21485 (include "sync.md")