OSDN Git Service

4d4978d778b0f0d842810a472c608fd13ba75d3e
[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_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
107
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
112
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
144
145    (UNSPEC_C2_FLAG              95)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
173
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
178
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_SSE5_ASHIFT          154)
185    (UNSPEC_SSE5_LSHIFT          155)
186    (UNSPEC_FRCZ                 156)
187    (UNSPEC_CVTPH2PS             157)
188    (UNSPEC_CVTPS2PH             158)
189   ])
190
191 (define_constants
192   [(UNSPECV_BLOCKAGE            0)
193    (UNSPECV_STACK_PROBE         1)
194    (UNSPECV_EMMS                2)
195    (UNSPECV_LDMXCSR             3)
196    (UNSPECV_STMXCSR             4)
197    (UNSPECV_FEMMS               5)
198    (UNSPECV_CLFLUSH             6)
199    (UNSPECV_ALIGN               7)
200    (UNSPECV_MONITOR             8)
201    (UNSPECV_MWAIT               9)
202    (UNSPECV_CMPXCHG_1           10)
203    (UNSPECV_CMPXCHG_2           11)
204    (UNSPECV_XCHG                12)
205    (UNSPECV_LOCK                13)
206    (UNSPECV_PROLOGUE_USE        14)
207   ])
208
209 ;; Constants to represent pcomtrue/pcomfalse variants
210 (define_constants
211   [(PCOM_FALSE                  0)
212    (PCOM_TRUE                   1)
213    (COM_FALSE_S                 2)
214    (COM_FALSE_P                 3)
215    (COM_TRUE_S                  4)
216    (COM_TRUE_P                  5)
217   ])
218
219 ;; Registers by name.
220 (define_constants
221   [(AX_REG                       0)
222    (DX_REG                       1)
223    (CX_REG                       2)
224    (SI_REG                       4)
225    (DI_REG                       5)
226    (BP_REG                       6)
227    (SP_REG                       7)
228    (FLAGS_REG                   17)
229    (FPSR_REG                    18)
230    (FPCR_REG                    19)
231    (R10_REG                     39)
232    (R11_REG                     40)
233   ])
234
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
236 ;; from i386.c.
237
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first.  This allows for better optimization.  For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
242
243 \f
244 ;; Processor type.  This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247                     nocona,core2,generic32,generic64,amdfam10"
248   (const (symbol_ref "ix86_tune")))
249
250 ;; A basic instruction type.  Refinements due to arguments to be
251 ;; provided in other attributes.
252 (define_attr "type"
253   "other,multi,
254    alu,alu1,negnot,imov,imovx,lea,
255    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256    icmp,test,ibr,setcc,icmov,
257    push,pop,call,callv,leave,
258    str,bitmanip,
259    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
262    ssemuladd,sse4arg,
263    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264   (const_string "other"))
265
266 ;; Main data type used by the insn
267 (define_attr "mode"
268   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269   (const_string "unknown"))
270
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274            (const_string "i387")
275          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
278            (const_string "sse")
279          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
280            (const_string "mmx")
281          (eq_attr "type" "other")
282            (const_string "unknown")]
283          (const_string "integer")))
284
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
288                           bitmanip")
289            (const_int 0)
290          (eq_attr "unit" "i387,sse,mmx")
291            (const_int 0)
292          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
293                           imul,icmp,push,pop")
294            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295          (eq_attr "type" "imov,test")
296            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297          (eq_attr "type" "call")
298            (if_then_else (match_operand 0 "constant_call_address_operand" "")
299              (const_int 4)
300              (const_int 0))
301          (eq_attr "type" "callv")
302            (if_then_else (match_operand 1 "constant_call_address_operand" "")
303              (const_int 4)
304              (const_int 0))
305          ;; We don't know the size before shorten_branches.  Expect
306          ;; the instruction to fit for better scheduling.
307          (eq_attr "type" "ibr")
308            (const_int 1)
309          ]
310          (symbol_ref "/* Update immediate_length and other attributes! */
311                       gcc_unreachable (),1")))
312
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315   (cond [(eq_attr "type" "str,other,multi,fxch")
316            (const_int 0)
317          (and (eq_attr "type" "call")
318               (match_operand 0 "constant_call_address_operand" ""))
319              (const_int 0)
320          (and (eq_attr "type" "callv")
321               (match_operand 1 "constant_call_address_operand" ""))
322              (const_int 0)
323          ]
324          (symbol_ref "ix86_attr_length_address_default (insn)")))
325
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328   (if_then_else (ior (eq_attr "mode" "HI")
329                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
330     (const_int 1)
331     (const_int 0)))
332
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
336     (const_int 1)
337     (const_int 0)))
338
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
341   (if_then_else
342     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343          (eq_attr "unit" "sse,mmx"))
344     (const_int 1)
345     (const_int 0)))
346
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349   (cond [(and (eq_attr "mode" "DI")
350               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
351            (const_int 1)
352          (and (eq_attr "mode" "QI")
353               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
354                   (const_int 0)))
355            (const_int 1)
356          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
357              (const_int 0))
358            (const_int 1)
359         ]
360         (const_int 0)))
361
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
364
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367   (cond [(eq_attr "type" "str,leave")
368            (const_int 0)
369          (eq_attr "unit" "i387")
370            (const_int 0)
371          (and (eq_attr "type" "incdec")
372               (ior (match_operand:SI 1 "register_operand" "")
373                    (match_operand:HI 1 "register_operand" "")))
374            (const_int 0)
375          (and (eq_attr "type" "push")
376               (not (match_operand 1 "memory_operand" "")))
377            (const_int 0)
378          (and (eq_attr "type" "pop")
379               (not (match_operand 0 "memory_operand" "")))
380            (const_int 0)
381          (and (eq_attr "type" "imov")
382               (ior (and (match_operand 0 "register_operand" "")
383                         (match_operand 1 "immediate_operand" ""))
384                    (ior (and (match_operand 0 "ax_reg_operand" "")
385                              (match_operand 1 "memory_displacement_only_operand" ""))
386                         (and (match_operand 0 "memory_displacement_only_operand" "")
387                              (match_operand 1 "ax_reg_operand" "")))))
388            (const_int 0)
389          (and (eq_attr "type" "call")
390               (match_operand 0 "constant_call_address_operand" ""))
391              (const_int 0)
392          (and (eq_attr "type" "callv")
393               (match_operand 1 "constant_call_address_operand" ""))
394              (const_int 0)
395          ]
396          (const_int 1)))
397
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
401 ;; other insns.
402 (define_attr "length" ""
403   (cond [(eq_attr "type" "other,multi,fistp,frndint")
404            (const_int 16)
405          (eq_attr "type" "fcmp")
406            (const_int 4)
407          (eq_attr "unit" "i387")
408            (plus (const_int 2)
409                  (plus (attr "prefix_data16")
410                        (attr "length_address")))]
411          (plus (plus (attr "modrm")
412                      (plus (attr "prefix_0f")
413                            (plus (attr "prefix_rex")
414                                  (plus (attr "prefix_extra")
415                                        (const_int 1)))))
416                (plus (attr "prefix_rep")
417                      (plus (attr "prefix_data16")
418                            (plus (attr "length_immediate")
419                                  (attr "length_address")))))))
420
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
424
425 (define_attr "memory" "none,load,store,both,unknown"
426   (cond [(eq_attr "type" "other,multi,str")
427            (const_string "unknown")
428          (eq_attr "type" "lea,fcmov,fpspc")
429            (const_string "none")
430          (eq_attr "type" "fistp,leave")
431            (const_string "both")
432          (eq_attr "type" "frndint")
433            (const_string "load")
434          (eq_attr "type" "push")
435            (if_then_else (match_operand 1 "memory_operand" "")
436              (const_string "both")
437              (const_string "store"))
438          (eq_attr "type" "pop")
439            (if_then_else (match_operand 0 "memory_operand" "")
440              (const_string "both")
441              (const_string "load"))
442          (eq_attr "type" "setcc")
443            (if_then_else (match_operand 0 "memory_operand" "")
444              (const_string "store")
445              (const_string "none"))
446          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447            (if_then_else (ior (match_operand 0 "memory_operand" "")
448                               (match_operand 1 "memory_operand" ""))
449              (const_string "load")
450              (const_string "none"))
451          (eq_attr "type" "ibr")
452            (if_then_else (match_operand 0 "memory_operand" "")
453              (const_string "load")
454              (const_string "none"))
455          (eq_attr "type" "call")
456            (if_then_else (match_operand 0 "constant_call_address_operand" "")
457              (const_string "none")
458              (const_string "load"))
459          (eq_attr "type" "callv")
460            (if_then_else (match_operand 1 "constant_call_address_operand" "")
461              (const_string "none")
462              (const_string "load"))
463          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464               (match_operand 1 "memory_operand" ""))
465            (const_string "both")
466          (and (match_operand 0 "memory_operand" "")
467               (match_operand 1 "memory_operand" ""))
468            (const_string "both")
469          (match_operand 0 "memory_operand" "")
470            (const_string "store")
471          (match_operand 1 "memory_operand" "")
472            (const_string "load")
473          (and (eq_attr "type"
474                  "!alu1,negnot,ishift1,
475                    imov,imovx,icmp,test,bitmanip,
476                    fmov,fcmp,fsgn,
477                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479               (match_operand 2 "memory_operand" ""))
480            (const_string "load")
481          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482               (match_operand 3 "memory_operand" ""))
483            (const_string "load")
484         ]
485         (const_string "none")))
486
487 ;; Indicates if an instruction has both an immediate and a displacement.
488
489 (define_attr "imm_disp" "false,true,unknown"
490   (cond [(eq_attr "type" "other,multi")
491            (const_string "unknown")
492          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493               (and (match_operand 0 "memory_displacement_operand" "")
494                    (match_operand 1 "immediate_operand" "")))
495            (const_string "true")
496          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497               (and (match_operand 0 "memory_displacement_operand" "")
498                    (match_operand 2 "immediate_operand" "")))
499            (const_string "true")
500         ]
501         (const_string "false")))
502
503 ;; Indicates if an FP operation has an integer source.
504
505 (define_attr "fp_int_src" "false,true"
506   (const_string "false"))
507
508 ;; Defines rounding mode of an FP operation.
509
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511   (const_string "any"))
512
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515   [(set_attr "length" "128")
516    (set_attr "type" "multi")])
517
518 ;; All integer comparison codes.
519 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
520
521 ;; All floating-point comparison codes.
522 (define_code_iterator fp_cond [unordered ordered
523                                uneq unge ungt unle unlt ltgt ])
524
525 (define_code_iterator plusminus [plus minus])
526
527 ;; Base name for define_insn and insn mnemonic.
528 (define_code_attr addsub [(plus "add") (minus "sub")])
529
530 ;; Mark commutative operators as such in constraints.
531 (define_code_attr comm [(plus "%") (minus "")])
532
533 ;; All single word integer modes.
534 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
535
536 ;; Instruction suffix for integer modes.
537 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
538
539 ;; Register class for integer modes.
540 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
541
542 ;; Immediate operand constraint for integer modes.
543 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
544
545 ;; General operand predicate for integer modes.
546 (define_mode_attr general_operand
547         [(QI "general_operand")
548          (HI "general_operand")
549          (SI "general_operand")
550          (DI "x86_64_general_operand")])
551
552 ;; SSE and x87 SFmode and DFmode floating point modes
553 (define_mode_iterator MODEF [SF DF])
554
555 ;; All x87 floating point modes
556 (define_mode_iterator X87MODEF [SF DF XF])
557
558 ;; All integer modes handled by x87 fisttp operator.
559 (define_mode_iterator X87MODEI [HI SI DI])
560
561 ;; All integer modes handled by integer x87 operators.
562 (define_mode_iterator X87MODEI12 [HI SI])
563
564 ;; All integer modes handled by SSE cvtts?2si* operators.
565 (define_mode_iterator SSEMODEI24 [SI DI])
566
567 ;; SSE asm suffix for floating point modes
568 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
569
570 ;; SSE vector mode corresponding to a scalar mode
571 (define_mode_attr ssevecmode
572   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
573 \f
574 ;; Scheduling descriptions
575
576 (include "pentium.md")
577 (include "ppro.md")
578 (include "k6.md")
579 (include "athlon.md")
580 (include "geode.md")
581
582 \f
583 ;; Operand and operator predicates and constraints
584
585 (include "predicates.md")
586 (include "constraints.md")
587
588 \f
589 ;; Compare instructions.
590
591 ;; All compare insns have expanders that save the operands away without
592 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
593 ;; after the cmp) will actually emit the cmpM.
594
595 (define_expand "cmpti"
596   [(set (reg:CC FLAGS_REG)
597         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
598                     (match_operand:TI 1 "x86_64_general_operand" "")))]
599   "TARGET_64BIT"
600 {
601   if (MEM_P (operands[0]) && MEM_P (operands[1]))
602     operands[0] = force_reg (TImode, operands[0]);
603   ix86_compare_op0 = operands[0];
604   ix86_compare_op1 = operands[1];
605   DONE;
606 })
607
608 (define_expand "cmpdi"
609   [(set (reg:CC FLAGS_REG)
610         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
611                     (match_operand:DI 1 "x86_64_general_operand" "")))]
612   ""
613 {
614   if (MEM_P (operands[0]) && MEM_P (operands[1]))
615     operands[0] = force_reg (DImode, operands[0]);
616   ix86_compare_op0 = operands[0];
617   ix86_compare_op1 = operands[1];
618   DONE;
619 })
620
621 (define_expand "cmpsi"
622   [(set (reg:CC FLAGS_REG)
623         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
624                     (match_operand:SI 1 "general_operand" "")))]
625   ""
626 {
627   if (MEM_P (operands[0]) && MEM_P (operands[1]))
628     operands[0] = force_reg (SImode, operands[0]);
629   ix86_compare_op0 = operands[0];
630   ix86_compare_op1 = operands[1];
631   DONE;
632 })
633
634 (define_expand "cmphi"
635   [(set (reg:CC FLAGS_REG)
636         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
637                     (match_operand:HI 1 "general_operand" "")))]
638   ""
639 {
640   if (MEM_P (operands[0]) && MEM_P (operands[1]))
641     operands[0] = force_reg (HImode, operands[0]);
642   ix86_compare_op0 = operands[0];
643   ix86_compare_op1 = operands[1];
644   DONE;
645 })
646
647 (define_expand "cmpqi"
648   [(set (reg:CC FLAGS_REG)
649         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
650                     (match_operand:QI 1 "general_operand" "")))]
651   "TARGET_QIMODE_MATH"
652 {
653   if (MEM_P (operands[0]) && MEM_P (operands[1]))
654     operands[0] = force_reg (QImode, operands[0]);
655   ix86_compare_op0 = operands[0];
656   ix86_compare_op1 = operands[1];
657   DONE;
658 })
659
660 (define_insn "cmpdi_ccno_1_rex64"
661   [(set (reg FLAGS_REG)
662         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
663                  (match_operand:DI 1 "const0_operand" "n,n")))]
664   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
665   "@
666    test{q}\t%0, %0
667    cmp{q}\t{%1, %0|%0, %1}"
668   [(set_attr "type" "test,icmp")
669    (set_attr "length_immediate" "0,1")
670    (set_attr "mode" "DI")])
671
672 (define_insn "*cmpdi_minus_1_rex64"
673   [(set (reg FLAGS_REG)
674         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
675                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
676                  (const_int 0)))]
677   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
678   "cmp{q}\t{%1, %0|%0, %1}"
679   [(set_attr "type" "icmp")
680    (set_attr "mode" "DI")])
681
682 (define_expand "cmpdi_1_rex64"
683   [(set (reg:CC FLAGS_REG)
684         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
685                     (match_operand:DI 1 "general_operand" "")))]
686   "TARGET_64BIT"
687   "")
688
689 (define_insn "cmpdi_1_insn_rex64"
690   [(set (reg FLAGS_REG)
691         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
692                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
693   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
694   "cmp{q}\t{%1, %0|%0, %1}"
695   [(set_attr "type" "icmp")
696    (set_attr "mode" "DI")])
697
698
699 (define_insn "*cmpsi_ccno_1"
700   [(set (reg FLAGS_REG)
701         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
702                  (match_operand:SI 1 "const0_operand" "n,n")))]
703   "ix86_match_ccmode (insn, CCNOmode)"
704   "@
705    test{l}\t%0, %0
706    cmp{l}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "test,icmp")
708    (set_attr "length_immediate" "0,1")
709    (set_attr "mode" "SI")])
710
711 (define_insn "*cmpsi_minus_1"
712   [(set (reg FLAGS_REG)
713         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
714                            (match_operand:SI 1 "general_operand" "ri,mr"))
715                  (const_int 0)))]
716   "ix86_match_ccmode (insn, CCGOCmode)"
717   "cmp{l}\t{%1, %0|%0, %1}"
718   [(set_attr "type" "icmp")
719    (set_attr "mode" "SI")])
720
721 (define_expand "cmpsi_1"
722   [(set (reg:CC FLAGS_REG)
723         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
724                     (match_operand:SI 1 "general_operand" "")))]
725   ""
726   "")
727
728 (define_insn "*cmpsi_1_insn"
729   [(set (reg FLAGS_REG)
730         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
731                  (match_operand:SI 1 "general_operand" "ri,mr")))]
732   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
733     && ix86_match_ccmode (insn, CCmode)"
734   "cmp{l}\t{%1, %0|%0, %1}"
735   [(set_attr "type" "icmp")
736    (set_attr "mode" "SI")])
737
738 (define_insn "*cmphi_ccno_1"
739   [(set (reg FLAGS_REG)
740         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
741                  (match_operand:HI 1 "const0_operand" "n,n")))]
742   "ix86_match_ccmode (insn, CCNOmode)"
743   "@
744    test{w}\t%0, %0
745    cmp{w}\t{%1, %0|%0, %1}"
746   [(set_attr "type" "test,icmp")
747    (set_attr "length_immediate" "0,1")
748    (set_attr "mode" "HI")])
749
750 (define_insn "*cmphi_minus_1"
751   [(set (reg FLAGS_REG)
752         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
753                            (match_operand:HI 1 "general_operand" "ri,mr"))
754                  (const_int 0)))]
755   "ix86_match_ccmode (insn, CCGOCmode)"
756   "cmp{w}\t{%1, %0|%0, %1}"
757   [(set_attr "type" "icmp")
758    (set_attr "mode" "HI")])
759
760 (define_insn "*cmphi_1"
761   [(set (reg FLAGS_REG)
762         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
763                  (match_operand:HI 1 "general_operand" "ri,mr")))]
764   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
765    && ix86_match_ccmode (insn, CCmode)"
766   "cmp{w}\t{%1, %0|%0, %1}"
767   [(set_attr "type" "icmp")
768    (set_attr "mode" "HI")])
769
770 (define_insn "*cmpqi_ccno_1"
771   [(set (reg FLAGS_REG)
772         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
773                  (match_operand:QI 1 "const0_operand" "n,n")))]
774   "ix86_match_ccmode (insn, CCNOmode)"
775   "@
776    test{b}\t%0, %0
777    cmp{b}\t{$0, %0|%0, 0}"
778   [(set_attr "type" "test,icmp")
779    (set_attr "length_immediate" "0,1")
780    (set_attr "mode" "QI")])
781
782 (define_insn "*cmpqi_1"
783   [(set (reg FLAGS_REG)
784         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
785                  (match_operand:QI 1 "general_operand" "qi,mq")))]
786   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
787     && ix86_match_ccmode (insn, CCmode)"
788   "cmp{b}\t{%1, %0|%0, %1}"
789   [(set_attr "type" "icmp")
790    (set_attr "mode" "QI")])
791
792 (define_insn "*cmpqi_minus_1"
793   [(set (reg FLAGS_REG)
794         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
795                            (match_operand:QI 1 "general_operand" "qi,mq"))
796                  (const_int 0)))]
797   "ix86_match_ccmode (insn, CCGOCmode)"
798   "cmp{b}\t{%1, %0|%0, %1}"
799   [(set_attr "type" "icmp")
800    (set_attr "mode" "QI")])
801
802 (define_insn "*cmpqi_ext_1"
803   [(set (reg FLAGS_REG)
804         (compare
805           (match_operand:QI 0 "general_operand" "Qm")
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 1 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)))]
811   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
812   "cmp{b}\t{%h1, %0|%0, %h1}"
813   [(set_attr "type" "icmp")
814    (set_attr "mode" "QI")])
815
816 (define_insn "*cmpqi_ext_1_rex64"
817   [(set (reg FLAGS_REG)
818         (compare
819           (match_operand:QI 0 "register_operand" "Q")
820           (subreg:QI
821             (zero_extract:SI
822               (match_operand 1 "ext_register_operand" "Q")
823               (const_int 8)
824               (const_int 8)) 0)))]
825   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
826   "cmp{b}\t{%h1, %0|%0, %h1}"
827   [(set_attr "type" "icmp")
828    (set_attr "mode" "QI")])
829
830 (define_insn "*cmpqi_ext_2"
831   [(set (reg FLAGS_REG)
832         (compare
833           (subreg:QI
834             (zero_extract:SI
835               (match_operand 0 "ext_register_operand" "Q")
836               (const_int 8)
837               (const_int 8)) 0)
838           (match_operand:QI 1 "const0_operand" "n")))]
839   "ix86_match_ccmode (insn, CCNOmode)"
840   "test{b}\t%h0, %h0"
841   [(set_attr "type" "test")
842    (set_attr "length_immediate" "0")
843    (set_attr "mode" "QI")])
844
845 (define_expand "cmpqi_ext_3"
846   [(set (reg:CC FLAGS_REG)
847         (compare:CC
848           (subreg:QI
849             (zero_extract:SI
850               (match_operand 0 "ext_register_operand" "")
851               (const_int 8)
852               (const_int 8)) 0)
853           (match_operand:QI 1 "general_operand" "")))]
854   ""
855   "")
856
857 (define_insn "cmpqi_ext_3_insn"
858   [(set (reg FLAGS_REG)
859         (compare
860           (subreg:QI
861             (zero_extract:SI
862               (match_operand 0 "ext_register_operand" "Q")
863               (const_int 8)
864               (const_int 8)) 0)
865           (match_operand:QI 1 "general_operand" "Qmn")))]
866   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
867   "cmp{b}\t{%1, %h0|%h0, %1}"
868   [(set_attr "type" "icmp")
869    (set_attr "mode" "QI")])
870
871 (define_insn "cmpqi_ext_3_insn_rex64"
872   [(set (reg FLAGS_REG)
873         (compare
874           (subreg:QI
875             (zero_extract:SI
876               (match_operand 0 "ext_register_operand" "Q")
877               (const_int 8)
878               (const_int 8)) 0)
879           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
880   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
881   "cmp{b}\t{%1, %h0|%h0, %1}"
882   [(set_attr "type" "icmp")
883    (set_attr "mode" "QI")])
884
885 (define_insn "*cmpqi_ext_4"
886   [(set (reg FLAGS_REG)
887         (compare
888           (subreg:QI
889             (zero_extract:SI
890               (match_operand 0 "ext_register_operand" "Q")
891               (const_int 8)
892               (const_int 8)) 0)
893           (subreg:QI
894             (zero_extract:SI
895               (match_operand 1 "ext_register_operand" "Q")
896               (const_int 8)
897               (const_int 8)) 0)))]
898   "ix86_match_ccmode (insn, CCmode)"
899   "cmp{b}\t{%h1, %h0|%h0, %h1}"
900   [(set_attr "type" "icmp")
901    (set_attr "mode" "QI")])
902
903 ;; These implement float point compares.
904 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
905 ;; which would allow mix and match FP modes on the compares.  Which is what
906 ;; the old patterns did, but with many more of them.
907
908 (define_expand "cmpxf"
909   [(set (reg:CC FLAGS_REG)
910         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
911                     (match_operand:XF 1 "nonmemory_operand" "")))]
912   "TARGET_80387"
913 {
914   ix86_compare_op0 = operands[0];
915   ix86_compare_op1 = operands[1];
916   DONE;
917 })
918
919 (define_expand "cmp<mode>"
920   [(set (reg:CC FLAGS_REG)
921         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
922                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
923   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
924 {
925   ix86_compare_op0 = operands[0];
926   ix86_compare_op1 = operands[1];
927   DONE;
928 })
929
930 ;; FP compares, step 1:
931 ;; Set the FP condition codes.
932 ;;
933 ;; CCFPmode     compare with exceptions
934 ;; CCFPUmode    compare with no exceptions
935
936 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
937 ;; used to manage the reg stack popping would not be preserved.
938
939 (define_insn "*cmpfp_0"
940   [(set (match_operand:HI 0 "register_operand" "=a")
941         (unspec:HI
942           [(compare:CCFP
943              (match_operand 1 "register_operand" "f")
944              (match_operand 2 "const0_operand" "X"))]
945         UNSPEC_FNSTSW))]
946   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
947    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
948   "* return output_fp_compare (insn, operands, 0, 0);"
949   [(set_attr "type" "multi")
950    (set_attr "unit" "i387")
951    (set (attr "mode")
952      (cond [(match_operand:SF 1 "" "")
953               (const_string "SF")
954             (match_operand:DF 1 "" "")
955               (const_string "DF")
956            ]
957            (const_string "XF")))])
958
959 (define_insn_and_split "*cmpfp_0_cc"
960   [(set (reg:CCFP FLAGS_REG)
961         (compare:CCFP
962           (match_operand 1 "register_operand" "f")
963           (match_operand 2 "const0_operand" "X")))
964    (clobber (match_operand:HI 0 "register_operand" "=a"))]
965   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
966    && TARGET_SAHF && !TARGET_CMOVE
967    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
968   "#"
969   "&& reload_completed"
970   [(set (match_dup 0)
971         (unspec:HI
972           [(compare:CCFP (match_dup 1)(match_dup 2))]
973         UNSPEC_FNSTSW))
974    (set (reg:CC FLAGS_REG)
975         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
976   ""
977   [(set_attr "type" "multi")
978    (set_attr "unit" "i387")
979    (set (attr "mode")
980      (cond [(match_operand:SF 1 "" "")
981               (const_string "SF")
982             (match_operand:DF 1 "" "")
983               (const_string "DF")
984            ]
985            (const_string "XF")))])
986
987 (define_insn "*cmpfp_xf"
988   [(set (match_operand:HI 0 "register_operand" "=a")
989         (unspec:HI
990           [(compare:CCFP
991              (match_operand:XF 1 "register_operand" "f")
992              (match_operand:XF 2 "register_operand" "f"))]
993           UNSPEC_FNSTSW))]
994   "TARGET_80387"
995   "* return output_fp_compare (insn, operands, 0, 0);"
996   [(set_attr "type" "multi")
997    (set_attr "unit" "i387")
998    (set_attr "mode" "XF")])
999
1000 (define_insn_and_split "*cmpfp_xf_cc"
1001   [(set (reg:CCFP FLAGS_REG)
1002         (compare:CCFP
1003           (match_operand:XF 1 "register_operand" "f")
1004           (match_operand:XF 2 "register_operand" "f")))
1005    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1006   "TARGET_80387
1007    && TARGET_SAHF && !TARGET_CMOVE"
1008   "#"
1009   "&& reload_completed"
1010   [(set (match_dup 0)
1011         (unspec:HI
1012           [(compare:CCFP (match_dup 1)(match_dup 2))]
1013         UNSPEC_FNSTSW))
1014    (set (reg:CC FLAGS_REG)
1015         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1016   ""
1017   [(set_attr "type" "multi")
1018    (set_attr "unit" "i387")
1019    (set_attr "mode" "XF")])
1020
1021 (define_insn "*cmpfp_<mode>"
1022   [(set (match_operand:HI 0 "register_operand" "=a")
1023         (unspec:HI
1024           [(compare:CCFP
1025              (match_operand:MODEF 1 "register_operand" "f")
1026              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1027           UNSPEC_FNSTSW))]
1028   "TARGET_80387"
1029   "* return output_fp_compare (insn, operands, 0, 0);"
1030   [(set_attr "type" "multi")
1031    (set_attr "unit" "i387")
1032    (set_attr "mode" "<MODE>")])
1033
1034 (define_insn_and_split "*cmpfp_<mode>_cc"
1035   [(set (reg:CCFP FLAGS_REG)
1036         (compare:CCFP
1037           (match_operand:MODEF 1 "register_operand" "f")
1038           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1039    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1040   "TARGET_80387
1041    && TARGET_SAHF && !TARGET_CMOVE"
1042   "#"
1043   "&& reload_completed"
1044   [(set (match_dup 0)
1045         (unspec:HI
1046           [(compare:CCFP (match_dup 1)(match_dup 2))]
1047         UNSPEC_FNSTSW))
1048    (set (reg:CC FLAGS_REG)
1049         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1050   ""
1051   [(set_attr "type" "multi")
1052    (set_attr "unit" "i387")
1053    (set_attr "mode" "<MODE>")])
1054
1055 (define_insn "*cmpfp_u"
1056   [(set (match_operand:HI 0 "register_operand" "=a")
1057         (unspec:HI
1058           [(compare:CCFPU
1059              (match_operand 1 "register_operand" "f")
1060              (match_operand 2 "register_operand" "f"))]
1061           UNSPEC_FNSTSW))]
1062   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1063    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1064   "* return output_fp_compare (insn, operands, 0, 1);"
1065   [(set_attr "type" "multi")
1066    (set_attr "unit" "i387")
1067    (set (attr "mode")
1068      (cond [(match_operand:SF 1 "" "")
1069               (const_string "SF")
1070             (match_operand:DF 1 "" "")
1071               (const_string "DF")
1072            ]
1073            (const_string "XF")))])
1074
1075 (define_insn_and_split "*cmpfp_u_cc"
1076   [(set (reg:CCFPU FLAGS_REG)
1077         (compare:CCFPU
1078           (match_operand 1 "register_operand" "f")
1079           (match_operand 2 "register_operand" "f")))
1080    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1081   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1082    && TARGET_SAHF && !TARGET_CMOVE
1083    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1084   "#"
1085   "&& reload_completed"
1086   [(set (match_dup 0)
1087         (unspec:HI
1088           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1089         UNSPEC_FNSTSW))
1090    (set (reg:CC FLAGS_REG)
1091         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1092   ""
1093   [(set_attr "type" "multi")
1094    (set_attr "unit" "i387")
1095    (set (attr "mode")
1096      (cond [(match_operand:SF 1 "" "")
1097               (const_string "SF")
1098             (match_operand:DF 1 "" "")
1099               (const_string "DF")
1100            ]
1101            (const_string "XF")))])
1102
1103 (define_insn "*cmpfp_<mode>"
1104   [(set (match_operand:HI 0 "register_operand" "=a")
1105         (unspec:HI
1106           [(compare:CCFP
1107              (match_operand 1 "register_operand" "f")
1108              (match_operator 3 "float_operator"
1109                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1110           UNSPEC_FNSTSW))]
1111   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1112    && TARGET_USE_<MODE>MODE_FIOP
1113    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1114   "* return output_fp_compare (insn, operands, 0, 0);"
1115   [(set_attr "type" "multi")
1116    (set_attr "unit" "i387")
1117    (set_attr "fp_int_src" "true")
1118    (set_attr "mode" "<MODE>")])
1119
1120 (define_insn_and_split "*cmpfp_<mode>_cc"
1121   [(set (reg:CCFP FLAGS_REG)
1122         (compare:CCFP
1123           (match_operand 1 "register_operand" "f")
1124           (match_operator 3 "float_operator"
1125             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1126    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1127   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128    && TARGET_SAHF && !TARGET_CMOVE
1129    && TARGET_USE_<MODE>MODE_FIOP
1130    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1131   "#"
1132   "&& reload_completed"
1133   [(set (match_dup 0)
1134         (unspec:HI
1135           [(compare:CCFP
1136              (match_dup 1)
1137              (match_op_dup 3 [(match_dup 2)]))]
1138         UNSPEC_FNSTSW))
1139    (set (reg:CC FLAGS_REG)
1140         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1141   ""
1142   [(set_attr "type" "multi")
1143    (set_attr "unit" "i387")
1144    (set_attr "fp_int_src" "true")
1145    (set_attr "mode" "<MODE>")])
1146
1147 ;; FP compares, step 2
1148 ;; Move the fpsw to ax.
1149
1150 (define_insn "x86_fnstsw_1"
1151   [(set (match_operand:HI 0 "register_operand" "=a")
1152         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1153   "TARGET_80387"
1154   "fnstsw\t%0"
1155   [(set_attr "length" "2")
1156    (set_attr "mode" "SI")
1157    (set_attr "unit" "i387")])
1158
1159 ;; FP compares, step 3
1160 ;; Get ax into flags, general case.
1161
1162 (define_insn "x86_sahf_1"
1163   [(set (reg:CC FLAGS_REG)
1164         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1165                    UNSPEC_SAHF))]
1166   "TARGET_SAHF"
1167 {
1168 #ifdef HAVE_AS_IX86_SAHF
1169   return "sahf";
1170 #else
1171   return ".byte\t0x9e";
1172 #endif
1173 }
1174   [(set_attr "length" "1")
1175    (set_attr "athlon_decode" "vector")
1176    (set_attr "amdfam10_decode" "direct")
1177    (set_attr "mode" "SI")])
1178
1179 ;; Pentium Pro can do steps 1 through 3 in one go.
1180 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1181 (define_insn "*cmpfp_i_mixed"
1182   [(set (reg:CCFP FLAGS_REG)
1183         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1184                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1185   "TARGET_MIX_SSE_I387
1186    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1187    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1188   "* return output_fp_compare (insn, operands, 1, 0);"
1189   [(set_attr "type" "fcmp,ssecomi")
1190    (set (attr "mode")
1191      (if_then_else (match_operand:SF 1 "" "")
1192         (const_string "SF")
1193         (const_string "DF")))
1194    (set_attr "athlon_decode" "vector")
1195    (set_attr "amdfam10_decode" "direct")])
1196
1197 (define_insn "*cmpfp_i_sse"
1198   [(set (reg:CCFP FLAGS_REG)
1199         (compare:CCFP (match_operand 0 "register_operand" "x")
1200                       (match_operand 1 "nonimmediate_operand" "xm")))]
1201   "TARGET_SSE_MATH
1202    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1203    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1204   "* return output_fp_compare (insn, operands, 1, 0);"
1205   [(set_attr "type" "ssecomi")
1206    (set (attr "mode")
1207      (if_then_else (match_operand:SF 1 "" "")
1208         (const_string "SF")
1209         (const_string "DF")))
1210    (set_attr "athlon_decode" "vector")
1211    (set_attr "amdfam10_decode" "direct")])
1212
1213 (define_insn "*cmpfp_i_i387"
1214   [(set (reg:CCFP FLAGS_REG)
1215         (compare:CCFP (match_operand 0 "register_operand" "f")
1216                       (match_operand 1 "register_operand" "f")))]
1217   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1218    && TARGET_CMOVE
1219    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1220    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1221   "* return output_fp_compare (insn, operands, 1, 0);"
1222   [(set_attr "type" "fcmp")
1223    (set (attr "mode")
1224      (cond [(match_operand:SF 1 "" "")
1225               (const_string "SF")
1226             (match_operand:DF 1 "" "")
1227               (const_string "DF")
1228            ]
1229            (const_string "XF")))
1230    (set_attr "athlon_decode" "vector")
1231    (set_attr "amdfam10_decode" "direct")])
1232
1233 (define_insn "*cmpfp_iu_mixed"
1234   [(set (reg:CCFPU FLAGS_REG)
1235         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1236                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1237   "TARGET_MIX_SSE_I387
1238    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1239    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1240   "* return output_fp_compare (insn, operands, 1, 1);"
1241   [(set_attr "type" "fcmp,ssecomi")
1242    (set (attr "mode")
1243      (if_then_else (match_operand:SF 1 "" "")
1244         (const_string "SF")
1245         (const_string "DF")))
1246    (set_attr "athlon_decode" "vector")
1247    (set_attr "amdfam10_decode" "direct")])
1248
1249 (define_insn "*cmpfp_iu_sse"
1250   [(set (reg:CCFPU FLAGS_REG)
1251         (compare:CCFPU (match_operand 0 "register_operand" "x")
1252                        (match_operand 1 "nonimmediate_operand" "xm")))]
1253   "TARGET_SSE_MATH
1254    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1255    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1256   "* return output_fp_compare (insn, operands, 1, 1);"
1257   [(set_attr "type" "ssecomi")
1258    (set (attr "mode")
1259      (if_then_else (match_operand:SF 1 "" "")
1260         (const_string "SF")
1261         (const_string "DF")))
1262    (set_attr "athlon_decode" "vector")
1263    (set_attr "amdfam10_decode" "direct")])
1264
1265 (define_insn "*cmpfp_iu_387"
1266   [(set (reg:CCFPU FLAGS_REG)
1267         (compare:CCFPU (match_operand 0 "register_operand" "f")
1268                        (match_operand 1 "register_operand" "f")))]
1269   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1270    && TARGET_CMOVE
1271    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1272    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1273   "* return output_fp_compare (insn, operands, 1, 1);"
1274   [(set_attr "type" "fcmp")
1275    (set (attr "mode")
1276      (cond [(match_operand:SF 1 "" "")
1277               (const_string "SF")
1278             (match_operand:DF 1 "" "")
1279               (const_string "DF")
1280            ]
1281            (const_string "XF")))
1282    (set_attr "athlon_decode" "vector")
1283    (set_attr "amdfam10_decode" "direct")])
1284 \f
1285 ;; Move instructions.
1286
1287 ;; General case of fullword move.
1288
1289 (define_expand "movsi"
1290   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1291         (match_operand:SI 1 "general_operand" ""))]
1292   ""
1293   "ix86_expand_move (SImode, operands); DONE;")
1294
1295 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1296 ;; general_operand.
1297 ;;
1298 ;; %%% We don't use a post-inc memory reference because x86 is not a
1299 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1300 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1301 ;; targets without our curiosities, and it is just as easy to represent
1302 ;; this differently.
1303
1304 (define_insn "*pushsi2"
1305   [(set (match_operand:SI 0 "push_operand" "=<")
1306         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1307   "!TARGET_64BIT"
1308   "push{l}\t%1"
1309   [(set_attr "type" "push")
1310    (set_attr "mode" "SI")])
1311
1312 ;; For 64BIT abi we always round up to 8 bytes.
1313 (define_insn "*pushsi2_rex64"
1314   [(set (match_operand:SI 0 "push_operand" "=X")
1315         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1316   "TARGET_64BIT"
1317   "push{q}\t%q1"
1318   [(set_attr "type" "push")
1319    (set_attr "mode" "SI")])
1320
1321 (define_insn "*pushsi2_prologue"
1322   [(set (match_operand:SI 0 "push_operand" "=<")
1323         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1324    (clobber (mem:BLK (scratch)))]
1325   "!TARGET_64BIT"
1326   "push{l}\t%1"
1327   [(set_attr "type" "push")
1328    (set_attr "mode" "SI")])
1329
1330 (define_insn "*popsi1_epilogue"
1331   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1332         (mem:SI (reg:SI SP_REG)))
1333    (set (reg:SI SP_REG)
1334         (plus:SI (reg:SI SP_REG) (const_int 4)))
1335    (clobber (mem:BLK (scratch)))]
1336   "!TARGET_64BIT"
1337   "pop{l}\t%0"
1338   [(set_attr "type" "pop")
1339    (set_attr "mode" "SI")])
1340
1341 (define_insn "popsi1"
1342   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1343         (mem:SI (reg:SI SP_REG)))
1344    (set (reg:SI SP_REG)
1345         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1346   "!TARGET_64BIT"
1347   "pop{l}\t%0"
1348   [(set_attr "type" "pop")
1349    (set_attr "mode" "SI")])
1350
1351 (define_insn "*movsi_xor"
1352   [(set (match_operand:SI 0 "register_operand" "=r")
1353         (match_operand:SI 1 "const0_operand" "i"))
1354    (clobber (reg:CC FLAGS_REG))]
1355   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1356   "xor{l}\t%0, %0"
1357   [(set_attr "type" "alu1")
1358    (set_attr "mode" "SI")
1359    (set_attr "length_immediate" "0")])
1360
1361 (define_insn "*movsi_or"
1362   [(set (match_operand:SI 0 "register_operand" "=r")
1363         (match_operand:SI 1 "immediate_operand" "i"))
1364    (clobber (reg:CC FLAGS_REG))]
1365   "reload_completed
1366    && operands[1] == constm1_rtx
1367    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1368 {
1369   operands[1] = constm1_rtx;
1370   return "or{l}\t{%1, %0|%0, %1}";
1371 }
1372   [(set_attr "type" "alu1")
1373    (set_attr "mode" "SI")
1374    (set_attr "length_immediate" "1")])
1375
1376 (define_insn "*movsi_1"
1377   [(set (match_operand:SI 0 "nonimmediate_operand"
1378                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1379         (match_operand:SI 1 "general_operand"
1380                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1381   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1382 {
1383   switch (get_attr_type (insn))
1384     {
1385     case TYPE_SSELOG1:
1386       if (get_attr_mode (insn) == MODE_TI)
1387         return "pxor\t%0, %0";
1388       return "xorps\t%0, %0";
1389
1390     case TYPE_SSEMOV:
1391       switch (get_attr_mode (insn))
1392         {
1393         case MODE_TI:
1394           return "movdqa\t{%1, %0|%0, %1}";
1395         case MODE_V4SF:
1396           return "movaps\t{%1, %0|%0, %1}";
1397         case MODE_SI:
1398           return "movd\t{%1, %0|%0, %1}";
1399         case MODE_SF:
1400           return "movss\t{%1, %0|%0, %1}";
1401         default:
1402           gcc_unreachable ();
1403         }
1404
1405     case TYPE_MMXADD:
1406       return "pxor\t%0, %0";
1407
1408     case TYPE_MMXMOV:
1409       if (get_attr_mode (insn) == MODE_DI)
1410         return "movq\t{%1, %0|%0, %1}";
1411       return "movd\t{%1, %0|%0, %1}";
1412
1413     case TYPE_LEA:
1414       return "lea{l}\t{%1, %0|%0, %1}";
1415
1416     default:
1417       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1418       return "mov{l}\t{%1, %0|%0, %1}";
1419     }
1420 }
1421   [(set (attr "type")
1422      (cond [(eq_attr "alternative" "2")
1423               (const_string "mmxadd")
1424             (eq_attr "alternative" "3,4,5")
1425               (const_string "mmxmov")
1426             (eq_attr "alternative" "6")
1427               (const_string "sselog1")
1428             (eq_attr "alternative" "7,8,9,10,11")
1429               (const_string "ssemov")
1430             (match_operand:DI 1 "pic_32bit_operand" "")
1431               (const_string "lea")
1432            ]
1433            (const_string "imov")))
1434    (set (attr "mode")
1435      (cond [(eq_attr "alternative" "2,3")
1436               (const_string "DI")
1437             (eq_attr "alternative" "6,7")
1438               (if_then_else
1439                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1440                 (const_string "V4SF")
1441                 (const_string "TI"))
1442             (and (eq_attr "alternative" "8,9,10,11")
1443                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1444               (const_string "SF")
1445            ]
1446            (const_string "SI")))])
1447
1448 ;; Stores and loads of ax to arbitrary constant address.
1449 ;; We fake an second form of instruction to force reload to load address
1450 ;; into register when rax is not available
1451 (define_insn "*movabssi_1_rex64"
1452   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1453         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1454   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1455   "@
1456    movabs{l}\t{%1, %P0|%P0, %1}
1457    mov{l}\t{%1, %a0|%a0, %1}"
1458   [(set_attr "type" "imov")
1459    (set_attr "modrm" "0,*")
1460    (set_attr "length_address" "8,0")
1461    (set_attr "length_immediate" "0,*")
1462    (set_attr "memory" "store")
1463    (set_attr "mode" "SI")])
1464
1465 (define_insn "*movabssi_2_rex64"
1466   [(set (match_operand:SI 0 "register_operand" "=a,r")
1467         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1468   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1469   "@
1470    movabs{l}\t{%P1, %0|%0, %P1}
1471    mov{l}\t{%a1, %0|%0, %a1}"
1472   [(set_attr "type" "imov")
1473    (set_attr "modrm" "0,*")
1474    (set_attr "length_address" "8,0")
1475    (set_attr "length_immediate" "0")
1476    (set_attr "memory" "load")
1477    (set_attr "mode" "SI")])
1478
1479 (define_insn "*swapsi"
1480   [(set (match_operand:SI 0 "register_operand" "+r")
1481         (match_operand:SI 1 "register_operand" "+r"))
1482    (set (match_dup 1)
1483         (match_dup 0))]
1484   ""
1485   "xchg{l}\t%1, %0"
1486   [(set_attr "type" "imov")
1487    (set_attr "mode" "SI")
1488    (set_attr "pent_pair" "np")
1489    (set_attr "athlon_decode" "vector")
1490    (set_attr "amdfam10_decode" "double")])
1491
1492 (define_expand "movhi"
1493   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1494         (match_operand:HI 1 "general_operand" ""))]
1495   ""
1496   "ix86_expand_move (HImode, operands); DONE;")
1497
1498 (define_insn "*pushhi2"
1499   [(set (match_operand:HI 0 "push_operand" "=X")
1500         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1501   "!TARGET_64BIT"
1502   "push{l}\t%k1"
1503   [(set_attr "type" "push")
1504    (set_attr "mode" "SI")])
1505
1506 ;; For 64BIT abi we always round up to 8 bytes.
1507 (define_insn "*pushhi2_rex64"
1508   [(set (match_operand:HI 0 "push_operand" "=X")
1509         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1510   "TARGET_64BIT"
1511   "push{q}\t%q1"
1512   [(set_attr "type" "push")
1513    (set_attr "mode" "DI")])
1514
1515 (define_insn "*movhi_1"
1516   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1517         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1518   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1519 {
1520   switch (get_attr_type (insn))
1521     {
1522     case TYPE_IMOVX:
1523       /* movzwl is faster than movw on p2 due to partial word stalls,
1524          though not as fast as an aligned movl.  */
1525       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1526     default:
1527       if (get_attr_mode (insn) == MODE_SI)
1528         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1529       else
1530         return "mov{w}\t{%1, %0|%0, %1}";
1531     }
1532 }
1533   [(set (attr "type")
1534      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1535               (const_string "imov")
1536             (and (eq_attr "alternative" "0")
1537                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1538                           (const_int 0))
1539                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1540                           (const_int 0))))
1541               (const_string "imov")
1542             (and (eq_attr "alternative" "1,2")
1543                  (match_operand:HI 1 "aligned_operand" ""))
1544               (const_string "imov")
1545             (and (ne (symbol_ref "TARGET_MOVX")
1546                      (const_int 0))
1547                  (eq_attr "alternative" "0,2"))
1548               (const_string "imovx")
1549            ]
1550            (const_string "imov")))
1551     (set (attr "mode")
1552       (cond [(eq_attr "type" "imovx")
1553                (const_string "SI")
1554              (and (eq_attr "alternative" "1,2")
1555                   (match_operand:HI 1 "aligned_operand" ""))
1556                (const_string "SI")
1557              (and (eq_attr "alternative" "0")
1558                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                            (const_int 0))
1560                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1561                            (const_int 0))))
1562                (const_string "SI")
1563             ]
1564             (const_string "HI")))])
1565
1566 ;; Stores and loads of ax to arbitrary constant address.
1567 ;; We fake an second form of instruction to force reload to load address
1568 ;; into register when rax is not available
1569 (define_insn "*movabshi_1_rex64"
1570   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1571         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1572   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1573   "@
1574    movabs{w}\t{%1, %P0|%P0, %1}
1575    mov{w}\t{%1, %a0|%a0, %1}"
1576   [(set_attr "type" "imov")
1577    (set_attr "modrm" "0,*")
1578    (set_attr "length_address" "8,0")
1579    (set_attr "length_immediate" "0,*")
1580    (set_attr "memory" "store")
1581    (set_attr "mode" "HI")])
1582
1583 (define_insn "*movabshi_2_rex64"
1584   [(set (match_operand:HI 0 "register_operand" "=a,r")
1585         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1586   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1587   "@
1588    movabs{w}\t{%P1, %0|%0, %P1}
1589    mov{w}\t{%a1, %0|%0, %a1}"
1590   [(set_attr "type" "imov")
1591    (set_attr "modrm" "0,*")
1592    (set_attr "length_address" "8,0")
1593    (set_attr "length_immediate" "0")
1594    (set_attr "memory" "load")
1595    (set_attr "mode" "HI")])
1596
1597 (define_insn "*swaphi_1"
1598   [(set (match_operand:HI 0 "register_operand" "+r")
1599         (match_operand:HI 1 "register_operand" "+r"))
1600    (set (match_dup 1)
1601         (match_dup 0))]
1602   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1603   "xchg{l}\t%k1, %k0"
1604   [(set_attr "type" "imov")
1605    (set_attr "mode" "SI")
1606    (set_attr "pent_pair" "np")
1607    (set_attr "athlon_decode" "vector")
1608    (set_attr "amdfam10_decode" "double")])
1609
1610 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1611 (define_insn "*swaphi_2"
1612   [(set (match_operand:HI 0 "register_operand" "+r")
1613         (match_operand:HI 1 "register_operand" "+r"))
1614    (set (match_dup 1)
1615         (match_dup 0))]
1616   "TARGET_PARTIAL_REG_STALL"
1617   "xchg{w}\t%1, %0"
1618   [(set_attr "type" "imov")
1619    (set_attr "mode" "HI")
1620    (set_attr "pent_pair" "np")
1621    (set_attr "athlon_decode" "vector")])
1622
1623 (define_expand "movstricthi"
1624   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1625         (match_operand:HI 1 "general_operand" ""))]
1626   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1627 {
1628   /* Don't generate memory->memory moves, go through a register */
1629   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1630     operands[1] = force_reg (HImode, operands[1]);
1631 })
1632
1633 (define_insn "*movstricthi_1"
1634   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1635         (match_operand:HI 1 "general_operand" "rn,m"))]
1636   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1637    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1638   "mov{w}\t{%1, %0|%0, %1}"
1639   [(set_attr "type" "imov")
1640    (set_attr "mode" "HI")])
1641
1642 (define_insn "*movstricthi_xor"
1643   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1644         (match_operand:HI 1 "const0_operand" "i"))
1645    (clobber (reg:CC FLAGS_REG))]
1646   "reload_completed
1647    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1648   "xor{w}\t%0, %0"
1649   [(set_attr "type" "alu1")
1650    (set_attr "mode" "HI")
1651    (set_attr "length_immediate" "0")])
1652
1653 (define_expand "movqi"
1654   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1655         (match_operand:QI 1 "general_operand" ""))]
1656   ""
1657   "ix86_expand_move (QImode, operands); DONE;")
1658
1659 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1660 ;; "push a byte".  But actually we use pushl, which has the effect
1661 ;; of rounding the amount pushed up to a word.
1662
1663 (define_insn "*pushqi2"
1664   [(set (match_operand:QI 0 "push_operand" "=X")
1665         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1666   "!TARGET_64BIT"
1667   "push{l}\t%k1"
1668   [(set_attr "type" "push")
1669    (set_attr "mode" "SI")])
1670
1671 ;; For 64BIT abi we always round up to 8 bytes.
1672 (define_insn "*pushqi2_rex64"
1673   [(set (match_operand:QI 0 "push_operand" "=X")
1674         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1675   "TARGET_64BIT"
1676   "push{q}\t%q1"
1677   [(set_attr "type" "push")
1678    (set_attr "mode" "DI")])
1679
1680 ;; Situation is quite tricky about when to choose full sized (SImode) move
1681 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1682 ;; partial register dependency machines (such as AMD Athlon), where QImode
1683 ;; moves issue extra dependency and for partial register stalls machines
1684 ;; that don't use QImode patterns (and QImode move cause stall on the next
1685 ;; instruction).
1686 ;;
1687 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1688 ;; register stall machines with, where we use QImode instructions, since
1689 ;; partial register stall can be caused there.  Then we use movzx.
1690 (define_insn "*movqi_1"
1691   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1692         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1693   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1694 {
1695   switch (get_attr_type (insn))
1696     {
1697     case TYPE_IMOVX:
1698       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1699       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1700     default:
1701       if (get_attr_mode (insn) == MODE_SI)
1702         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1703       else
1704         return "mov{b}\t{%1, %0|%0, %1}";
1705     }
1706 }
1707   [(set (attr "type")
1708      (cond [(and (eq_attr "alternative" "5")
1709                  (not (match_operand:QI 1 "aligned_operand" "")))
1710               (const_string "imovx")
1711             (ne (symbol_ref "optimize_size") (const_int 0))
1712               (const_string "imov")
1713             (and (eq_attr "alternative" "3")
1714                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1715                           (const_int 0))
1716                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1717                           (const_int 0))))
1718               (const_string "imov")
1719             (eq_attr "alternative" "3,5")
1720               (const_string "imovx")
1721             (and (ne (symbol_ref "TARGET_MOVX")
1722                      (const_int 0))
1723                  (eq_attr "alternative" "2"))
1724               (const_string "imovx")
1725            ]
1726            (const_string "imov")))
1727    (set (attr "mode")
1728       (cond [(eq_attr "alternative" "3,4,5")
1729                (const_string "SI")
1730              (eq_attr "alternative" "6")
1731                (const_string "QI")
1732              (eq_attr "type" "imovx")
1733                (const_string "SI")
1734              (and (eq_attr "type" "imov")
1735                   (and (eq_attr "alternative" "0,1")
1736                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1737                                 (const_int 0))
1738                             (and (eq (symbol_ref "optimize_size")
1739                                      (const_int 0))
1740                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741                                      (const_int 0))))))
1742                (const_string "SI")
1743              ;; Avoid partial register stalls when not using QImode arithmetic
1744              (and (eq_attr "type" "imov")
1745                   (and (eq_attr "alternative" "0,1")
1746                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1747                                 (const_int 0))
1748                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1749                                 (const_int 0)))))
1750                (const_string "SI")
1751            ]
1752            (const_string "QI")))])
1753
1754 (define_expand "reload_outqi"
1755   [(parallel [(match_operand:QI 0 "" "=m")
1756               (match_operand:QI 1 "register_operand" "r")
1757               (match_operand:QI 2 "register_operand" "=&q")])]
1758   ""
1759 {
1760   rtx op0, op1, op2;
1761   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1762
1763   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1764   if (! q_regs_operand (op1, QImode))
1765     {
1766       emit_insn (gen_movqi (op2, op1));
1767       op1 = op2;
1768     }
1769   emit_insn (gen_movqi (op0, op1));
1770   DONE;
1771 })
1772
1773 (define_insn "*swapqi_1"
1774   [(set (match_operand:QI 0 "register_operand" "+r")
1775         (match_operand:QI 1 "register_operand" "+r"))
1776    (set (match_dup 1)
1777         (match_dup 0))]
1778   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1779   "xchg{l}\t%k1, %k0"
1780   [(set_attr "type" "imov")
1781    (set_attr "mode" "SI")
1782    (set_attr "pent_pair" "np")
1783    (set_attr "athlon_decode" "vector")
1784    (set_attr "amdfam10_decode" "vector")])
1785
1786 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1787 (define_insn "*swapqi_2"
1788   [(set (match_operand:QI 0 "register_operand" "+q")
1789         (match_operand:QI 1 "register_operand" "+q"))
1790    (set (match_dup 1)
1791         (match_dup 0))]
1792   "TARGET_PARTIAL_REG_STALL"
1793   "xchg{b}\t%1, %0"
1794   [(set_attr "type" "imov")
1795    (set_attr "mode" "QI")
1796    (set_attr "pent_pair" "np")
1797    (set_attr "athlon_decode" "vector")])
1798
1799 (define_expand "movstrictqi"
1800   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1801         (match_operand:QI 1 "general_operand" ""))]
1802   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1803 {
1804   /* Don't generate memory->memory moves, go through a register.  */
1805   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1806     operands[1] = force_reg (QImode, operands[1]);
1807 })
1808
1809 (define_insn "*movstrictqi_1"
1810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1811         (match_operand:QI 1 "general_operand" "*qn,m"))]
1812   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1813    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1814   "mov{b}\t{%1, %0|%0, %1}"
1815   [(set_attr "type" "imov")
1816    (set_attr "mode" "QI")])
1817
1818 (define_insn "*movstrictqi_xor"
1819   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1820         (match_operand:QI 1 "const0_operand" "i"))
1821    (clobber (reg:CC FLAGS_REG))]
1822   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1823   "xor{b}\t%0, %0"
1824   [(set_attr "type" "alu1")
1825    (set_attr "mode" "QI")
1826    (set_attr "length_immediate" "0")])
1827
1828 (define_insn "*movsi_extv_1"
1829   [(set (match_operand:SI 0 "register_operand" "=R")
1830         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1831                          (const_int 8)
1832                          (const_int 8)))]
1833   ""
1834   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1835   [(set_attr "type" "imovx")
1836    (set_attr "mode" "SI")])
1837
1838 (define_insn "*movhi_extv_1"
1839   [(set (match_operand:HI 0 "register_operand" "=R")
1840         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1841                          (const_int 8)
1842                          (const_int 8)))]
1843   ""
1844   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1845   [(set_attr "type" "imovx")
1846    (set_attr "mode" "SI")])
1847
1848 (define_insn "*movqi_extv_1"
1849   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1850         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1851                          (const_int 8)
1852                          (const_int 8)))]
1853   "!TARGET_64BIT"
1854 {
1855   switch (get_attr_type (insn))
1856     {
1857     case TYPE_IMOVX:
1858       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1859     default:
1860       return "mov{b}\t{%h1, %0|%0, %h1}";
1861     }
1862 }
1863   [(set (attr "type")
1864      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1865                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1866                              (ne (symbol_ref "TARGET_MOVX")
1867                                  (const_int 0))))
1868         (const_string "imovx")
1869         (const_string "imov")))
1870    (set (attr "mode")
1871      (if_then_else (eq_attr "type" "imovx")
1872         (const_string "SI")
1873         (const_string "QI")))])
1874
1875 (define_insn "*movqi_extv_1_rex64"
1876   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1877         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1878                          (const_int 8)
1879                          (const_int 8)))]
1880   "TARGET_64BIT"
1881 {
1882   switch (get_attr_type (insn))
1883     {
1884     case TYPE_IMOVX:
1885       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1886     default:
1887       return "mov{b}\t{%h1, %0|%0, %h1}";
1888     }
1889 }
1890   [(set (attr "type")
1891      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1892                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1893                              (ne (symbol_ref "TARGET_MOVX")
1894                                  (const_int 0))))
1895         (const_string "imovx")
1896         (const_string "imov")))
1897    (set (attr "mode")
1898      (if_then_else (eq_attr "type" "imovx")
1899         (const_string "SI")
1900         (const_string "QI")))])
1901
1902 ;; Stores and loads of ax to arbitrary constant address.
1903 ;; We fake an second form of instruction to force reload to load address
1904 ;; into register when rax is not available
1905 (define_insn "*movabsqi_1_rex64"
1906   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1907         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1908   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1909   "@
1910    movabs{b}\t{%1, %P0|%P0, %1}
1911    mov{b}\t{%1, %a0|%a0, %1}"
1912   [(set_attr "type" "imov")
1913    (set_attr "modrm" "0,*")
1914    (set_attr "length_address" "8,0")
1915    (set_attr "length_immediate" "0,*")
1916    (set_attr "memory" "store")
1917    (set_attr "mode" "QI")])
1918
1919 (define_insn "*movabsqi_2_rex64"
1920   [(set (match_operand:QI 0 "register_operand" "=a,r")
1921         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1922   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1923   "@
1924    movabs{b}\t{%P1, %0|%0, %P1}
1925    mov{b}\t{%a1, %0|%0, %a1}"
1926   [(set_attr "type" "imov")
1927    (set_attr "modrm" "0,*")
1928    (set_attr "length_address" "8,0")
1929    (set_attr "length_immediate" "0")
1930    (set_attr "memory" "load")
1931    (set_attr "mode" "QI")])
1932
1933 (define_insn "*movdi_extzv_1"
1934   [(set (match_operand:DI 0 "register_operand" "=R")
1935         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1936                          (const_int 8)
1937                          (const_int 8)))]
1938   "TARGET_64BIT"
1939   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1940   [(set_attr "type" "imovx")
1941    (set_attr "mode" "DI")])
1942
1943 (define_insn "*movsi_extzv_1"
1944   [(set (match_operand:SI 0 "register_operand" "=R")
1945         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1946                          (const_int 8)
1947                          (const_int 8)))]
1948   ""
1949   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1950   [(set_attr "type" "imovx")
1951    (set_attr "mode" "SI")])
1952
1953 (define_insn "*movqi_extzv_2"
1954   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1955         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1956                                     (const_int 8)
1957                                     (const_int 8)) 0))]
1958   "!TARGET_64BIT"
1959 {
1960   switch (get_attr_type (insn))
1961     {
1962     case TYPE_IMOVX:
1963       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1964     default:
1965       return "mov{b}\t{%h1, %0|%0, %h1}";
1966     }
1967 }
1968   [(set (attr "type")
1969      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1970                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1971                              (ne (symbol_ref "TARGET_MOVX")
1972                                  (const_int 0))))
1973         (const_string "imovx")
1974         (const_string "imov")))
1975    (set (attr "mode")
1976      (if_then_else (eq_attr "type" "imovx")
1977         (const_string "SI")
1978         (const_string "QI")))])
1979
1980 (define_insn "*movqi_extzv_2_rex64"
1981   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1982         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1983                                     (const_int 8)
1984                                     (const_int 8)) 0))]
1985   "TARGET_64BIT"
1986 {
1987   switch (get_attr_type (insn))
1988     {
1989     case TYPE_IMOVX:
1990       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1991     default:
1992       return "mov{b}\t{%h1, %0|%0, %h1}";
1993     }
1994 }
1995   [(set (attr "type")
1996      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1997                         (ne (symbol_ref "TARGET_MOVX")
1998                             (const_int 0)))
1999         (const_string "imovx")
2000         (const_string "imov")))
2001    (set (attr "mode")
2002      (if_then_else (eq_attr "type" "imovx")
2003         (const_string "SI")
2004         (const_string "QI")))])
2005
2006 (define_insn "movsi_insv_1"
2007   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2008                          (const_int 8)
2009                          (const_int 8))
2010         (match_operand:SI 1 "general_operand" "Qmn"))]
2011   "!TARGET_64BIT"
2012   "mov{b}\t{%b1, %h0|%h0, %b1}"
2013   [(set_attr "type" "imov")
2014    (set_attr "mode" "QI")])
2015
2016 (define_insn "*movsi_insv_1_rex64"
2017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2018                          (const_int 8)
2019                          (const_int 8))
2020         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2021   "TARGET_64BIT"
2022   "mov{b}\t{%b1, %h0|%h0, %b1}"
2023   [(set_attr "type" "imov")
2024    (set_attr "mode" "QI")])
2025
2026 (define_insn "movdi_insv_1_rex64"
2027   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2028                          (const_int 8)
2029                          (const_int 8))
2030         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2031   "TARGET_64BIT"
2032   "mov{b}\t{%b1, %h0|%h0, %b1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "mode" "QI")])
2035
2036 (define_insn "*movqi_insv_2"
2037   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2038                          (const_int 8)
2039                          (const_int 8))
2040         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2041                      (const_int 8)))]
2042   ""
2043   "mov{b}\t{%h1, %h0|%h0, %h1}"
2044   [(set_attr "type" "imov")
2045    (set_attr "mode" "QI")])
2046
2047 (define_expand "movdi"
2048   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2049         (match_operand:DI 1 "general_operand" ""))]
2050   ""
2051   "ix86_expand_move (DImode, operands); DONE;")
2052
2053 (define_insn "*pushdi"
2054   [(set (match_operand:DI 0 "push_operand" "=<")
2055         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2056   "!TARGET_64BIT"
2057   "#")
2058
2059 (define_insn "*pushdi2_rex64"
2060   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2061         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2062   "TARGET_64BIT"
2063   "@
2064    push{q}\t%1
2065    #"
2066   [(set_attr "type" "push,multi")
2067    (set_attr "mode" "DI")])
2068
2069 ;; Convert impossible pushes of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it.  In case this
2071 ;; fails, push sign extended lower part first and then overwrite
2072 ;; upper part by 32bit move.
2073 (define_peephole2
2074   [(match_scratch:DI 2 "r")
2075    (set (match_operand:DI 0 "push_operand" "")
2076         (match_operand:DI 1 "immediate_operand" ""))]
2077   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078    && !x86_64_immediate_operand (operands[1], DImode)"
2079   [(set (match_dup 2) (match_dup 1))
2080    (set (match_dup 0) (match_dup 2))]
2081   "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2086 (define_peephole2
2087   [(set (match_operand:DI 0 "push_operand" "")
2088         (match_operand:DI 1 "immediate_operand" ""))]
2089   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091   [(set (match_dup 0) (match_dup 1))
2092    (set (match_dup 2) (match_dup 3))]
2093   "split_di (operands + 1, 1, operands + 2, operands + 3);
2094    operands[1] = gen_lowpart (DImode, operands[2]);
2095    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2096                                                     GEN_INT (4)));
2097   ")
2098
2099 (define_split
2100   [(set (match_operand:DI 0 "push_operand" "")
2101         (match_operand:DI 1 "immediate_operand" ""))]
2102   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2103                     ? epilogue_completed : reload_completed)
2104    && !symbolic_operand (operands[1], DImode)
2105    && !x86_64_immediate_operand (operands[1], DImode)"
2106   [(set (match_dup 0) (match_dup 1))
2107    (set (match_dup 2) (match_dup 3))]
2108   "split_di (operands + 1, 1, operands + 2, operands + 3);
2109    operands[1] = gen_lowpart (DImode, operands[2]);
2110    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2111                                                     GEN_INT (4)));
2112   ")
2113
2114 (define_insn "*pushdi2_prologue_rex64"
2115   [(set (match_operand:DI 0 "push_operand" "=<")
2116         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2117    (clobber (mem:BLK (scratch)))]
2118   "TARGET_64BIT"
2119   "push{q}\t%1"
2120   [(set_attr "type" "push")
2121    (set_attr "mode" "DI")])
2122
2123 (define_insn "*popdi1_epilogue_rex64"
2124   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2125         (mem:DI (reg:DI SP_REG)))
2126    (set (reg:DI SP_REG)
2127         (plus:DI (reg:DI SP_REG) (const_int 8)))
2128    (clobber (mem:BLK (scratch)))]
2129   "TARGET_64BIT"
2130   "pop{q}\t%0"
2131   [(set_attr "type" "pop")
2132    (set_attr "mode" "DI")])
2133
2134 (define_insn "popdi1"
2135   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2136         (mem:DI (reg:DI SP_REG)))
2137    (set (reg:DI SP_REG)
2138         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2139   "TARGET_64BIT"
2140   "pop{q}\t%0"
2141   [(set_attr "type" "pop")
2142    (set_attr "mode" "DI")])
2143
2144 (define_insn "*movdi_xor_rex64"
2145   [(set (match_operand:DI 0 "register_operand" "=r")
2146         (match_operand:DI 1 "const0_operand" "i"))
2147    (clobber (reg:CC FLAGS_REG))]
2148   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2149    && reload_completed"
2150   "xor{l}\t%k0, %k0";
2151   [(set_attr "type" "alu1")
2152    (set_attr "mode" "SI")
2153    (set_attr "length_immediate" "0")])
2154
2155 (define_insn "*movdi_or_rex64"
2156   [(set (match_operand:DI 0 "register_operand" "=r")
2157         (match_operand:DI 1 "const_int_operand" "i"))
2158    (clobber (reg:CC FLAGS_REG))]
2159   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2160    && reload_completed
2161    && operands[1] == constm1_rtx"
2162 {
2163   operands[1] = constm1_rtx;
2164   return "or{q}\t{%1, %0|%0, %1}";
2165 }
2166   [(set_attr "type" "alu1")
2167    (set_attr "mode" "DI")
2168    (set_attr "length_immediate" "1")])
2169
2170 (define_insn "*movdi_2"
2171   [(set (match_operand:DI 0 "nonimmediate_operand"
2172                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2173         (match_operand:DI 1 "general_operand"
2174                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2175   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2176   "@
2177    #
2178    #
2179    pxor\t%0, %0
2180    movq\t{%1, %0|%0, %1}
2181    movq\t{%1, %0|%0, %1}
2182    pxor\t%0, %0
2183    movq\t{%1, %0|%0, %1}
2184    movdqa\t{%1, %0|%0, %1}
2185    movq\t{%1, %0|%0, %1}
2186    xorps\t%0, %0
2187    movlps\t{%1, %0|%0, %1}
2188    movaps\t{%1, %0|%0, %1}
2189    movlps\t{%1, %0|%0, %1}"
2190   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2191    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2192
2193 (define_split
2194   [(set (match_operand:DI 0 "push_operand" "")
2195         (match_operand:DI 1 "general_operand" ""))]
2196   "!TARGET_64BIT && reload_completed
2197    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2198   [(const_int 0)]
2199   "ix86_split_long_move (operands); DONE;")
2200
2201 ;; %%% This multiword shite has got to go.
2202 (define_split
2203   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2204         (match_operand:DI 1 "general_operand" ""))]
2205   "!TARGET_64BIT && reload_completed
2206    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2207    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2208   [(const_int 0)]
2209   "ix86_split_long_move (operands); DONE;")
2210
2211 (define_insn "*movdi_1_rex64"
2212   [(set (match_operand:DI 0 "nonimmediate_operand"
2213           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2214         (match_operand:DI 1 "general_operand"
2215           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2216   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 {
2218   switch (get_attr_type (insn))
2219     {
2220     case TYPE_SSECVT:
2221       if (SSE_REG_P (operands[0]))
2222         return "movq2dq\t{%1, %0|%0, %1}";
2223       else
2224         return "movdq2q\t{%1, %0|%0, %1}";
2225
2226     case TYPE_SSEMOV:
2227       if (get_attr_mode (insn) == MODE_TI)
2228         return "movdqa\t{%1, %0|%0, %1}";
2229       /* FALLTHRU */
2230
2231     case TYPE_MMXMOV:
2232       /* Moves from and into integer register is done using movd
2233          opcode with REX prefix.  */
2234       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2235         return "movd\t{%1, %0|%0, %1}";
2236       return "movq\t{%1, %0|%0, %1}";
2237
2238     case TYPE_SSELOG1:
2239     case TYPE_MMXADD:
2240       return "pxor\t%0, %0";
2241
2242     case TYPE_MULTI:
2243       return "#";
2244
2245     case TYPE_LEA:
2246       return "lea{q}\t{%a1, %0|%0, %a1}";
2247
2248     default:
2249       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2250       if (get_attr_mode (insn) == MODE_SI)
2251         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2252       else if (which_alternative == 2)
2253         return "movabs{q}\t{%1, %0|%0, %1}";
2254       else
2255         return "mov{q}\t{%1, %0|%0, %1}";
2256     }
2257 }
2258   [(set (attr "type")
2259      (cond [(eq_attr "alternative" "5")
2260               (const_string "mmxadd")
2261             (eq_attr "alternative" "6,7,8,9,10")
2262               (const_string "mmxmov")
2263             (eq_attr "alternative" "11")
2264               (const_string "sselog1")
2265             (eq_attr "alternative" "12,13,14,15,16")
2266               (const_string "ssemov")
2267             (eq_attr "alternative" "17,18")
2268               (const_string "ssecvt")
2269             (eq_attr "alternative" "4")
2270               (const_string "multi")
2271             (match_operand:DI 1 "pic_32bit_operand" "")
2272               (const_string "lea")
2273            ]
2274            (const_string "imov")))
2275    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2276    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2277    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2278
2279 ;; Stores and loads of ax to arbitrary constant address.
2280 ;; We fake an second form of instruction to force reload to load address
2281 ;; into register when rax is not available
2282 (define_insn "*movabsdi_1_rex64"
2283   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2284         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2285   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2286   "@
2287    movabs{q}\t{%1, %P0|%P0, %1}
2288    mov{q}\t{%1, %a0|%a0, %1}"
2289   [(set_attr "type" "imov")
2290    (set_attr "modrm" "0,*")
2291    (set_attr "length_address" "8,0")
2292    (set_attr "length_immediate" "0,*")
2293    (set_attr "memory" "store")
2294    (set_attr "mode" "DI")])
2295
2296 (define_insn "*movabsdi_2_rex64"
2297   [(set (match_operand:DI 0 "register_operand" "=a,r")
2298         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2299   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2300   "@
2301    movabs{q}\t{%P1, %0|%0, %P1}
2302    mov{q}\t{%a1, %0|%0, %a1}"
2303   [(set_attr "type" "imov")
2304    (set_attr "modrm" "0,*")
2305    (set_attr "length_address" "8,0")
2306    (set_attr "length_immediate" "0")
2307    (set_attr "memory" "load")
2308    (set_attr "mode" "DI")])
2309
2310 ;; Convert impossible stores of immediate to existing instructions.
2311 ;; First try to get scratch register and go through it.  In case this
2312 ;; fails, move by 32bit parts.
2313 (define_peephole2
2314   [(match_scratch:DI 2 "r")
2315    (set (match_operand:DI 0 "memory_operand" "")
2316         (match_operand:DI 1 "immediate_operand" ""))]
2317   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2318    && !x86_64_immediate_operand (operands[1], DImode)"
2319   [(set (match_dup 2) (match_dup 1))
2320    (set (match_dup 0) (match_dup 2))]
2321   "")
2322
2323 ;; We need to define this as both peepholer and splitter for case
2324 ;; peephole2 pass is not run.
2325 ;; "&& 1" is needed to keep it from matching the previous pattern.
2326 (define_peephole2
2327   [(set (match_operand:DI 0 "memory_operand" "")
2328         (match_operand:DI 1 "immediate_operand" ""))]
2329   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2330    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2331   [(set (match_dup 2) (match_dup 3))
2332    (set (match_dup 4) (match_dup 5))]
2333   "split_di (operands, 2, operands + 2, operands + 4);")
2334
2335 (define_split
2336   [(set (match_operand:DI 0 "memory_operand" "")
2337         (match_operand:DI 1 "immediate_operand" ""))]
2338   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339                     ? epilogue_completed : reload_completed)
2340    && !symbolic_operand (operands[1], DImode)
2341    && !x86_64_immediate_operand (operands[1], DImode)"
2342   [(set (match_dup 2) (match_dup 3))
2343    (set (match_dup 4) (match_dup 5))]
2344   "split_di (operands, 2, operands + 2, operands + 4);")
2345
2346 (define_insn "*swapdi_rex64"
2347   [(set (match_operand:DI 0 "register_operand" "+r")
2348         (match_operand:DI 1 "register_operand" "+r"))
2349    (set (match_dup 1)
2350         (match_dup 0))]
2351   "TARGET_64BIT"
2352   "xchg{q}\t%1, %0"
2353   [(set_attr "type" "imov")
2354    (set_attr "mode" "DI")
2355    (set_attr "pent_pair" "np")
2356    (set_attr "athlon_decode" "vector")
2357    (set_attr "amdfam10_decode" "double")])
2358
2359 (define_expand "movti"
2360   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2361         (match_operand:TI 1 "nonimmediate_operand" ""))]
2362   "TARGET_SSE || TARGET_64BIT"
2363 {
2364   if (TARGET_64BIT)
2365     ix86_expand_move (TImode, operands);
2366   else if (push_operand (operands[0], TImode))
2367     ix86_expand_push (TImode, operands[1]);
2368   else
2369     ix86_expand_vector_move (TImode, operands);
2370   DONE;
2371 })
2372
2373 (define_insn "*movti_internal"
2374   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2375         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2376   "TARGET_SSE && !TARGET_64BIT
2377    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2378 {
2379   switch (which_alternative)
2380     {
2381     case 0:
2382       if (get_attr_mode (insn) == MODE_V4SF)
2383         return "xorps\t%0, %0";
2384       else
2385         return "pxor\t%0, %0";
2386     case 1:
2387     case 2:
2388       if (get_attr_mode (insn) == MODE_V4SF)
2389         return "movaps\t{%1, %0|%0, %1}";
2390       else
2391         return "movdqa\t{%1, %0|%0, %1}";
2392     default:
2393       gcc_unreachable ();
2394     }
2395 }
2396   [(set_attr "type" "sselog1,ssemov,ssemov")
2397    (set (attr "mode")
2398         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2399                     (ne (symbol_ref "optimize_size") (const_int 0)))
2400                  (const_string "V4SF")
2401                (and (eq_attr "alternative" "2")
2402                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2403                         (const_int 0)))
2404                  (const_string "V4SF")]
2405               (const_string "TI")))])
2406
2407 (define_insn "*movti_rex64"
2408   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2409         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2410   "TARGET_64BIT
2411    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2412 {
2413   switch (which_alternative)
2414     {
2415     case 0:
2416     case 1:
2417       return "#";
2418     case 2:
2419       if (get_attr_mode (insn) == MODE_V4SF)
2420         return "xorps\t%0, %0";
2421       else
2422         return "pxor\t%0, %0";
2423     case 3:
2424     case 4:
2425       if (get_attr_mode (insn) == MODE_V4SF)
2426         return "movaps\t{%1, %0|%0, %1}";
2427       else
2428         return "movdqa\t{%1, %0|%0, %1}";
2429     default:
2430       gcc_unreachable ();
2431     }
2432 }
2433   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2434    (set (attr "mode")
2435         (cond [(eq_attr "alternative" "2,3")
2436                  (if_then_else
2437                    (ne (symbol_ref "optimize_size")
2438                        (const_int 0))
2439                    (const_string "V4SF")
2440                    (const_string "TI"))
2441                (eq_attr "alternative" "4")
2442                  (if_then_else
2443                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2444                             (const_int 0))
2445                         (ne (symbol_ref "optimize_size")
2446                             (const_int 0)))
2447                    (const_string "V4SF")
2448                    (const_string "TI"))]
2449                (const_string "DI")))])
2450
2451 (define_split
2452   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2453         (match_operand:TI 1 "general_operand" ""))]
2454   "reload_completed && !SSE_REG_P (operands[0])
2455    && !SSE_REG_P (operands[1])"
2456   [(const_int 0)]
2457   "ix86_split_long_move (operands); DONE;")
2458
2459 ;; This expands to what emit_move_complex would generate if we didn't
2460 ;; have a movti pattern.  Having this avoids problems with reload on
2461 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2462 ;; to have around all the time.
2463 (define_expand "movcdi"
2464   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2465         (match_operand:CDI 1 "general_operand" ""))]
2466   ""
2467 {
2468   if (push_operand (operands[0], CDImode))
2469     emit_move_complex_push (CDImode, operands[0], operands[1]);
2470   else
2471     emit_move_complex_parts (operands[0], operands[1]);
2472   DONE;
2473 })
2474
2475 (define_expand "movsf"
2476   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2477         (match_operand:SF 1 "general_operand" ""))]
2478   ""
2479   "ix86_expand_move (SFmode, operands); DONE;")
2480
2481 (define_insn "*pushsf"
2482   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2483         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2484   "!TARGET_64BIT"
2485 {
2486   /* Anything else should be already split before reg-stack.  */
2487   gcc_assert (which_alternative == 1);
2488   return "push{l}\t%1";
2489 }
2490   [(set_attr "type" "multi,push,multi")
2491    (set_attr "unit" "i387,*,*")
2492    (set_attr "mode" "SF,SI,SF")])
2493
2494 (define_insn "*pushsf_rex64"
2495   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2496         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2497   "TARGET_64BIT"
2498 {
2499   /* Anything else should be already split before reg-stack.  */
2500   gcc_assert (which_alternative == 1);
2501   return "push{q}\t%q1";
2502 }
2503   [(set_attr "type" "multi,push,multi")
2504    (set_attr "unit" "i387,*,*")
2505    (set_attr "mode" "SF,DI,SF")])
2506
2507 (define_split
2508   [(set (match_operand:SF 0 "push_operand" "")
2509         (match_operand:SF 1 "memory_operand" ""))]
2510   "reload_completed
2511    && MEM_P (operands[1])
2512    && (operands[2] = find_constant_src (insn))"
2513   [(set (match_dup 0)
2514         (match_dup 2))])
2515
2516
2517 ;; %%% Kill this when call knows how to work this out.
2518 (define_split
2519   [(set (match_operand:SF 0 "push_operand" "")
2520         (match_operand:SF 1 "any_fp_register_operand" ""))]
2521   "!TARGET_64BIT"
2522   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2523    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2524
2525 (define_split
2526   [(set (match_operand:SF 0 "push_operand" "")
2527         (match_operand:SF 1 "any_fp_register_operand" ""))]
2528   "TARGET_64BIT"
2529   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2530    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2531
2532 (define_insn "*movsf_1"
2533   [(set (match_operand:SF 0 "nonimmediate_operand"
2534           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2535         (match_operand:SF 1 "general_operand"
2536           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2537   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2538    && (reload_in_progress || reload_completed
2539        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2540        || (!TARGET_SSE_MATH && optimize_size
2541            && standard_80387_constant_p (operands[1]))
2542        || GET_CODE (operands[1]) != CONST_DOUBLE
2543        || memory_operand (operands[0], SFmode))"
2544 {
2545   switch (which_alternative)
2546     {
2547     case 0:
2548     case 1:
2549       return output_387_reg_move (insn, operands);
2550
2551     case 2:
2552       return standard_80387_constant_opcode (operands[1]);
2553
2554     case 3:
2555     case 4:
2556       return "mov{l}\t{%1, %0|%0, %1}";
2557     case 5:
2558       if (get_attr_mode (insn) == MODE_TI)
2559         return "pxor\t%0, %0";
2560       else
2561         return "xorps\t%0, %0";
2562     case 6:
2563       if (get_attr_mode (insn) == MODE_V4SF)
2564         return "movaps\t{%1, %0|%0, %1}";
2565       else
2566         return "movss\t{%1, %0|%0, %1}";
2567     case 7: case 8:
2568       return "movss\t{%1, %0|%0, %1}";
2569
2570     case 9: case 10:
2571     case 12: case 13: case 14: case 15:
2572       return "movd\t{%1, %0|%0, %1}";
2573
2574     case 11:
2575       return "movq\t{%1, %0|%0, %1}";
2576
2577     default:
2578       gcc_unreachable ();
2579     }
2580 }
2581   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2582    (set (attr "mode")
2583         (cond [(eq_attr "alternative" "3,4,9,10")
2584                  (const_string "SI")
2585                (eq_attr "alternative" "5")
2586                  (if_then_else
2587                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588                                  (const_int 0))
2589                              (ne (symbol_ref "TARGET_SSE2")
2590                                  (const_int 0)))
2591                         (eq (symbol_ref "optimize_size")
2592                             (const_int 0)))
2593                    (const_string "TI")
2594                    (const_string "V4SF"))
2595                /* For architectures resolving dependencies on
2596                   whole SSE registers use APS move to break dependency
2597                   chains, otherwise use short move to avoid extra work.
2598
2599                   Do the same for architectures resolving dependencies on
2600                   the parts.  While in DF mode it is better to always handle
2601                   just register parts, the SF mode is different due to lack
2602                   of instructions to load just part of the register.  It is
2603                   better to maintain the whole registers in single format
2604                   to avoid problems on using packed logical operations.  */
2605                (eq_attr "alternative" "6")
2606                  (if_then_else
2607                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2608                             (const_int 0))
2609                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2610                             (const_int 0)))
2611                    (const_string "V4SF")
2612                    (const_string "SF"))
2613                (eq_attr "alternative" "11")
2614                  (const_string "DI")]
2615                (const_string "SF")))])
2616
2617 (define_insn "*swapsf"
2618   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2619         (match_operand:SF 1 "fp_register_operand" "+f"))
2620    (set (match_dup 1)
2621         (match_dup 0))]
2622   "reload_completed || TARGET_80387"
2623 {
2624   if (STACK_TOP_P (operands[0]))
2625     return "fxch\t%1";
2626   else
2627     return "fxch\t%0";
2628 }
2629   [(set_attr "type" "fxch")
2630    (set_attr "mode" "SF")])
2631
2632 (define_expand "movdf"
2633   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2634         (match_operand:DF 1 "general_operand" ""))]
2635   ""
2636   "ix86_expand_move (DFmode, operands); DONE;")
2637
2638 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2639 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2640 ;; On the average, pushdf using integers can be still shorter.  Allow this
2641 ;; pattern for optimize_size too.
2642
2643 (define_insn "*pushdf_nointeger"
2644   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2645         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2646   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2647 {
2648   /* This insn should be already split before reg-stack.  */
2649   gcc_unreachable ();
2650 }
2651   [(set_attr "type" "multi")
2652    (set_attr "unit" "i387,*,*,*")
2653    (set_attr "mode" "DF,SI,SI,DF")])
2654
2655 (define_insn "*pushdf_integer"
2656   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2657         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2658   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2659 {
2660   /* This insn should be already split before reg-stack.  */
2661   gcc_unreachable ();
2662 }
2663   [(set_attr "type" "multi")
2664    (set_attr "unit" "i387,*,*")
2665    (set_attr "mode" "DF,SI,DF")])
2666
2667 ;; %%% Kill this when call knows how to work this out.
2668 (define_split
2669   [(set (match_operand:DF 0 "push_operand" "")
2670         (match_operand:DF 1 "any_fp_register_operand" ""))]
2671   "!TARGET_64BIT && reload_completed"
2672   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2673    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2674   "")
2675
2676 (define_split
2677   [(set (match_operand:DF 0 "push_operand" "")
2678         (match_operand:DF 1 "any_fp_register_operand" ""))]
2679   "TARGET_64BIT && reload_completed"
2680   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2681    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2682   "")
2683
2684 (define_split
2685   [(set (match_operand:DF 0 "push_operand" "")
2686         (match_operand:DF 1 "general_operand" ""))]
2687   "reload_completed"
2688   [(const_int 0)]
2689   "ix86_split_long_move (operands); DONE;")
2690
2691 ;; Moving is usually shorter when only FP registers are used. This separate
2692 ;; movdf pattern avoids the use of integer registers for FP operations
2693 ;; when optimizing for size.
2694
2695 (define_insn "*movdf_nointeger"
2696   [(set (match_operand:DF 0 "nonimmediate_operand"
2697                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2698         (match_operand:DF 1 "general_operand"
2699                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2700   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2701    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2702    && (reload_in_progress || reload_completed
2703        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2704        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2705            && !memory_operand (operands[0], DFmode)
2706            && standard_80387_constant_p (operands[1]))
2707        || GET_CODE (operands[1]) != CONST_DOUBLE
2708        || ((optimize_size
2709             || !TARGET_MEMORY_MISMATCH_STALL
2710             || reload_in_progress || reload_completed)
2711            && memory_operand (operands[0], DFmode)))"
2712 {
2713   switch (which_alternative)
2714     {
2715     case 0:
2716     case 1:
2717       return output_387_reg_move (insn, operands);
2718
2719     case 2:
2720       return standard_80387_constant_opcode (operands[1]);
2721
2722     case 3:
2723     case 4:
2724       return "#";
2725     case 5:
2726       switch (get_attr_mode (insn))
2727         {
2728         case MODE_V4SF:
2729           return "xorps\t%0, %0";
2730         case MODE_V2DF:
2731           return "xorpd\t%0, %0";
2732         case MODE_TI:
2733           return "pxor\t%0, %0";
2734         default:
2735           gcc_unreachable ();
2736         }
2737     case 6:
2738     case 7:
2739     case 8:
2740       switch (get_attr_mode (insn))
2741         {
2742         case MODE_V4SF:
2743           return "movaps\t{%1, %0|%0, %1}";
2744         case MODE_V2DF:
2745           return "movapd\t{%1, %0|%0, %1}";
2746         case MODE_TI:
2747           return "movdqa\t{%1, %0|%0, %1}";
2748         case MODE_DI:
2749           return "movq\t{%1, %0|%0, %1}";
2750         case MODE_DF:
2751           return "movsd\t{%1, %0|%0, %1}";
2752         case MODE_V1DF:
2753           return "movlpd\t{%1, %0|%0, %1}";
2754         case MODE_V2SF:
2755           return "movlps\t{%1, %0|%0, %1}";
2756         default:
2757           gcc_unreachable ();
2758         }
2759
2760     default:
2761       gcc_unreachable ();
2762     }
2763 }
2764   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2765    (set (attr "mode")
2766         (cond [(eq_attr "alternative" "0,1,2")
2767                  (const_string "DF")
2768                (eq_attr "alternative" "3,4")
2769                  (const_string "SI")
2770
2771                /* For SSE1, we have many fewer alternatives.  */
2772                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2773                  (cond [(eq_attr "alternative" "5,6")
2774                           (const_string "V4SF")
2775                        ]
2776                    (const_string "V2SF"))
2777
2778                /* xorps is one byte shorter.  */
2779                (eq_attr "alternative" "5")
2780                  (cond [(ne (symbol_ref "optimize_size")
2781                             (const_int 0))
2782                           (const_string "V4SF")
2783                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2784                             (const_int 0))
2785                           (const_string "TI")
2786                        ]
2787                        (const_string "V2DF"))
2788
2789                /* For architectures resolving dependencies on
2790                   whole SSE registers use APD move to break dependency
2791                   chains, otherwise use short move to avoid extra work.
2792
2793                   movaps encodes one byte shorter.  */
2794                (eq_attr "alternative" "6")
2795                  (cond
2796                    [(ne (symbol_ref "optimize_size")
2797                         (const_int 0))
2798                       (const_string "V4SF")
2799                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2800                         (const_int 0))
2801                       (const_string "V2DF")
2802                    ]
2803                    (const_string "DF"))
2804                /* For architectures resolving dependencies on register
2805                   parts we may avoid extra work to zero out upper part
2806                   of register.  */
2807                (eq_attr "alternative" "7")
2808                  (if_then_else
2809                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2810                        (const_int 0))
2811                    (const_string "V1DF")
2812                    (const_string "DF"))
2813               ]
2814               (const_string "DF")))])
2815
2816 (define_insn "*movdf_integer_rex64"
2817   [(set (match_operand:DF 0 "nonimmediate_operand"
2818                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2819         (match_operand:DF 1 "general_operand"
2820                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2821   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2822    && (reload_in_progress || reload_completed
2823        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2824        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2825            && standard_80387_constant_p (operands[1]))
2826        || GET_CODE (operands[1]) != CONST_DOUBLE
2827        || memory_operand (operands[0], DFmode))"
2828 {
2829   switch (which_alternative)
2830     {
2831     case 0:
2832     case 1:
2833       return output_387_reg_move (insn, operands);
2834
2835     case 2:
2836       return standard_80387_constant_opcode (operands[1]);
2837
2838     case 3:
2839     case 4:
2840       return "#";
2841
2842     case 5:
2843       switch (get_attr_mode (insn))
2844         {
2845         case MODE_V4SF:
2846           return "xorps\t%0, %0";
2847         case MODE_V2DF:
2848           return "xorpd\t%0, %0";
2849         case MODE_TI:
2850           return "pxor\t%0, %0";
2851         default:
2852           gcc_unreachable ();
2853         }
2854     case 6:
2855     case 7:
2856     case 8:
2857       switch (get_attr_mode (insn))
2858         {
2859         case MODE_V4SF:
2860           return "movaps\t{%1, %0|%0, %1}";
2861         case MODE_V2DF:
2862           return "movapd\t{%1, %0|%0, %1}";
2863         case MODE_TI:
2864           return "movdqa\t{%1, %0|%0, %1}";
2865         case MODE_DI:
2866           return "movq\t{%1, %0|%0, %1}";
2867         case MODE_DF:
2868           return "movsd\t{%1, %0|%0, %1}";
2869         case MODE_V1DF:
2870           return "movlpd\t{%1, %0|%0, %1}";
2871         case MODE_V2SF:
2872           return "movlps\t{%1, %0|%0, %1}";
2873         default:
2874           gcc_unreachable ();
2875         }
2876
2877     case 9:
2878     case 10:
2879       return "movd\t{%1, %0|%0, %1}";
2880
2881     default:
2882       gcc_unreachable();
2883     }
2884 }
2885   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2886    (set (attr "mode")
2887         (cond [(eq_attr "alternative" "0,1,2")
2888                  (const_string "DF")
2889                (eq_attr "alternative" "3,4,9,10")
2890                  (const_string "DI")
2891
2892                /* For SSE1, we have many fewer alternatives.  */
2893                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2894                  (cond [(eq_attr "alternative" "5,6")
2895                           (const_string "V4SF")
2896                        ]
2897                    (const_string "V2SF"))
2898
2899                /* xorps is one byte shorter.  */
2900                (eq_attr "alternative" "5")
2901                  (cond [(ne (symbol_ref "optimize_size")
2902                             (const_int 0))
2903                           (const_string "V4SF")
2904                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2905                             (const_int 0))
2906                           (const_string "TI")
2907                        ]
2908                        (const_string "V2DF"))
2909
2910                /* For architectures resolving dependencies on
2911                   whole SSE registers use APD move to break dependency
2912                   chains, otherwise use short move to avoid extra work.
2913
2914                   movaps encodes one byte shorter.  */
2915                (eq_attr "alternative" "6")
2916                  (cond
2917                    [(ne (symbol_ref "optimize_size")
2918                         (const_int 0))
2919                       (const_string "V4SF")
2920                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2921                         (const_int 0))
2922                       (const_string "V2DF")
2923                    ]
2924                    (const_string "DF"))
2925                /* For architectures resolving dependencies on register
2926                   parts we may avoid extra work to zero out upper part
2927                   of register.  */
2928                (eq_attr "alternative" "7")
2929                  (if_then_else
2930                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2931                        (const_int 0))
2932                    (const_string "V1DF")
2933                    (const_string "DF"))
2934               ]
2935               (const_string "DF")))])
2936
2937 (define_insn "*movdf_integer"
2938   [(set (match_operand:DF 0 "nonimmediate_operand"
2939                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2940         (match_operand:DF 1 "general_operand"
2941                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2942   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2943    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2944    && (reload_in_progress || reload_completed
2945        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2946        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2947            && standard_80387_constant_p (operands[1]))
2948        || GET_CODE (operands[1]) != CONST_DOUBLE
2949        || memory_operand (operands[0], DFmode))"
2950 {
2951   switch (which_alternative)
2952     {
2953     case 0:
2954     case 1:
2955       return output_387_reg_move (insn, operands);
2956
2957     case 2:
2958       return standard_80387_constant_opcode (operands[1]);
2959
2960     case 3:
2961     case 4:
2962       return "#";
2963
2964     case 5:
2965       switch (get_attr_mode (insn))
2966         {
2967         case MODE_V4SF:
2968           return "xorps\t%0, %0";
2969         case MODE_V2DF:
2970           return "xorpd\t%0, %0";
2971         case MODE_TI:
2972           return "pxor\t%0, %0";
2973         default:
2974           gcc_unreachable ();
2975         }
2976     case 6:
2977     case 7:
2978     case 8:
2979       switch (get_attr_mode (insn))
2980         {
2981         case MODE_V4SF:
2982           return "movaps\t{%1, %0|%0, %1}";
2983         case MODE_V2DF:
2984           return "movapd\t{%1, %0|%0, %1}";
2985         case MODE_TI:
2986           return "movdqa\t{%1, %0|%0, %1}";
2987         case MODE_DI:
2988           return "movq\t{%1, %0|%0, %1}";
2989         case MODE_DF:
2990           return "movsd\t{%1, %0|%0, %1}";
2991         case MODE_V1DF:
2992           return "movlpd\t{%1, %0|%0, %1}";
2993         case MODE_V2SF:
2994           return "movlps\t{%1, %0|%0, %1}";
2995         default:
2996           gcc_unreachable ();
2997         }
2998
2999     default:
3000       gcc_unreachable();
3001     }
3002 }
3003   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3004    (set (attr "mode")
3005         (cond [(eq_attr "alternative" "0,1,2")
3006                  (const_string "DF")
3007                (eq_attr "alternative" "3,4")
3008                  (const_string "SI")
3009
3010                /* For SSE1, we have many fewer alternatives.  */
3011                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3012                  (cond [(eq_attr "alternative" "5,6")
3013                           (const_string "V4SF")
3014                        ]
3015                    (const_string "V2SF"))
3016
3017                /* xorps is one byte shorter.  */
3018                (eq_attr "alternative" "5")
3019                  (cond [(ne (symbol_ref "optimize_size")
3020                             (const_int 0))
3021                           (const_string "V4SF")
3022                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3023                             (const_int 0))
3024                           (const_string "TI")
3025                        ]
3026                        (const_string "V2DF"))
3027
3028                /* For architectures resolving dependencies on
3029                   whole SSE registers use APD move to break dependency
3030                   chains, otherwise use short move to avoid extra work.
3031
3032                   movaps encodes one byte shorter.  */
3033                (eq_attr "alternative" "6")
3034                  (cond
3035                    [(ne (symbol_ref "optimize_size")
3036                         (const_int 0))
3037                       (const_string "V4SF")
3038                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3039                         (const_int 0))
3040                       (const_string "V2DF")
3041                    ]
3042                    (const_string "DF"))
3043                /* For architectures resolving dependencies on register
3044                   parts we may avoid extra work to zero out upper part
3045                   of register.  */
3046                (eq_attr "alternative" "7")
3047                  (if_then_else
3048                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3049                        (const_int 0))
3050                    (const_string "V1DF")
3051                    (const_string "DF"))
3052               ]
3053               (const_string "DF")))])
3054
3055 (define_split
3056   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3057         (match_operand:DF 1 "general_operand" ""))]
3058   "reload_completed
3059    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3060    && ! (ANY_FP_REG_P (operands[0]) ||
3061          (GET_CODE (operands[0]) == SUBREG
3062           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3063    && ! (ANY_FP_REG_P (operands[1]) ||
3064          (GET_CODE (operands[1]) == SUBREG
3065           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3066   [(const_int 0)]
3067   "ix86_split_long_move (operands); DONE;")
3068
3069 (define_insn "*swapdf"
3070   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3071         (match_operand:DF 1 "fp_register_operand" "+f"))
3072    (set (match_dup 1)
3073         (match_dup 0))]
3074   "reload_completed || TARGET_80387"
3075 {
3076   if (STACK_TOP_P (operands[0]))
3077     return "fxch\t%1";
3078   else
3079     return "fxch\t%0";
3080 }
3081   [(set_attr "type" "fxch")
3082    (set_attr "mode" "DF")])
3083
3084 (define_expand "movxf"
3085   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3086         (match_operand:XF 1 "general_operand" ""))]
3087   ""
3088   "ix86_expand_move (XFmode, operands); DONE;")
3089
3090 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3091 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3092 ;; Pushing using integer instructions is longer except for constants
3093 ;; and direct memory references.
3094 ;; (assuming that any given constant is pushed only once, but this ought to be
3095 ;;  handled elsewhere).
3096
3097 (define_insn "*pushxf_nointeger"
3098   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3099         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3100   "optimize_size"
3101 {
3102   /* This insn should be already split before reg-stack.  */
3103   gcc_unreachable ();
3104 }
3105   [(set_attr "type" "multi")
3106    (set_attr "unit" "i387,*,*")
3107    (set_attr "mode" "XF,SI,SI")])
3108
3109 (define_insn "*pushxf_integer"
3110   [(set (match_operand:XF 0 "push_operand" "=<,<")
3111         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3112   "!optimize_size"
3113 {
3114   /* This insn should be already split before reg-stack.  */
3115   gcc_unreachable ();
3116 }
3117   [(set_attr "type" "multi")
3118    (set_attr "unit" "i387,*")
3119    (set_attr "mode" "XF,SI")])
3120
3121 (define_split
3122   [(set (match_operand 0 "push_operand" "")
3123         (match_operand 1 "general_operand" ""))]
3124   "reload_completed
3125    && (GET_MODE (operands[0]) == XFmode
3126        || GET_MODE (operands[0]) == DFmode)
3127    && !ANY_FP_REG_P (operands[1])"
3128   [(const_int 0)]
3129   "ix86_split_long_move (operands); DONE;")
3130
3131 (define_split
3132   [(set (match_operand:XF 0 "push_operand" "")
3133         (match_operand:XF 1 "any_fp_register_operand" ""))]
3134   "!TARGET_64BIT"
3135   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3136    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3137   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3138
3139 (define_split
3140   [(set (match_operand:XF 0 "push_operand" "")
3141         (match_operand:XF 1 "any_fp_register_operand" ""))]
3142   "TARGET_64BIT"
3143   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3144    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3145   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3146
3147 ;; Do not use integer registers when optimizing for size
3148 (define_insn "*movxf_nointeger"
3149   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3150         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3151   "optimize_size
3152    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3153    && (reload_in_progress || reload_completed
3154        || (optimize_size && standard_80387_constant_p (operands[1]))
3155        || GET_CODE (operands[1]) != CONST_DOUBLE
3156        || memory_operand (operands[0], XFmode))"
3157 {
3158   switch (which_alternative)
3159     {
3160     case 0:
3161     case 1:
3162       return output_387_reg_move (insn, operands);
3163
3164     case 2:
3165       return standard_80387_constant_opcode (operands[1]);
3166
3167     case 3: case 4:
3168       return "#";
3169     default:
3170       gcc_unreachable ();
3171     }
3172 }
3173   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3174    (set_attr "mode" "XF,XF,XF,SI,SI")])
3175
3176 (define_insn "*movxf_integer"
3177   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3178         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3179   "!optimize_size
3180    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181    && (reload_in_progress || reload_completed
3182        || (optimize_size && standard_80387_constant_p (operands[1]))
3183        || GET_CODE (operands[1]) != CONST_DOUBLE
3184        || memory_operand (operands[0], XFmode))"
3185 {
3186   switch (which_alternative)
3187     {
3188     case 0:
3189     case 1:
3190       return output_387_reg_move (insn, operands);
3191
3192     case 2:
3193       return standard_80387_constant_opcode (operands[1]);
3194
3195     case 3: case 4:
3196       return "#";
3197
3198     default:
3199       gcc_unreachable ();
3200     }
3201 }
3202   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3203    (set_attr "mode" "XF,XF,XF,SI,SI")])
3204
3205 (define_expand "movtf"
3206   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3207         (match_operand:TF 1 "nonimmediate_operand" ""))]
3208   "TARGET_64BIT"
3209 {
3210   ix86_expand_move (TFmode, operands);
3211   DONE;
3212 })
3213
3214 (define_insn "*movtf_internal"
3215   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3216         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3217   "TARGET_64BIT
3218    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3219 {
3220   switch (which_alternative)
3221     {
3222     case 0:
3223     case 1:
3224       if (get_attr_mode (insn) == MODE_V4SF)
3225         return "movaps\t{%1, %0|%0, %1}";
3226       else
3227         return "movdqa\t{%1, %0|%0, %1}";
3228     case 2:
3229       if (get_attr_mode (insn) == MODE_V4SF)
3230         return "xorps\t%0, %0";
3231       else
3232         return "pxor\t%0, %0";
3233     case 3:
3234     case 4:
3235         return "#";
3236     default:
3237       gcc_unreachable ();
3238     }
3239 }
3240   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3241    (set (attr "mode")
3242         (cond [(eq_attr "alternative" "0,2")
3243                  (if_then_else
3244                    (ne (symbol_ref "optimize_size")
3245                        (const_int 0))
3246                    (const_string "V4SF")
3247                    (const_string "TI"))
3248                (eq_attr "alternative" "1")
3249                  (if_then_else
3250                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3251                             (const_int 0))
3252                         (ne (symbol_ref "optimize_size")
3253                             (const_int 0)))
3254                    (const_string "V4SF")
3255                    (const_string "TI"))]
3256                (const_string "DI")))])
3257
3258 (define_split
3259   [(set (match_operand 0 "nonimmediate_operand" "")
3260         (match_operand 1 "general_operand" ""))]
3261   "reload_completed
3262    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3263    && GET_MODE (operands[0]) == XFmode
3264    && ! (ANY_FP_REG_P (operands[0]) ||
3265          (GET_CODE (operands[0]) == SUBREG
3266           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3267    && ! (ANY_FP_REG_P (operands[1]) ||
3268          (GET_CODE (operands[1]) == SUBREG
3269           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3270   [(const_int 0)]
3271   "ix86_split_long_move (operands); DONE;")
3272
3273 (define_split
3274   [(set (match_operand 0 "register_operand" "")
3275         (match_operand 1 "memory_operand" ""))]
3276   "reload_completed
3277    && MEM_P (operands[1])
3278    && (GET_MODE (operands[0]) == TFmode
3279        || GET_MODE (operands[0]) == XFmode
3280        || GET_MODE (operands[0]) == SFmode
3281        || GET_MODE (operands[0]) == DFmode)
3282    && (operands[2] = find_constant_src (insn))"
3283   [(set (match_dup 0) (match_dup 2))]
3284 {
3285   rtx c = operands[2];
3286   rtx r = operands[0];
3287
3288   if (GET_CODE (r) == SUBREG)
3289     r = SUBREG_REG (r);
3290
3291   if (SSE_REG_P (r))
3292     {
3293       if (!standard_sse_constant_p (c))
3294         FAIL;
3295     }
3296   else if (FP_REG_P (r))
3297     {
3298       if (!standard_80387_constant_p (c))
3299         FAIL;
3300     }
3301   else if (MMX_REG_P (r))
3302     FAIL;
3303 })
3304
3305 (define_split
3306   [(set (match_operand 0 "register_operand" "")
3307         (float_extend (match_operand 1 "memory_operand" "")))]
3308   "reload_completed
3309    && MEM_P (operands[1])
3310    && (GET_MODE (operands[0]) == TFmode
3311        || GET_MODE (operands[0]) == XFmode
3312        || GET_MODE (operands[0]) == SFmode
3313        || GET_MODE (operands[0]) == DFmode)
3314    && (operands[2] = find_constant_src (insn))"
3315   [(set (match_dup 0) (match_dup 2))]
3316 {
3317   rtx c = operands[2];
3318   rtx r = operands[0];
3319
3320   if (GET_CODE (r) == SUBREG)
3321     r = SUBREG_REG (r);
3322
3323   if (SSE_REG_P (r))
3324     {
3325       if (!standard_sse_constant_p (c))
3326         FAIL;
3327     }
3328   else if (FP_REG_P (r))
3329     {
3330       if (!standard_80387_constant_p (c))
3331         FAIL;
3332     }
3333   else if (MMX_REG_P (r))
3334     FAIL;
3335 })
3336
3337 (define_insn "swapxf"
3338   [(set (match_operand:XF 0 "register_operand" "+f")
3339         (match_operand:XF 1 "register_operand" "+f"))
3340    (set (match_dup 1)
3341         (match_dup 0))]
3342   "TARGET_80387"
3343 {
3344   if (STACK_TOP_P (operands[0]))
3345     return "fxch\t%1";
3346   else
3347     return "fxch\t%0";
3348 }
3349   [(set_attr "type" "fxch")
3350    (set_attr "mode" "XF")])
3351
3352 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3353 (define_split
3354   [(set (match_operand:X87MODEF 0 "register_operand" "")
3355         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3356   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3357    && (standard_80387_constant_p (operands[1]) == 8
3358        || standard_80387_constant_p (operands[1]) == 9)"
3359   [(set (match_dup 0)(match_dup 1))
3360    (set (match_dup 0)
3361         (neg:X87MODEF (match_dup 0)))]
3362 {
3363   REAL_VALUE_TYPE r;
3364
3365   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3366   if (real_isnegzero (&r))
3367     operands[1] = CONST0_RTX (<MODE>mode);
3368   else
3369     operands[1] = CONST1_RTX (<MODE>mode);
3370 })
3371
3372 (define_split
3373   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3374         (match_operand:TF 1 "general_operand" ""))]
3375   "reload_completed
3376    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3377   [(const_int 0)]
3378   "ix86_split_long_move (operands); DONE;")
3379 \f
3380 ;; Zero extension instructions
3381
3382 (define_expand "zero_extendhisi2"
3383   [(set (match_operand:SI 0 "register_operand" "")
3384      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3385   ""
3386 {
3387   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3388     {
3389       operands[1] = force_reg (HImode, operands[1]);
3390       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3391       DONE;
3392     }
3393 })
3394
3395 (define_insn "zero_extendhisi2_and"
3396   [(set (match_operand:SI 0 "register_operand" "=r")
3397      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3398    (clobber (reg:CC FLAGS_REG))]
3399   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3400   "#"
3401   [(set_attr "type" "alu1")
3402    (set_attr "mode" "SI")])
3403
3404 (define_split
3405   [(set (match_operand:SI 0 "register_operand" "")
3406         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3409   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3410               (clobber (reg:CC FLAGS_REG))])]
3411   "")
3412
3413 (define_insn "*zero_extendhisi2_movzwl"
3414   [(set (match_operand:SI 0 "register_operand" "=r")
3415      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3416   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3417   "movz{wl|x}\t{%1, %0|%0, %1}"
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "SI")])
3420
3421 (define_expand "zero_extendqihi2"
3422   [(parallel
3423     [(set (match_operand:HI 0 "register_operand" "")
3424        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3425      (clobber (reg:CC FLAGS_REG))])]
3426   ""
3427   "")
3428
3429 (define_insn "*zero_extendqihi2_and"
3430   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3431      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3432    (clobber (reg:CC FLAGS_REG))]
3433   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3434   "#"
3435   [(set_attr "type" "alu1")
3436    (set_attr "mode" "HI")])
3437
3438 (define_insn "*zero_extendqihi2_movzbw_and"
3439   [(set (match_operand:HI 0 "register_operand" "=r,r")
3440      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3441    (clobber (reg:CC FLAGS_REG))]
3442   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3443   "#"
3444   [(set_attr "type" "imovx,alu1")
3445    (set_attr "mode" "HI")])
3446
3447 ; zero extend to SImode here to avoid partial register stalls
3448 (define_insn "*zero_extendqihi2_movzbl"
3449   [(set (match_operand:HI 0 "register_operand" "=r")
3450      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3451   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3452   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3453   [(set_attr "type" "imovx")
3454    (set_attr "mode" "SI")])
3455
3456 ;; For the movzbw case strip only the clobber
3457 (define_split
3458   [(set (match_operand:HI 0 "register_operand" "")
3459         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3460    (clobber (reg:CC FLAGS_REG))]
3461   "reload_completed
3462    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3463    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3464   [(set (match_operand:HI 0 "register_operand" "")
3465         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3466
3467 ;; When source and destination does not overlap, clear destination
3468 ;; first and then do the movb
3469 (define_split
3470   [(set (match_operand:HI 0 "register_operand" "")
3471         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3472    (clobber (reg:CC FLAGS_REG))]
3473   "reload_completed
3474    && ANY_QI_REG_P (operands[0])
3475    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3476    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3477   [(set (match_dup 0) (const_int 0))
3478    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3479   "operands[2] = gen_lowpart (QImode, operands[0]);")
3480
3481 ;; Rest is handled by single and.
3482 (define_split
3483   [(set (match_operand:HI 0 "register_operand" "")
3484         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3485    (clobber (reg:CC FLAGS_REG))]
3486   "reload_completed
3487    && true_regnum (operands[0]) == true_regnum (operands[1])"
3488   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3489               (clobber (reg:CC FLAGS_REG))])]
3490   "")
3491
3492 (define_expand "zero_extendqisi2"
3493   [(parallel
3494     [(set (match_operand:SI 0 "register_operand" "")
3495        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3496      (clobber (reg:CC FLAGS_REG))])]
3497   ""
3498   "")
3499
3500 (define_insn "*zero_extendqisi2_and"
3501   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3502      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3503    (clobber (reg:CC FLAGS_REG))]
3504   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3505   "#"
3506   [(set_attr "type" "alu1")
3507    (set_attr "mode" "SI")])
3508
3509 (define_insn "*zero_extendqisi2_movzbw_and"
3510   [(set (match_operand:SI 0 "register_operand" "=r,r")
3511      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3512    (clobber (reg:CC FLAGS_REG))]
3513   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3514   "#"
3515   [(set_attr "type" "imovx,alu1")
3516    (set_attr "mode" "SI")])
3517
3518 (define_insn "*zero_extendqisi2_movzbw"
3519   [(set (match_operand:SI 0 "register_operand" "=r")
3520      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3521   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3522   "movz{bl|x}\t{%1, %0|%0, %1}"
3523   [(set_attr "type" "imovx")
3524    (set_attr "mode" "SI")])
3525
3526 ;; For the movzbl case strip only the clobber
3527 (define_split
3528   [(set (match_operand:SI 0 "register_operand" "")
3529         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3530    (clobber (reg:CC FLAGS_REG))]
3531   "reload_completed
3532    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3533    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3534   [(set (match_dup 0)
3535         (zero_extend:SI (match_dup 1)))])
3536
3537 ;; When source and destination does not overlap, clear destination
3538 ;; first and then do the movb
3539 (define_split
3540   [(set (match_operand:SI 0 "register_operand" "")
3541         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3542    (clobber (reg:CC FLAGS_REG))]
3543   "reload_completed
3544    && ANY_QI_REG_P (operands[0])
3545    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3546    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3547    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3548   [(set (match_dup 0) (const_int 0))
3549    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3550   "operands[2] = gen_lowpart (QImode, operands[0]);")
3551
3552 ;; Rest is handled by single and.
3553 (define_split
3554   [(set (match_operand:SI 0 "register_operand" "")
3555         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3556    (clobber (reg:CC FLAGS_REG))]
3557   "reload_completed
3558    && true_regnum (operands[0]) == true_regnum (operands[1])"
3559   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3560               (clobber (reg:CC FLAGS_REG))])]
3561   "")
3562
3563 ;; %%% Kill me once multi-word ops are sane.
3564 (define_expand "zero_extendsidi2"
3565   [(set (match_operand:DI 0 "register_operand" "")
3566      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3567   ""
3568 {
3569   if (!TARGET_64BIT)
3570     {
3571       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3572       DONE;
3573     }
3574 })
3575
3576 (define_insn "zero_extendsidi2_32"
3577   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3578         (zero_extend:DI
3579          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3580    (clobber (reg:CC FLAGS_REG))]
3581   "!TARGET_64BIT"
3582   "@
3583    #
3584    #
3585    #
3586    movd\t{%1, %0|%0, %1}
3587    movd\t{%1, %0|%0, %1}
3588    movd\t{%1, %0|%0, %1}
3589    movd\t{%1, %0|%0, %1}"
3590   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3591    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3592
3593 (define_insn "zero_extendsidi2_rex64"
3594   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3595      (zero_extend:DI
3596        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3597   "TARGET_64BIT"
3598   "@
3599    mov\t{%k1, %k0|%k0, %k1}
3600    #
3601    movd\t{%1, %0|%0, %1}
3602    movd\t{%1, %0|%0, %1}
3603    movd\t{%1, %0|%0, %1}
3604    movd\t{%1, %0|%0, %1}"
3605   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3606    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3607
3608 (define_split
3609   [(set (match_operand:DI 0 "memory_operand" "")
3610      (zero_extend:DI (match_dup 0)))]
3611   "TARGET_64BIT"
3612   [(set (match_dup 4) (const_int 0))]
3613   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3614
3615 (define_split
3616   [(set (match_operand:DI 0 "register_operand" "")
3617         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3618    (clobber (reg:CC FLAGS_REG))]
3619   "!TARGET_64BIT && reload_completed
3620    && true_regnum (operands[0]) == true_regnum (operands[1])"
3621   [(set (match_dup 4) (const_int 0))]
3622   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3623
3624 (define_split
3625   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3626         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3627    (clobber (reg:CC FLAGS_REG))]
3628   "!TARGET_64BIT && reload_completed
3629    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3630   [(set (match_dup 3) (match_dup 1))
3631    (set (match_dup 4) (const_int 0))]
3632   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3633
3634 (define_insn "zero_extendhidi2"
3635   [(set (match_operand:DI 0 "register_operand" "=r")
3636      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3637   "TARGET_64BIT"
3638   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3639   [(set_attr "type" "imovx")
3640    (set_attr "mode" "DI")])
3641
3642 (define_insn "zero_extendqidi2"
3643   [(set (match_operand:DI 0 "register_operand" "=r")
3644      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3645   "TARGET_64BIT"
3646   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3647   [(set_attr "type" "imovx")
3648    (set_attr "mode" "DI")])
3649 \f
3650 ;; Sign extension instructions
3651
3652 (define_expand "extendsidi2"
3653   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3654                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3655               (clobber (reg:CC FLAGS_REG))
3656               (clobber (match_scratch:SI 2 ""))])]
3657   ""
3658 {
3659   if (TARGET_64BIT)
3660     {
3661       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3662       DONE;
3663     }
3664 })
3665
3666 (define_insn "*extendsidi2_1"
3667   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3668         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3669    (clobber (reg:CC FLAGS_REG))
3670    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3671   "!TARGET_64BIT"
3672   "#")
3673
3674 (define_insn "extendsidi2_rex64"
3675   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3676         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3677   "TARGET_64BIT"
3678   "@
3679    {cltq|cdqe}
3680    movs{lq|x}\t{%1,%0|%0, %1}"
3681   [(set_attr "type" "imovx")
3682    (set_attr "mode" "DI")
3683    (set_attr "prefix_0f" "0")
3684    (set_attr "modrm" "0,1")])
3685
3686 (define_insn "extendhidi2"
3687   [(set (match_operand:DI 0 "register_operand" "=r")
3688         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3689   "TARGET_64BIT"
3690   "movs{wq|x}\t{%1,%0|%0, %1}"
3691   [(set_attr "type" "imovx")
3692    (set_attr "mode" "DI")])
3693
3694 (define_insn "extendqidi2"
3695   [(set (match_operand:DI 0 "register_operand" "=r")
3696         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3697   "TARGET_64BIT"
3698   "movs{bq|x}\t{%1,%0|%0, %1}"
3699    [(set_attr "type" "imovx")
3700     (set_attr "mode" "DI")])
3701
3702 ;; Extend to memory case when source register does die.
3703 (define_split
3704   [(set (match_operand:DI 0 "memory_operand" "")
3705         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3706    (clobber (reg:CC FLAGS_REG))
3707    (clobber (match_operand:SI 2 "register_operand" ""))]
3708   "(reload_completed
3709     && dead_or_set_p (insn, operands[1])
3710     && !reg_mentioned_p (operands[1], operands[0]))"
3711   [(set (match_dup 3) (match_dup 1))
3712    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3713               (clobber (reg:CC FLAGS_REG))])
3714    (set (match_dup 4) (match_dup 1))]
3715   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3716
3717 ;; Extend to memory case when source register does not die.
3718 (define_split
3719   [(set (match_operand:DI 0 "memory_operand" "")
3720         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3721    (clobber (reg:CC FLAGS_REG))
3722    (clobber (match_operand:SI 2 "register_operand" ""))]
3723   "reload_completed"
3724   [(const_int 0)]
3725 {
3726   split_di (&operands[0], 1, &operands[3], &operands[4]);
3727
3728   emit_move_insn (operands[3], operands[1]);
3729
3730   /* Generate a cltd if possible and doing so it profitable.  */
3731   if ((optimize_size || TARGET_USE_CLTD)
3732       && true_regnum (operands[1]) == AX_REG
3733       && true_regnum (operands[2]) == DX_REG)
3734     {
3735       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3736     }
3737   else
3738     {
3739       emit_move_insn (operands[2], operands[1]);
3740       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3741     }
3742   emit_move_insn (operands[4], operands[2]);
3743   DONE;
3744 })
3745
3746 ;; Extend to register case.  Optimize case where source and destination
3747 ;; registers match and cases where we can use cltd.
3748 (define_split
3749   [(set (match_operand:DI 0 "register_operand" "")
3750         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3751    (clobber (reg:CC FLAGS_REG))
3752    (clobber (match_scratch:SI 2 ""))]
3753   "reload_completed"
3754   [(const_int 0)]
3755 {
3756   split_di (&operands[0], 1, &operands[3], &operands[4]);
3757
3758   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3759     emit_move_insn (operands[3], operands[1]);
3760
3761   /* Generate a cltd if possible and doing so it profitable.  */
3762   if ((optimize_size || TARGET_USE_CLTD)
3763       && true_regnum (operands[3]) == AX_REG)
3764     {
3765       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3766       DONE;
3767     }
3768
3769   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3770     emit_move_insn (operands[4], operands[1]);
3771
3772   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3773   DONE;
3774 })
3775
3776 (define_insn "extendhisi2"
3777   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3778         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3779   ""
3780 {
3781   switch (get_attr_prefix_0f (insn))
3782     {
3783     case 0:
3784       return "{cwtl|cwde}";
3785     default:
3786       return "movs{wl|x}\t{%1,%0|%0, %1}";
3787     }
3788 }
3789   [(set_attr "type" "imovx")
3790    (set_attr "mode" "SI")
3791    (set (attr "prefix_0f")
3792      ;; movsx is short decodable while cwtl is vector decoded.
3793      (if_then_else (and (eq_attr "cpu" "!k6")
3794                         (eq_attr "alternative" "0"))
3795         (const_string "0")
3796         (const_string "1")))
3797    (set (attr "modrm")
3798      (if_then_else (eq_attr "prefix_0f" "0")
3799         (const_string "0")
3800         (const_string "1")))])
3801
3802 (define_insn "*extendhisi2_zext"
3803   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3804         (zero_extend:DI
3805           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3806   "TARGET_64BIT"
3807 {
3808   switch (get_attr_prefix_0f (insn))
3809     {
3810     case 0:
3811       return "{cwtl|cwde}";
3812     default:
3813       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3814     }
3815 }
3816   [(set_attr "type" "imovx")
3817    (set_attr "mode" "SI")
3818    (set (attr "prefix_0f")
3819      ;; movsx is short decodable while cwtl is vector decoded.
3820      (if_then_else (and (eq_attr "cpu" "!k6")
3821                         (eq_attr "alternative" "0"))
3822         (const_string "0")
3823         (const_string "1")))
3824    (set (attr "modrm")
3825      (if_then_else (eq_attr "prefix_0f" "0")
3826         (const_string "0")
3827         (const_string "1")))])
3828
3829 (define_insn "extendqihi2"
3830   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3831         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3832   ""
3833 {
3834   switch (get_attr_prefix_0f (insn))
3835     {
3836     case 0:
3837       return "{cbtw|cbw}";
3838     default:
3839       return "movs{bw|x}\t{%1,%0|%0, %1}";
3840     }
3841 }
3842   [(set_attr "type" "imovx")
3843    (set_attr "mode" "HI")
3844    (set (attr "prefix_0f")
3845      ;; movsx is short decodable while cwtl is vector decoded.
3846      (if_then_else (and (eq_attr "cpu" "!k6")
3847                         (eq_attr "alternative" "0"))
3848         (const_string "0")
3849         (const_string "1")))
3850    (set (attr "modrm")
3851      (if_then_else (eq_attr "prefix_0f" "0")
3852         (const_string "0")
3853         (const_string "1")))])
3854
3855 (define_insn "extendqisi2"
3856   [(set (match_operand:SI 0 "register_operand" "=r")
3857         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3858   ""
3859   "movs{bl|x}\t{%1,%0|%0, %1}"
3860    [(set_attr "type" "imovx")
3861     (set_attr "mode" "SI")])
3862
3863 (define_insn "*extendqisi2_zext"
3864   [(set (match_operand:DI 0 "register_operand" "=r")
3865         (zero_extend:DI
3866           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3867   "TARGET_64BIT"
3868   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3869    [(set_attr "type" "imovx")
3870     (set_attr "mode" "SI")])
3871 \f
3872 ;; Conversions between float and double.
3873
3874 ;; These are all no-ops in the model used for the 80387.  So just
3875 ;; emit moves.
3876
3877 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3878 (define_insn "*dummy_extendsfdf2"
3879   [(set (match_operand:DF 0 "push_operand" "=<")
3880         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3881   "0"
3882   "#")
3883
3884 (define_split
3885   [(set (match_operand:DF 0 "push_operand" "")
3886         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3887   "!TARGET_64BIT"
3888   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3889    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3890
3891 (define_split
3892   [(set (match_operand:DF 0 "push_operand" "")
3893         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3894   "TARGET_64BIT"
3895   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3896    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3897
3898 (define_insn "*dummy_extendsfxf2"
3899   [(set (match_operand:XF 0 "push_operand" "=<")
3900         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3901   "0"
3902   "#")
3903
3904 (define_split
3905   [(set (match_operand:XF 0 "push_operand" "")
3906         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3907   ""
3908   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3909    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3910   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3911
3912 (define_split
3913   [(set (match_operand:XF 0 "push_operand" "")
3914         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3915   "TARGET_64BIT"
3916   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3917    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3918   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3919
3920 (define_split
3921   [(set (match_operand:XF 0 "push_operand" "")
3922         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3923   ""
3924   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3925    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3926   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3927
3928 (define_split
3929   [(set (match_operand:XF 0 "push_operand" "")
3930         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3931   "TARGET_64BIT"
3932   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3933    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3934   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3935
3936 (define_expand "extendsfdf2"
3937   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3938         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3939   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3940 {
3941   /* ??? Needed for compress_float_constant since all fp constants
3942      are LEGITIMATE_CONSTANT_P.  */
3943   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3944     {
3945       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3946           && standard_80387_constant_p (operands[1]) > 0)
3947         {
3948           operands[1] = simplify_const_unary_operation
3949             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3950           emit_move_insn_1 (operands[0], operands[1]);
3951           DONE;
3952         }
3953       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3954     }
3955 })
3956
3957 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3958    cvtss2sd:
3959       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3960       cvtps2pd xmm2,xmm1
3961    We do the conversion post reload to avoid producing of 128bit spills
3962    that might lead to ICE on 32bit target.  The sequence unlikely combine
3963    anyway.  */
3964 (define_split
3965   [(set (match_operand:DF 0 "register_operand" "")
3966         (float_extend:DF
3967           (match_operand:SF 1 "nonimmediate_operand" "")))]
3968   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3969    && reload_completed && SSE_REG_P (operands[0])"
3970    [(set (match_dup 2)
3971          (float_extend:V2DF
3972            (vec_select:V2SF
3973              (match_dup 3)
3974              (parallel [(const_int 0) (const_int 1)]))))]
3975 {
3976   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3977   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3978   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3979      Try to avoid move when unpacking can be done in source.  */
3980   if (REG_P (operands[1]))
3981     {
3982       /* If it is unsafe to overwrite upper half of source, we need
3983          to move to destination and unpack there.  */
3984       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3985            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3986           && true_regnum (operands[0]) != true_regnum (operands[1]))
3987         {
3988           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3989           emit_move_insn (tmp, operands[1]);
3990         }
3991       else
3992         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3993       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3994     }
3995   else
3996     emit_insn (gen_vec_setv4sf_0 (operands[3],
3997                                   CONST0_RTX (V4SFmode), operands[1]));
3998 })
3999
4000 (define_insn "*extendsfdf2_mixed"
4001   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4002         (float_extend:DF
4003           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4004   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4005 {
4006   switch (which_alternative)
4007     {
4008     case 0:
4009     case 1:
4010       return output_387_reg_move (insn, operands);
4011
4012     case 2:
4013       return "cvtss2sd\t{%1, %0|%0, %1}";
4014
4015     default:
4016       gcc_unreachable ();
4017     }
4018 }
4019   [(set_attr "type" "fmov,fmov,ssecvt")
4020    (set_attr "mode" "SF,XF,DF")])
4021
4022 (define_insn "*extendsfdf2_sse"
4023   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4024         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4025   "TARGET_SSE2 && TARGET_SSE_MATH"
4026   "cvtss2sd\t{%1, %0|%0, %1}"
4027   [(set_attr "type" "ssecvt")
4028    (set_attr "mode" "DF")])
4029
4030 (define_insn "*extendsfdf2_i387"
4031   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4032         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4033   "TARGET_80387"
4034   "* return output_387_reg_move (insn, operands);"
4035   [(set_attr "type" "fmov")
4036    (set_attr "mode" "SF,XF")])
4037
4038 (define_expand "extend<mode>xf2"
4039   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4040         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4041   "TARGET_80387"
4042 {
4043   /* ??? Needed for compress_float_constant since all fp constants
4044      are LEGITIMATE_CONSTANT_P.  */
4045   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4046     {
4047       if (standard_80387_constant_p (operands[1]) > 0)
4048         {
4049           operands[1] = simplify_const_unary_operation
4050             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4051           emit_move_insn_1 (operands[0], operands[1]);
4052           DONE;
4053         }
4054       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4055     }
4056 })
4057
4058 (define_insn "*extend<mode>xf2_i387"
4059   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4060         (float_extend:XF
4061           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4062   "TARGET_80387"
4063   "* return output_387_reg_move (insn, operands);"
4064   [(set_attr "type" "fmov")
4065    (set_attr "mode" "<MODE>,XF")])
4066
4067 ;; %%% This seems bad bad news.
4068 ;; This cannot output into an f-reg because there is no way to be sure
4069 ;; of truncating in that case.  Otherwise this is just like a simple move
4070 ;; insn.  So we pretend we can output to a reg in order to get better
4071 ;; register preferencing, but we really use a stack slot.
4072
4073 ;; Conversion from DFmode to SFmode.
4074
4075 (define_expand "truncdfsf2"
4076   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4077         (float_truncate:SF
4078           (match_operand:DF 1 "nonimmediate_operand" "")))]
4079   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4080 {
4081   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4082     ;
4083   else if (flag_unsafe_math_optimizations)
4084     ;
4085   else
4086     {
4087       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4088       rtx temp = assign_386_stack_local (SFmode, slot);
4089       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4090       DONE;
4091     }
4092 })
4093
4094 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4095    cvtsd2ss:
4096       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4097       cvtpd2ps xmm2,xmm1
4098    We do the conversion post reload to avoid producing of 128bit spills
4099    that might lead to ICE on 32bit target.  The sequence unlikely combine
4100    anyway.  */
4101 (define_split
4102   [(set (match_operand:SF 0 "register_operand" "")
4103         (float_truncate:SF
4104           (match_operand:DF 1 "nonimmediate_operand" "")))]
4105   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4106    && reload_completed && SSE_REG_P (operands[0])"
4107    [(set (match_dup 2)
4108          (vec_concat:V4SF
4109            (float_truncate:V2SF
4110              (match_dup 4))
4111            (match_dup 3)))]
4112 {
4113   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4114   operands[3] = CONST0_RTX (V2SFmode);
4115   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4116   /* Use movsd for loading from memory, unpcklpd for registers.
4117      Try to avoid move when unpacking can be done in source, or SSE3
4118      movddup is available.  */
4119   if (REG_P (operands[1]))
4120     {
4121       if (!TARGET_SSE3
4122           && true_regnum (operands[0]) != true_regnum (operands[1])
4123           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4124               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4125         {
4126           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4127           emit_move_insn (tmp, operands[1]);
4128           operands[1] = tmp;
4129         }
4130       else if (!TARGET_SSE3)
4131         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4132       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4133     }
4134   else
4135     emit_insn (gen_sse2_loadlpd (operands[4],
4136                                  CONST0_RTX (V2DFmode), operands[1]));
4137 })
4138
4139 (define_expand "truncdfsf2_with_temp"
4140   [(parallel [(set (match_operand:SF 0 "" "")
4141                    (float_truncate:SF (match_operand:DF 1 "" "")))
4142               (clobber (match_operand:SF 2 "" ""))])]
4143   "")
4144
4145 (define_insn "*truncdfsf_fast_mixed"
4146   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4147         (float_truncate:SF
4148           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4149   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4150 {
4151   switch (which_alternative)
4152     {
4153     case 0:
4154     case 1:
4155       return output_387_reg_move (insn, operands);
4156     case 2:
4157       return "cvtsd2ss\t{%1, %0|%0, %1}";
4158     default:
4159       gcc_unreachable ();
4160     }
4161 }
4162   [(set_attr "type" "fmov,fmov,ssecvt")
4163    (set_attr "mode" "SF")])
4164
4165 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4166 ;; because nothing we do here is unsafe.
4167 (define_insn "*truncdfsf_fast_sse"
4168   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4169         (float_truncate:SF
4170           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4171   "TARGET_SSE2 && TARGET_SSE_MATH"
4172   "cvtsd2ss\t{%1, %0|%0, %1}"
4173   [(set_attr "type" "ssecvt")
4174    (set_attr "mode" "SF")])
4175
4176 (define_insn "*truncdfsf_fast_i387"
4177   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4178         (float_truncate:SF
4179           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4180   "TARGET_80387 && flag_unsafe_math_optimizations"
4181   "* return output_387_reg_move (insn, operands);"
4182   [(set_attr "type" "fmov")
4183    (set_attr "mode" "SF")])
4184
4185 (define_insn "*truncdfsf_mixed"
4186   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4187         (float_truncate:SF
4188           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4189    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4190   "TARGET_MIX_SSE_I387"
4191 {
4192   switch (which_alternative)
4193     {
4194     case 0:
4195       return output_387_reg_move (insn, operands);
4196
4197     case 1:
4198       return "#";
4199     case 2:
4200       return "cvtsd2ss\t{%1, %0|%0, %1}";
4201     default:
4202       gcc_unreachable ();
4203     }
4204 }
4205   [(set_attr "type" "fmov,multi,ssecvt")
4206    (set_attr "unit" "*,i387,*")
4207    (set_attr "mode" "SF")])
4208
4209 (define_insn "*truncdfsf_i387"
4210   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4211         (float_truncate:SF
4212           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4213    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4214   "TARGET_80387"
4215 {
4216   switch (which_alternative)
4217     {
4218     case 0:
4219       return output_387_reg_move (insn, operands);
4220
4221     case 1:
4222       return "#";
4223     default:
4224       gcc_unreachable ();
4225     }
4226 }
4227   [(set_attr "type" "fmov,multi")
4228    (set_attr "unit" "*,i387")
4229    (set_attr "mode" "SF")])
4230
4231 (define_insn "*truncdfsf2_i387_1"
4232   [(set (match_operand:SF 0 "memory_operand" "=m")
4233         (float_truncate:SF
4234           (match_operand:DF 1 "register_operand" "f")))]
4235   "TARGET_80387
4236    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4237    && !TARGET_MIX_SSE_I387"
4238   "* return output_387_reg_move (insn, operands);"
4239   [(set_attr "type" "fmov")
4240    (set_attr "mode" "SF")])
4241
4242 (define_split
4243   [(set (match_operand:SF 0 "register_operand" "")
4244         (float_truncate:SF
4245          (match_operand:DF 1 "fp_register_operand" "")))
4246    (clobber (match_operand 2 "" ""))]
4247   "reload_completed"
4248   [(set (match_dup 2) (match_dup 1))
4249    (set (match_dup 0) (match_dup 2))]
4250 {
4251   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4252 })
4253
4254 ;; Conversion from XFmode to {SF,DF}mode
4255
4256 (define_expand "truncxf<mode>2"
4257   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4258                    (float_truncate:MODEF
4259                      (match_operand:XF 1 "register_operand" "")))
4260               (clobber (match_dup 2))])]
4261   "TARGET_80387"
4262 {
4263   if (flag_unsafe_math_optimizations)
4264     {
4265       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4266       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4267       if (reg != operands[0])
4268         emit_move_insn (operands[0], reg);
4269       DONE;
4270     }
4271   else
4272     {
4273       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4274       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4275     }
4276 })
4277
4278 (define_insn "*truncxfsf2_mixed"
4279   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4280         (float_truncate:SF
4281           (match_operand:XF 1 "register_operand" "f,f")))
4282    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4283   "TARGET_80387"
4284 {
4285   gcc_assert (!which_alternative);
4286   return output_387_reg_move (insn, operands);
4287 }
4288   [(set_attr "type" "fmov,multi")
4289    (set_attr "unit" "*,i387")
4290    (set_attr "mode" "SF")])
4291
4292 (define_insn "*truncxfdf2_mixed"
4293   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4294         (float_truncate:DF
4295           (match_operand:XF 1 "register_operand" "f,f")))
4296    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4297   "TARGET_80387"
4298 {
4299   gcc_assert (!which_alternative);
4300   return output_387_reg_move (insn, operands);
4301 }
4302   [(set_attr "type" "fmov,multi")
4303    (set_attr "unit" "*,i387")
4304    (set_attr "mode" "DF")])
4305
4306 (define_insn "truncxf<mode>2_i387_noop"
4307   [(set (match_operand:MODEF 0 "register_operand" "=f")
4308         (float_truncate:MODEF
4309           (match_operand:XF 1 "register_operand" "f")))]
4310   "TARGET_80387 && flag_unsafe_math_optimizations"
4311   "* return output_387_reg_move (insn, operands);"
4312   [(set_attr "type" "fmov")
4313    (set_attr "mode" "<MODE>")])
4314
4315 (define_insn "*truncxf<mode>2_i387"
4316   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4317         (float_truncate:MODEF
4318           (match_operand:XF 1 "register_operand" "f")))]
4319   "TARGET_80387"
4320   "* return output_387_reg_move (insn, operands);"
4321   [(set_attr "type" "fmov")
4322    (set_attr "mode" "<MODE>")])
4323
4324 (define_split
4325   [(set (match_operand:MODEF 0 "register_operand" "")
4326         (float_truncate:MODEF
4327           (match_operand:XF 1 "register_operand" "")))
4328    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4329   "TARGET_80387 && reload_completed"
4330   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4331    (set (match_dup 0) (match_dup 2))]
4332   "")
4333
4334 (define_split
4335   [(set (match_operand:MODEF 0 "memory_operand" "")
4336         (float_truncate:MODEF
4337           (match_operand:XF 1 "register_operand" "")))
4338    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4339   "TARGET_80387"
4340   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4341   "")
4342 \f
4343 ;; Signed conversion to DImode.
4344
4345 (define_expand "fix_truncxfdi2"
4346   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4347                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4348               (clobber (reg:CC FLAGS_REG))])]
4349   "TARGET_80387"
4350 {
4351   if (TARGET_FISTTP)
4352    {
4353      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4354      DONE;
4355    }
4356 })
4357
4358 (define_expand "fix_trunc<mode>di2"
4359   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4360                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4361               (clobber (reg:CC FLAGS_REG))])]
4362   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4363 {
4364   if (TARGET_FISTTP
4365       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4366    {
4367      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4368      DONE;
4369    }
4370   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4371    {
4372      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4373      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4374      if (out != operands[0])
4375         emit_move_insn (operands[0], out);
4376      DONE;
4377    }
4378 })
4379
4380 ;; Signed conversion to SImode.
4381
4382 (define_expand "fix_truncxfsi2"
4383   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4384                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4385               (clobber (reg:CC FLAGS_REG))])]
4386   "TARGET_80387"
4387 {
4388   if (TARGET_FISTTP)
4389    {
4390      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4391      DONE;
4392    }
4393 })
4394
4395 (define_expand "fix_trunc<mode>si2"
4396   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4397                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4398               (clobber (reg:CC FLAGS_REG))])]
4399   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4400 {
4401   if (TARGET_FISTTP
4402       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4403    {
4404      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4405      DONE;
4406    }
4407   if (SSE_FLOAT_MODE_P (<MODE>mode))
4408    {
4409      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4410      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4411      if (out != operands[0])
4412         emit_move_insn (operands[0], out);
4413      DONE;
4414    }
4415 })
4416
4417 ;; Signed conversion to HImode.
4418
4419 (define_expand "fix_trunc<mode>hi2"
4420   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4421                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4422               (clobber (reg:CC FLAGS_REG))])]
4423   "TARGET_80387
4424    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4425 {
4426   if (TARGET_FISTTP)
4427    {
4428      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4429      DONE;
4430    }
4431 })
4432
4433 ;; Unsigned conversion to SImode.
4434
4435 (define_expand "fixuns_trunc<mode>si2"
4436   [(parallel
4437     [(set (match_operand:SI 0 "register_operand" "")
4438           (unsigned_fix:SI
4439             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4440      (use (match_dup 2))
4441      (clobber (match_scratch:<ssevecmode> 3 ""))
4442      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4443   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4444 {
4445   enum machine_mode mode = <MODE>mode;
4446   enum machine_mode vecmode = <ssevecmode>mode;
4447   REAL_VALUE_TYPE TWO31r;
4448   rtx two31;
4449
4450   real_ldexp (&TWO31r, &dconst1, 31);
4451   two31 = const_double_from_real_value (TWO31r, mode);
4452   two31 = ix86_build_const_vector (mode, true, two31);
4453   operands[2] = force_reg (vecmode, two31);
4454 })
4455
4456 (define_insn_and_split "*fixuns_trunc<mode>_1"
4457   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4458         (unsigned_fix:SI
4459           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4460    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4461    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4462    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4463   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4464   "#"
4465   "&& reload_completed"
4466   [(const_int 0)]
4467 {
4468   ix86_split_convert_uns_si_sse (operands);
4469   DONE;
4470 })
4471
4472 ;; Unsigned conversion to HImode.
4473 ;; Without these patterns, we'll try the unsigned SI conversion which
4474 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4475
4476 (define_expand "fixuns_trunc<mode>hi2"
4477   [(set (match_dup 2)
4478         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4479    (set (match_operand:HI 0 "nonimmediate_operand" "")
4480         (subreg:HI (match_dup 2) 0))]
4481   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4482   "operands[2] = gen_reg_rtx (SImode);")
4483
4484 ;; When SSE is available, it is always faster to use it!
4485 (define_insn "fix_trunc<mode>di_sse"
4486   [(set (match_operand:DI 0 "register_operand" "=r,r")
4487         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4488   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4489    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4490   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4491   [(set_attr "type" "sseicvt")
4492    (set_attr "mode" "<MODE>")
4493    (set_attr "athlon_decode" "double,vector")
4494    (set_attr "amdfam10_decode" "double,double")])
4495
4496 (define_insn "fix_trunc<mode>si_sse"
4497   [(set (match_operand:SI 0 "register_operand" "=r,r")
4498         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4499   "SSE_FLOAT_MODE_P (<MODE>mode)
4500    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4501   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4502   [(set_attr "type" "sseicvt")
4503    (set_attr "mode" "<MODE>")
4504    (set_attr "athlon_decode" "double,vector")
4505    (set_attr "amdfam10_decode" "double,double")])
4506
4507 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4508 (define_peephole2
4509   [(set (match_operand:MODEF 0 "register_operand" "")
4510         (match_operand:MODEF 1 "memory_operand" ""))
4511    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4512         (fix:SSEMODEI24 (match_dup 0)))]
4513   "TARGET_SHORTEN_X87_SSE
4514    && peep2_reg_dead_p (2, operands[0])"
4515   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4516   "")
4517
4518 ;; Avoid vector decoded forms of the instruction.
4519 (define_peephole2
4520   [(match_scratch:DF 2 "Y2")
4521    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4522         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4523   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4524   [(set (match_dup 2) (match_dup 1))
4525    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4526   "")
4527
4528 (define_peephole2
4529   [(match_scratch:SF 2 "x")
4530    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4531         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4532   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4533   [(set (match_dup 2) (match_dup 1))
4534    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4535   "")
4536
4537 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4538   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4539         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4540   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4541    && TARGET_FISTTP
4542    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4543          && (TARGET_64BIT || <MODE>mode != DImode))
4544         && TARGET_SSE_MATH)
4545    && !(reload_completed || reload_in_progress)"
4546   "#"
4547   "&& 1"
4548   [(const_int 0)]
4549 {
4550   if (memory_operand (operands[0], VOIDmode))
4551     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4552   else
4553     {
4554       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4555       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4556                                                             operands[1],
4557                                                             operands[2]));
4558     }
4559   DONE;
4560 }
4561   [(set_attr "type" "fisttp")
4562    (set_attr "mode" "<MODE>")])
4563
4564 (define_insn "fix_trunc<mode>_i387_fisttp"
4565   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4566         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4567    (clobber (match_scratch:XF 2 "=&1f"))]
4568   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569    && TARGET_FISTTP
4570    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4571          && (TARGET_64BIT || <MODE>mode != DImode))
4572         && TARGET_SSE_MATH)"
4573   "* return output_fix_trunc (insn, operands, 1);"
4574   [(set_attr "type" "fisttp")
4575    (set_attr "mode" "<MODE>")])
4576
4577 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4578   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4579         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4580    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4581    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && TARGET_FISTTP
4584    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585         && (TARGET_64BIT || <MODE>mode != DImode))
4586         && TARGET_SSE_MATH)"
4587   "#"
4588   [(set_attr "type" "fisttp")
4589    (set_attr "mode" "<MODE>")])
4590
4591 (define_split
4592   [(set (match_operand:X87MODEI 0 "register_operand" "")
4593         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4594    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4595    (clobber (match_scratch 3 ""))]
4596   "reload_completed"
4597   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4598               (clobber (match_dup 3))])
4599    (set (match_dup 0) (match_dup 2))]
4600   "")
4601
4602 (define_split
4603   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4604         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4605    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4606    (clobber (match_scratch 3 ""))]
4607   "reload_completed"
4608   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4609               (clobber (match_dup 3))])]
4610   "")
4611
4612 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4613 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4614 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4615 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4616 ;; function in i386.c.
4617 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4618   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4619         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4620    (clobber (reg:CC FLAGS_REG))]
4621   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4622    && !TARGET_FISTTP
4623    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4624          && (TARGET_64BIT || <MODE>mode != DImode))
4625    && !(reload_completed || reload_in_progress)"
4626   "#"
4627   "&& 1"
4628   [(const_int 0)]
4629 {
4630   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4631
4632   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4633   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4634   if (memory_operand (operands[0], VOIDmode))
4635     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4636                                          operands[2], operands[3]));
4637   else
4638     {
4639       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4640       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4641                                                      operands[2], operands[3],
4642                                                      operands[4]));
4643     }
4644   DONE;
4645 }
4646   [(set_attr "type" "fistp")
4647    (set_attr "i387_cw" "trunc")
4648    (set_attr "mode" "<MODE>")])
4649
4650 (define_insn "fix_truncdi_i387"
4651   [(set (match_operand:DI 0 "memory_operand" "=m")
4652         (fix:DI (match_operand 1 "register_operand" "f")))
4653    (use (match_operand:HI 2 "memory_operand" "m"))
4654    (use (match_operand:HI 3 "memory_operand" "m"))
4655    (clobber (match_scratch:XF 4 "=&1f"))]
4656   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4657    && !TARGET_FISTTP
4658    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4659   "* return output_fix_trunc (insn, operands, 0);"
4660   [(set_attr "type" "fistp")
4661    (set_attr "i387_cw" "trunc")
4662    (set_attr "mode" "DI")])
4663
4664 (define_insn "fix_truncdi_i387_with_temp"
4665   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4666         (fix:DI (match_operand 1 "register_operand" "f,f")))
4667    (use (match_operand:HI 2 "memory_operand" "m,m"))
4668    (use (match_operand:HI 3 "memory_operand" "m,m"))
4669    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4670    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4671   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672    && !TARGET_FISTTP
4673    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4674   "#"
4675   [(set_attr "type" "fistp")
4676    (set_attr "i387_cw" "trunc")
4677    (set_attr "mode" "DI")])
4678
4679 (define_split
4680   [(set (match_operand:DI 0 "register_operand" "")
4681         (fix:DI (match_operand 1 "register_operand" "")))
4682    (use (match_operand:HI 2 "memory_operand" ""))
4683    (use (match_operand:HI 3 "memory_operand" ""))
4684    (clobber (match_operand:DI 4 "memory_operand" ""))
4685    (clobber (match_scratch 5 ""))]
4686   "reload_completed"
4687   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4688               (use (match_dup 2))
4689               (use (match_dup 3))
4690               (clobber (match_dup 5))])
4691    (set (match_dup 0) (match_dup 4))]
4692   "")
4693
4694 (define_split
4695   [(set (match_operand:DI 0 "memory_operand" "")
4696         (fix:DI (match_operand 1 "register_operand" "")))
4697    (use (match_operand:HI 2 "memory_operand" ""))
4698    (use (match_operand:HI 3 "memory_operand" ""))
4699    (clobber (match_operand:DI 4 "memory_operand" ""))
4700    (clobber (match_scratch 5 ""))]
4701   "reload_completed"
4702   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4703               (use (match_dup 2))
4704               (use (match_dup 3))
4705               (clobber (match_dup 5))])]
4706   "")
4707
4708 (define_insn "fix_trunc<mode>_i387"
4709   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4710         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4711    (use (match_operand:HI 2 "memory_operand" "m"))
4712    (use (match_operand:HI 3 "memory_operand" "m"))]
4713   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4714    && !TARGET_FISTTP
4715    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4716   "* return output_fix_trunc (insn, operands, 0);"
4717   [(set_attr "type" "fistp")
4718    (set_attr "i387_cw" "trunc")
4719    (set_attr "mode" "<MODE>")])
4720
4721 (define_insn "fix_trunc<mode>_i387_with_temp"
4722   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4723         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4724    (use (match_operand:HI 2 "memory_operand" "m,m"))
4725    (use (match_operand:HI 3 "memory_operand" "m,m"))
4726    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4727   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4728    && !TARGET_FISTTP
4729    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4730   "#"
4731   [(set_attr "type" "fistp")
4732    (set_attr "i387_cw" "trunc")
4733    (set_attr "mode" "<MODE>")])
4734
4735 (define_split
4736   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4737         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4738    (use (match_operand:HI 2 "memory_operand" ""))
4739    (use (match_operand:HI 3 "memory_operand" ""))
4740    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4741   "reload_completed"
4742   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4743               (use (match_dup 2))
4744               (use (match_dup 3))])
4745    (set (match_dup 0) (match_dup 4))]
4746   "")
4747
4748 (define_split
4749   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4750         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4751    (use (match_operand:HI 2 "memory_operand" ""))
4752    (use (match_operand:HI 3 "memory_operand" ""))
4753    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4754   "reload_completed"
4755   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4756               (use (match_dup 2))
4757               (use (match_dup 3))])]
4758   "")
4759
4760 (define_insn "x86_fnstcw_1"
4761   [(set (match_operand:HI 0 "memory_operand" "=m")
4762         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4763   "TARGET_80387"
4764   "fnstcw\t%0"
4765   [(set_attr "length" "2")
4766    (set_attr "mode" "HI")
4767    (set_attr "unit" "i387")])
4768
4769 (define_insn "x86_fldcw_1"
4770   [(set (reg:HI FPCR_REG)
4771         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4772   "TARGET_80387"
4773   "fldcw\t%0"
4774   [(set_attr "length" "2")
4775    (set_attr "mode" "HI")
4776    (set_attr "unit" "i387")
4777    (set_attr "athlon_decode" "vector")
4778    (set_attr "amdfam10_decode" "vector")])
4779 \f
4780 ;; Conversion between fixed point and floating point.
4781
4782 ;; Even though we only accept memory inputs, the backend _really_
4783 ;; wants to be able to do this between registers.
4784
4785 (define_expand "floathi<mode>2"
4786   [(set (match_operand:MODEF 0 "register_operand" "")
4787         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4788   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4789 {
4790   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791     {
4792       emit_insn
4793         (gen_floatsi<mode>2 (operands[0],
4794                              convert_to_mode (SImode, operands[1], 0)));
4795       DONE;
4796     }
4797 })
4798
4799 (define_insn "*floathi<mode>2_i387"
4800   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4801         (float:MODEF
4802           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4803   "TARGET_80387
4804    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4805        || TARGET_MIX_SSE_I387)"
4806   "@
4807    fild%z1\t%1
4808    #"
4809   [(set_attr "type" "fmov,multi")
4810    (set_attr "mode" "<MODE>")
4811    (set_attr "unit" "*,i387")
4812    (set_attr "fp_int_src" "true")])
4813
4814 (define_expand "floatsi<mode>2"
4815   [(set (match_operand:MODEF 0 "register_operand" "")
4816         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4817   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4818   "
4819    /* When we use vector converts, we can't have input in memory.  */
4820    if (GET_MODE (operands[0]) == DFmode
4821        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4822        && SSE_FLOAT_MODE_P (DFmode))
4823      operands[1] = force_reg (SImode, operands[1]);
4824    else if (GET_MODE (operands[0]) == SFmode
4825             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4826             && SSE_FLOAT_MODE_P (SFmode))
4827      {
4828        /* When !flag_trapping_math, we handle SImode->SFmode vector
4829           conversions same way as SImode->DFmode.
4830
4831           For flat_trapping_math we can't safely use vector conversion without
4832           clearing upper half, otherwise precision exception might occur.
4833           However we can still generate the common sequence converting value
4834           from general register to XMM register as:
4835
4836             mov         reg32, mem32
4837             movd        mem32, xmm
4838             cvtdq2pd xmm,xmm
4839
4840           because we know that movd clears the upper half.
4841
4842           Sadly in this case we can't rely on reload moving the value to XMM
4843           register, since we need to know if upper half is OK, so we need
4844           to do reloading by hand.  We force operand to memory unless target
4845           supports inter unit moves.  */
4846        if (!flag_trapping_math)
4847          operands[1] = force_reg (SImode, operands[1]);
4848        else if (!MEM_P (operands[1]))
4849          {
4850            int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4851            rtx tmp = assign_386_stack_local (SImode, slot);
4852            emit_move_insn (tmp, operands[1]);
4853            operands[1] = tmp;
4854          }
4855      }
4856    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4857       !TARGET_INTER_UNIT_CONVERSIONS
4858       It is necessary for the patterns to not accept nonmemory operands
4859       as we would optimize out later.  */
4860    else if (!TARGET_INTER_UNIT_CONVERSIONS
4861             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4862             && !optimize_size
4863             && !MEM_P (operands[1]))
4864      {
4865        int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4866        rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4867        emit_move_insn (tmp, operands[1]);
4868        operands[1] = tmp;
4869      }
4870   ")
4871
4872 (define_insn "*floatsisf2_mixed_vector"
4873   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4874         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4875   "TARGET_MIX_SSE_I387 && !flag_trapping_math
4876    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4877   "@
4878    cvtdq2ps\t{%1, %0|%0, %1}
4879    fild%z1\t%1
4880    #"
4881   [(set_attr "type" "sseicvt,fmov,multi")
4882    (set_attr "mode" "SF")
4883    (set_attr "unit" "*,i387,*")
4884    (set_attr "athlon_decode" "double,*,*")
4885    (set_attr "amdfam10_decode" "double,*,*")
4886    (set_attr "fp_int_src" "false,true,true")])
4887
4888 (define_insn "*floatsisf2_mixed"
4889   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4890         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4891   "TARGET_MIX_SSE_I387
4892    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4893        || optimize_size)"
4894   "@
4895    fild%z1\t%1
4896    #
4897    cvtsi2ss\t{%1, %0|%0, %1}
4898    cvtsi2ss\t{%1, %0|%0, %1}"
4899   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4900    (set_attr "mode" "SF")
4901    (set_attr "unit" "*,i387,*,*")
4902    (set_attr "athlon_decode" "*,*,vector,double")
4903    (set_attr "amdfam10_decode" "*,*,vector,double")
4904    (set_attr "fp_int_src" "true")])
4905
4906 (define_insn "*floatsisf2_mixed_memory"
4907   [(set (match_operand:SF 0 "register_operand" "=f,x")
4908         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4909   "TARGET_MIX_SSE_I387
4910    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4911   "@
4912    fild%z1\t%1
4913    cvtsi2ss\t{%1, %0|%0, %1}"
4914   [(set_attr "type" "fmov,sseicvt")
4915    (set_attr "mode" "SF")
4916    (set_attr "athlon_decode" "*,double")
4917    (set_attr "amdfam10_decode" "*,double")
4918    (set_attr "fp_int_src" "true")])
4919
4920 (define_insn "*floatsisf2_sse_vector_nointernunit"
4921   [(set (match_operand:SF 0 "register_operand" "=x")
4922         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4923   "TARGET_SSE_MATH && flag_trapping_math
4924    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4925    && !TARGET_INTER_UNIT_MOVES"
4926   "#"
4927   [(set_attr "type" "multi")])
4928
4929 (define_insn "*floatsisf2_sse_vector_internunit"
4930   [(set (match_operand:SF 0 "register_operand" "=x,x")
4931         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4932   "TARGET_SSE_MATH && flag_trapping_math
4933    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4934    && TARGET_INTER_UNIT_MOVES"
4935   "#"
4936   [(set_attr "type" "multi")])
4937
4938 (define_split
4939   [(set (match_operand:SF 0 "register_operand" "")
4940         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4941   "flag_trapping_math
4942    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4943    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4944    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4945   [(set (match_dup 0)
4946         (float:V4SF (match_dup 2)))]
4947 {
4948   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4949   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4950   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4951 })
4952
4953 (define_split
4954   [(set (match_operand:SF 0 "register_operand" "")
4955         (float:SF (match_operand:SI 1 "register_operand" "")))]
4956   "flag_trapping_math
4957    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4958    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4959   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4960    (set (match_dup 0)
4961         (float:V4SF (match_dup 2)))]
4962 {
4963   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4964   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4965 })
4966
4967 (define_insn "*floatsisf2_sse_vector"
4968   [(set (match_operand:SF 0 "register_operand" "=x")
4969         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4970   "TARGET_SSE_MATH && !flag_trapping_math
4971    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4972    && !TARGET_INTER_UNIT_MOVES"
4973   "cvtdq2ps\t{%1, %0|%0, %1}"
4974   [(set_attr "type" "sseicvt")
4975    (set_attr "mode" "SF")
4976    (set_attr "athlon_decode" "double")
4977    (set_attr "amdfam10_decode" "double")
4978    (set_attr "fp_int_src" "true")])
4979
4980 (define_insn "*floatsisf2_sse"
4981   [(set (match_operand:SF 0 "register_operand" "=x,x")
4982         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4983   "TARGET_SSE_MATH
4984    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4985        || optimize_size)"
4986   "cvtsi2ss\t{%1, %0|%0, %1}"
4987   [(set_attr "type" "sseicvt")
4988    (set_attr "mode" "SF")
4989    (set_attr "athlon_decode" "vector,double")
4990    (set_attr "amdfam10_decode" "vector,double")
4991    (set_attr "fp_int_src" "true")])
4992
4993 (define_insn "*floatsisf2_sse_memory"
4994   [(set (match_operand:SF 0 "register_operand" "=x")
4995         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4996   "TARGET_SSE_MATH
4997    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4998   "cvtsi2ss\t{%1, %0|%0, %1}"
4999   [(set_attr "type" "sseicvt")
5000    (set_attr "mode" "SF")
5001    (set_attr "athlon_decode" "double")
5002    (set_attr "amdfam10_decode" "double")
5003    (set_attr "fp_int_src" "true")])
5004
5005 (define_insn "*floatsidf2_mixed_vector"
5006   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5007         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5008   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5009    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5010   "@
5011    cvtdq2pd\t{%1, %0|%0, %1}
5012    fild%z1\t%1
5013    #"
5014   [(set_attr "type" "sseicvt,fmov,multi")
5015    (set_attr "mode" "V2DF,DF,DF")
5016    (set_attr "unit" "*,*,i387")
5017    (set_attr "athlon_decode" "double,*,*")
5018    (set_attr "amdfam10_decode" "double,*,*")
5019    (set_attr "fp_int_src" "false,true,true")])
5020
5021 (define_insn "*floatsidf2_mixed"
5022   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5023         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5024   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5025    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5026        || optimize_size)"
5027   "@
5028    fild%z1\t%1
5029    #
5030    cvtsi2sd\t{%1, %0|%0, %1}
5031    cvtsi2sd\t{%1, %0|%0, %1}
5032    cvtdq2pd\t{%1, %0|%0, %1}"
5033   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5034    (set_attr "mode" "DF,DF,DF,DF,V2DF")
5035    (set_attr "unit" "*,i387,*,*,*")
5036    (set_attr "athlon_decode" "*,*,double,direct,double")
5037    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5038    (set_attr "fp_int_src" "true,true,true,true,false")])
5039
5040 (define_insn "*floatsidf2_mixed_memory"
5041   [(set (match_operand:DF 0 "register_operand" "=f,x")
5042         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5043   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5044    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5045   "@
5046    fild%z1\t%1
5047    cvtsi2sd\t{%1, %0|%0, %1}"
5048   [(set_attr "type" "fmov,sseicvt")
5049    (set_attr "mode" "DF")
5050    (set_attr "athlon_decode" "*,direct")
5051    (set_attr "amdfam10_decode" "*,double")
5052    (set_attr "fp_int_src" "true")])
5053
5054 (define_insn "*floatsidf2_sse_vector"
5055   [(set (match_operand:DF 0 "register_operand" "=x")
5056         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5057   "TARGET_SSE2 && TARGET_SSE_MATH
5058    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5059   "cvtdq2pd\t{%1, %0|%0, %1}"
5060   [(set_attr "type" "sseicvt")
5061    (set_attr "mode" "V2DF")
5062    (set_attr "athlon_decode" "double")
5063    (set_attr "amdfam10_decode" "double")
5064    (set_attr "fp_int_src" "true")])
5065
5066 (define_split
5067   [(set (match_operand:DF 0 "register_operand" "")
5068         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5069   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5070    && SSE_REG_P (operands[0])"
5071   [(set (match_dup 0)
5072         (float:V2DF
5073           (vec_select:V2SI
5074             (match_dup 2)
5075             (parallel [(const_int 0) (const_int 1)]))))]
5076 {
5077   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5078   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5079   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5080 })
5081
5082 (define_insn "*floatsidf2_sse"
5083   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5084         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5085   "TARGET_SSE2 && TARGET_SSE_MATH
5086    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5087        || optimize_size)"
5088   "@
5089    cvtsi2sd\t{%1, %0|%0, %1}
5090    cvtsi2sd\t{%1, %0|%0, %1}
5091    cvtdq2pd\t{%1, %0|%0, %1}"
5092   [(set_attr "type" "sseicvt")
5093    (set_attr "mode" "DF,DF,V2DF")
5094    (set_attr "athlon_decode" "double,direct,double")
5095    (set_attr "amdfam10_decode" "vector,double,double")
5096    (set_attr "fp_int_src" "true")])
5097
5098 (define_insn "*floatsidf2_memory"
5099   [(set (match_operand:DF 0 "register_operand" "=x")
5100         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5101   "TARGET_SSE2 && TARGET_SSE_MATH
5102    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5103        || optimize_size)"
5104   "cvtsi2sd\t{%1, %0|%0, %1}"
5105   [(set_attr "type" "sseicvt")
5106    (set_attr "mode" "DF")
5107    (set_attr "athlon_decode" "direct")
5108    (set_attr "amdfam10_decode" "double")
5109    (set_attr "fp_int_src" "true")])
5110
5111 (define_insn "*floatsi<mode>2_i387"
5112   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5113         (float:MODEF
5114           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5115   "TARGET_80387
5116    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5117   "@
5118    fild%z1\t%1
5119    #"
5120   [(set_attr "type" "fmov,multi")
5121    (set_attr "mode" "<MODE>")
5122    (set_attr "unit" "*,i387")
5123    (set_attr "fp_int_src" "true")])
5124
5125 (define_expand "floatdisf2"
5126   [(set (match_operand:SF 0 "register_operand" "")
5127         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5128   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5129 {
5130   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5131       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5132       && !optimize_size
5133       && !MEM_P (operands[1]))
5134     {
5135       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5136       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5137       emit_move_insn (tmp, operands[1]);
5138       operands[1] = tmp;
5139     }
5140 })
5141
5142 (define_insn "*floatdisf2_mixed"
5143   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5144         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5145   "TARGET_64BIT && TARGET_MIX_SSE_I387
5146    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5147   "@
5148    fild%z1\t%1
5149    #
5150    cvtsi2ss{q}\t{%1, %0|%0, %1}
5151    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5152   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5153    (set_attr "mode" "SF")
5154    (set_attr "unit" "*,i387,*,*")
5155    (set_attr "athlon_decode" "*,*,vector,double")
5156    (set_attr "amdfam10_decode" "*,*,vector,double")
5157    (set_attr "fp_int_src" "true")])
5158
5159 (define_insn "*floatdisf2_mixed"
5160   [(set (match_operand:SF 0 "register_operand" "=f,x")
5161         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5162   "TARGET_64BIT && TARGET_MIX_SSE_I387
5163    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5164   "@
5165    fild%z1\t%1
5166    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5167   [(set_attr "type" "fmov,sseicvt")
5168    (set_attr "mode" "SF")
5169    (set_attr "athlon_decode" "*,double")
5170    (set_attr "amdfam10_decode" "*,double")
5171    (set_attr "fp_int_src" "true")])
5172
5173 (define_insn "*floatdisf2_sse"
5174   [(set (match_operand:SF 0 "register_operand" "=x,x")
5175         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5176   "TARGET_64BIT && TARGET_SSE_MATH
5177    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5178   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5179   [(set_attr "type" "sseicvt")
5180    (set_attr "mode" "SF")
5181    (set_attr "athlon_decode" "vector,double")
5182    (set_attr "amdfam10_decode" "vector,double")
5183    (set_attr "fp_int_src" "true")])
5184
5185 (define_insn "*floatdisf2_memory"
5186   [(set (match_operand:SF 0 "register_operand" "=x")
5187         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5188   "TARGET_64BIT && TARGET_SSE_MATH
5189    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5190   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5191   [(set_attr "type" "sseicvt")
5192    (set_attr "mode" "SF")
5193    (set_attr "athlon_decode" "double")
5194    (set_attr "amdfam10_decode" "double")
5195    (set_attr "fp_int_src" "true")])
5196
5197 (define_expand "floatdidf2"
5198   [(set (match_operand:DF 0 "register_operand" "")
5199         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5200   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5201 {
5202   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5203     {
5204       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5205       DONE;
5206     }
5207   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5208       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5209       && !optimize_size
5210       && !MEM_P (operands[1]))
5211     {
5212       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5213       rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5214       emit_move_insn (tmp, operands[1]);
5215       operands[1] = tmp;
5216     }
5217 })
5218
5219 (define_insn "*floatdidf2_mixed"
5220   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5221         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5222   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5223    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5224   "@
5225    fild%z1\t%1
5226    #
5227    cvtsi2sd{q}\t{%1, %0|%0, %1}
5228    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5229   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5230    (set_attr "mode" "DF")
5231    (set_attr "unit" "*,i387,*,*")
5232    (set_attr "athlon_decode" "*,*,double,direct")
5233    (set_attr "amdfam10_decode" "*,*,vector,double")
5234    (set_attr "fp_int_src" "true")])
5235
5236 (define_insn "*floatdidf2_mixed_memory"
5237   [(set (match_operand:DF 0 "register_operand" "=f,x")
5238         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5239   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5240    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5241   "@
5242    fild%z1\t%1
5243    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5244   [(set_attr "type" "fmov,sseicvt")
5245    (set_attr "mode" "DF")
5246    (set_attr "athlon_decode" "*,direct")
5247    (set_attr "amdfam10_decode" "*,double")
5248    (set_attr "fp_int_src" "true")])
5249
5250 (define_insn "*floatdidf2_sse"
5251   [(set (match_operand:DF 0 "register_operand" "=x,x")
5252         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5253   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5254    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5255   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5256   [(set_attr "type" "sseicvt")
5257    (set_attr "mode" "DF")
5258    (set_attr "athlon_decode" "double,direct")
5259    (set_attr "amdfam10_decode" "vector,double")
5260    (set_attr "fp_int_src" "true")])
5261
5262 (define_insn "*floatdidf2_sse_memory"
5263   [(set (match_operand:DF 0 "register_operand" "=x")
5264         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5265   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5266    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5267   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5268   [(set_attr "type" "sseicvt")
5269    (set_attr "mode" "DF")
5270    (set_attr "athlon_decode" "direct")
5271    (set_attr "amdfam10_decode" "double")
5272    (set_attr "fp_int_src" "true")])
5273
5274 (define_insn "*floatdi<mode>2_i387"
5275   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5276         (float:MODEF
5277           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5278   "TARGET_80387
5279    && (!TARGET_SSE_MATH || !TARGET_64BIT
5280        || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5281   "@
5282    fild%z1\t%1
5283    #"
5284   [(set_attr "type" "fmov,multi")
5285    (set_attr "mode" "<MODE>")
5286    (set_attr "unit" "*,i387")
5287    (set_attr "fp_int_src" "true")])
5288
5289 (define_insn "float<mode>xf2"
5290   [(set (match_operand:XF 0 "register_operand" "=f,f")
5291         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5292   "TARGET_80387"
5293   "@
5294    fild%z1\t%1
5295    #"
5296   [(set_attr "type" "fmov,multi")
5297    (set_attr "mode" "XF")
5298    (set_attr "unit" "*,i387")
5299    (set_attr "fp_int_src" "true")])
5300
5301 ;; %%% Kill these when reload knows how to do it.
5302 (define_split
5303   [(set (match_operand 0 "fp_register_operand" "")
5304         (float (match_operand 1 "register_operand" "")))]
5305   "reload_completed
5306    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5307   [(const_int 0)]
5308 {
5309   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5310   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5311   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5312   ix86_free_from_memory (GET_MODE (operands[1]));
5313   DONE;
5314 })
5315
5316 (define_expand "floatunssi<mode>2"
5317   [(use (match_operand:MODEF 0 "register_operand" ""))
5318    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5319   "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5320 {
5321   ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5322   DONE;
5323 })
5324
5325 (define_expand "floatunsdisf2"
5326   [(use (match_operand:SF 0 "register_operand" ""))
5327    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5328   "TARGET_64BIT && TARGET_SSE_MATH"
5329   "x86_emit_floatuns (operands); DONE;")
5330
5331 (define_expand "floatunsdidf2"
5332   [(use (match_operand:DF 0 "register_operand" ""))
5333    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5334   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5335    && TARGET_SSE2 && TARGET_SSE_MATH"
5336 {
5337   if (TARGET_64BIT)
5338     x86_emit_floatuns (operands);
5339   else
5340     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5341   DONE;
5342 })
5343 \f
5344 ;; Add instructions
5345
5346 ;; %%% splits for addditi3
5347
5348 (define_expand "addti3"
5349   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5350         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5351                  (match_operand:TI 2 "x86_64_general_operand" "")))
5352    (clobber (reg:CC FLAGS_REG))]
5353   "TARGET_64BIT"
5354   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5355
5356 (define_insn "*addti3_1"
5357   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5358         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5359                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5360    (clobber (reg:CC FLAGS_REG))]
5361   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5362   "#")
5363
5364 (define_split
5365   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5366         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5367                  (match_operand:TI 2 "x86_64_general_operand" "")))
5368    (clobber (reg:CC FLAGS_REG))]
5369   "TARGET_64BIT && reload_completed"
5370   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5371                                           UNSPEC_ADD_CARRY))
5372               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5373    (parallel [(set (match_dup 3)
5374                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5375                                      (match_dup 4))
5376                             (match_dup 5)))
5377               (clobber (reg:CC FLAGS_REG))])]
5378   "split_ti (operands+0, 1, operands+0, operands+3);
5379    split_ti (operands+1, 1, operands+1, operands+4);
5380    split_ti (operands+2, 1, operands+2, operands+5);")
5381
5382 ;; %%% splits for addsidi3
5383 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5384 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5385 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5386
5387 (define_expand "adddi3"
5388   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5389         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5390                  (match_operand:DI 2 "x86_64_general_operand" "")))
5391    (clobber (reg:CC FLAGS_REG))]
5392   ""
5393   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5394
5395 (define_insn "*adddi3_1"
5396   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5397         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5398                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5399    (clobber (reg:CC FLAGS_REG))]
5400   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5401   "#")
5402
5403 (define_split
5404   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5405         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5406                  (match_operand:DI 2 "general_operand" "")))
5407    (clobber (reg:CC FLAGS_REG))]
5408   "!TARGET_64BIT && reload_completed"
5409   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5410                                           UNSPEC_ADD_CARRY))
5411               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5412    (parallel [(set (match_dup 3)
5413                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5414                                      (match_dup 4))
5415                             (match_dup 5)))
5416               (clobber (reg:CC FLAGS_REG))])]
5417   "split_di (operands+0, 1, operands+0, operands+3);
5418    split_di (operands+1, 1, operands+1, operands+4);
5419    split_di (operands+2, 1, operands+2, operands+5);")
5420
5421 (define_insn "adddi3_carry_rex64"
5422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5423           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5424                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5425                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5426    (clobber (reg:CC FLAGS_REG))]
5427   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5428   "adc{q}\t{%2, %0|%0, %2}"
5429   [(set_attr "type" "alu")
5430    (set_attr "pent_pair" "pu")
5431    (set_attr "mode" "DI")])
5432
5433 (define_insn "*adddi3_cc_rex64"
5434   [(set (reg:CC FLAGS_REG)
5435         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5436                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5437                    UNSPEC_ADD_CARRY))
5438    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5439         (plus:DI (match_dup 1) (match_dup 2)))]
5440   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5441   "add{q}\t{%2, %0|%0, %2}"
5442   [(set_attr "type" "alu")
5443    (set_attr "mode" "DI")])
5444
5445 (define_insn "*<addsub><mode>3_cc_overflow"
5446   [(set (reg:CCC FLAGS_REG)
5447         (compare:CCC
5448             (plusminus:SWI
5449                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5450                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5451             (match_dup 1)))
5452    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5453         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5454   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5455   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5456   [(set_attr "type" "alu")
5457    (set_attr "mode" "<MODE>")])
5458
5459 (define_insn "*add<mode>3_cconly_overflow"
5460   [(set (reg:CCC FLAGS_REG)
5461         (compare:CCC
5462                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5463                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5464                 (match_dup 1)))
5465    (clobber (match_scratch:SWI 0 "=<r>"))]
5466   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5467   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5468   [(set_attr "type" "alu")
5469    (set_attr "mode" "<MODE>")])
5470
5471 (define_insn "*sub<mode>3_cconly_overflow"
5472   [(set (reg:CCC FLAGS_REG)
5473         (compare:CCC
5474              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5475                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5476              (match_dup 0)))]
5477   ""
5478   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5479   [(set_attr "type" "icmp")
5480    (set_attr "mode" "<MODE>")])
5481
5482 (define_insn "*<addsub>si3_zext_cc_overflow"
5483   [(set (reg:CCC FLAGS_REG)
5484         (compare:CCC
5485             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5486                           (match_operand:SI 2 "general_operand" "g"))
5487             (match_dup 1)))
5488    (set (match_operand:DI 0 "register_operand" "=r")
5489         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5490   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5491   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5492   [(set_attr "type" "alu")
5493    (set_attr "mode" "SI")])
5494
5495 (define_insn "addqi3_carry"
5496   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5497           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5498                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5499                    (match_operand:QI 2 "general_operand" "qi,qm")))
5500    (clobber (reg:CC FLAGS_REG))]
5501   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5502   "adc{b}\t{%2, %0|%0, %2}"
5503   [(set_attr "type" "alu")
5504    (set_attr "pent_pair" "pu")
5505    (set_attr "mode" "QI")])
5506
5507 (define_insn "addhi3_carry"
5508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5509           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5510                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5511                    (match_operand:HI 2 "general_operand" "ri,rm")))
5512    (clobber (reg:CC FLAGS_REG))]
5513   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5514   "adc{w}\t{%2, %0|%0, %2}"
5515   [(set_attr "type" "alu")
5516    (set_attr "pent_pair" "pu")
5517    (set_attr "mode" "HI")])
5518
5519 (define_insn "addsi3_carry"
5520   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5521           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5522                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5523                    (match_operand:SI 2 "general_operand" "ri,rm")))
5524    (clobber (reg:CC FLAGS_REG))]
5525   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5526   "adc{l}\t{%2, %0|%0, %2}"
5527   [(set_attr "type" "alu")
5528    (set_attr "pent_pair" "pu")
5529    (set_attr "mode" "SI")])
5530
5531 (define_insn "*addsi3_carry_zext"
5532   [(set (match_operand:DI 0 "register_operand" "=r")
5533           (zero_extend:DI
5534             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5535                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5536                      (match_operand:SI 2 "general_operand" "g"))))
5537    (clobber (reg:CC FLAGS_REG))]
5538   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5539   "adc{l}\t{%2, %k0|%k0, %2}"
5540   [(set_attr "type" "alu")
5541    (set_attr "pent_pair" "pu")
5542    (set_attr "mode" "SI")])
5543
5544 (define_insn "*addsi3_cc"
5545   [(set (reg:CC FLAGS_REG)
5546         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5547                     (match_operand:SI 2 "general_operand" "ri,rm")]
5548                    UNSPEC_ADD_CARRY))
5549    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5550         (plus:SI (match_dup 1) (match_dup 2)))]
5551   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5552   "add{l}\t{%2, %0|%0, %2}"
5553   [(set_attr "type" "alu")
5554    (set_attr "mode" "SI")])
5555
5556 (define_insn "addqi3_cc"
5557   [(set (reg:CC FLAGS_REG)
5558         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5559                     (match_operand:QI 2 "general_operand" "qi,qm")]
5560                    UNSPEC_ADD_CARRY))
5561    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5562         (plus:QI (match_dup 1) (match_dup 2)))]
5563   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5564   "add{b}\t{%2, %0|%0, %2}"
5565   [(set_attr "type" "alu")
5566    (set_attr "mode" "QI")])
5567
5568 (define_expand "addsi3"
5569   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5570                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5571                             (match_operand:SI 2 "general_operand" "")))
5572               (clobber (reg:CC FLAGS_REG))])]
5573   ""
5574   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5575
5576 (define_insn "*lea_1"
5577   [(set (match_operand:SI 0 "register_operand" "=r")
5578         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5579   "!TARGET_64BIT"
5580   "lea{l}\t{%a1, %0|%0, %a1}"
5581   [(set_attr "type" "lea")
5582    (set_attr "mode" "SI")])
5583
5584 (define_insn "*lea_1_rex64"
5585   [(set (match_operand:SI 0 "register_operand" "=r")
5586         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5587   "TARGET_64BIT"
5588   "lea{l}\t{%a1, %0|%0, %a1}"
5589   [(set_attr "type" "lea")
5590    (set_attr "mode" "SI")])
5591
5592 (define_insn "*lea_1_zext"
5593   [(set (match_operand:DI 0 "register_operand" "=r")
5594         (zero_extend:DI
5595          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5596   "TARGET_64BIT"
5597   "lea{l}\t{%a1, %k0|%k0, %a1}"
5598   [(set_attr "type" "lea")
5599    (set_attr "mode" "SI")])
5600
5601 (define_insn "*lea_2_rex64"
5602   [(set (match_operand:DI 0 "register_operand" "=r")
5603         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5604   "TARGET_64BIT"
5605   "lea{q}\t{%a1, %0|%0, %a1}"
5606   [(set_attr "type" "lea")
5607    (set_attr "mode" "DI")])
5608
5609 ;; The lea patterns for non-Pmodes needs to be matched by several
5610 ;; insns converted to real lea by splitters.
5611
5612 (define_insn_and_split "*lea_general_1"
5613   [(set (match_operand 0 "register_operand" "=r")
5614         (plus (plus (match_operand 1 "index_register_operand" "l")
5615                     (match_operand 2 "register_operand" "r"))
5616               (match_operand 3 "immediate_operand" "i")))]
5617   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5618     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5619    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5620    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5621    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5622    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5623        || GET_MODE (operands[3]) == VOIDmode)"
5624   "#"
5625   "&& reload_completed"
5626   [(const_int 0)]
5627 {
5628   rtx pat;
5629   operands[0] = gen_lowpart (SImode, operands[0]);
5630   operands[1] = gen_lowpart (Pmode, operands[1]);
5631   operands[2] = gen_lowpart (Pmode, operands[2]);
5632   operands[3] = gen_lowpart (Pmode, operands[3]);
5633   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5634                       operands[3]);
5635   if (Pmode != SImode)
5636     pat = gen_rtx_SUBREG (SImode, pat, 0);
5637   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5638   DONE;
5639 }
5640   [(set_attr "type" "lea")
5641    (set_attr "mode" "SI")])
5642
5643 (define_insn_and_split "*lea_general_1_zext"
5644   [(set (match_operand:DI 0 "register_operand" "=r")
5645         (zero_extend:DI
5646           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5647                             (match_operand:SI 2 "register_operand" "r"))
5648                    (match_operand:SI 3 "immediate_operand" "i"))))]
5649   "TARGET_64BIT"
5650   "#"
5651   "&& reload_completed"
5652   [(set (match_dup 0)
5653         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5654                                                      (match_dup 2))
5655                                             (match_dup 3)) 0)))]
5656 {
5657   operands[1] = gen_lowpart (Pmode, operands[1]);
5658   operands[2] = gen_lowpart (Pmode, operands[2]);
5659   operands[3] = gen_lowpart (Pmode, operands[3]);
5660 }
5661   [(set_attr "type" "lea")
5662    (set_attr "mode" "SI")])
5663
5664 (define_insn_and_split "*lea_general_2"
5665   [(set (match_operand 0 "register_operand" "=r")
5666         (plus (mult (match_operand 1 "index_register_operand" "l")
5667                     (match_operand 2 "const248_operand" "i"))
5668               (match_operand 3 "nonmemory_operand" "ri")))]
5669   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5670     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5671    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5672    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5673    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5674        || GET_MODE (operands[3]) == VOIDmode)"
5675   "#"
5676   "&& reload_completed"
5677   [(const_int 0)]
5678 {
5679   rtx pat;
5680   operands[0] = gen_lowpart (SImode, operands[0]);
5681   operands[1] = gen_lowpart (Pmode, operands[1]);
5682   operands[3] = gen_lowpart (Pmode, operands[3]);
5683   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5684                       operands[3]);
5685   if (Pmode != SImode)
5686     pat = gen_rtx_SUBREG (SImode, pat, 0);
5687   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5688   DONE;
5689 }
5690   [(set_attr "type" "lea")
5691    (set_attr "mode" "SI")])
5692
5693 (define_insn_and_split "*lea_general_2_zext"
5694   [(set (match_operand:DI 0 "register_operand" "=r")
5695         (zero_extend:DI
5696           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5697                             (match_operand:SI 2 "const248_operand" "n"))
5698                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5699   "TARGET_64BIT"
5700   "#"
5701   "&& reload_completed"
5702   [(set (match_dup 0)
5703         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5704                                                      (match_dup 2))
5705                                             (match_dup 3)) 0)))]
5706 {
5707   operands[1] = gen_lowpart (Pmode, operands[1]);
5708   operands[3] = gen_lowpart (Pmode, operands[3]);
5709 }
5710   [(set_attr "type" "lea")
5711    (set_attr "mode" "SI")])
5712
5713 (define_insn_and_split "*lea_general_3"
5714   [(set (match_operand 0 "register_operand" "=r")
5715         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5716                           (match_operand 2 "const248_operand" "i"))
5717                     (match_operand 3 "register_operand" "r"))
5718               (match_operand 4 "immediate_operand" "i")))]
5719   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5720     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5721    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5722    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5723    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5724   "#"
5725   "&& reload_completed"
5726   [(const_int 0)]
5727 {
5728   rtx pat;
5729   operands[0] = gen_lowpart (SImode, operands[0]);
5730   operands[1] = gen_lowpart (Pmode, operands[1]);
5731   operands[3] = gen_lowpart (Pmode, operands[3]);
5732   operands[4] = gen_lowpart (Pmode, operands[4]);
5733   pat = gen_rtx_PLUS (Pmode,
5734                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5735                                                          operands[2]),
5736                                     operands[3]),
5737                       operands[4]);
5738   if (Pmode != SImode)
5739     pat = gen_rtx_SUBREG (SImode, pat, 0);
5740   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5741   DONE;
5742 }
5743   [(set_attr "type" "lea")
5744    (set_attr "mode" "SI")])
5745
5746 (define_insn_and_split "*lea_general_3_zext"
5747   [(set (match_operand:DI 0 "register_operand" "=r")
5748         (zero_extend:DI
5749           (plus:SI (plus:SI (mult:SI
5750                               (match_operand:SI 1 "index_register_operand" "l")
5751                               (match_operand:SI 2 "const248_operand" "n"))
5752                             (match_operand:SI 3 "register_operand" "r"))
5753                    (match_operand:SI 4 "immediate_operand" "i"))))]
5754   "TARGET_64BIT"
5755   "#"
5756   "&& reload_completed"
5757   [(set (match_dup 0)
5758         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5759                                                               (match_dup 2))
5760                                                      (match_dup 3))
5761                                             (match_dup 4)) 0)))]
5762 {
5763   operands[1] = gen_lowpart (Pmode, operands[1]);
5764   operands[3] = gen_lowpart (Pmode, operands[3]);
5765   operands[4] = gen_lowpart (Pmode, operands[4]);
5766 }
5767   [(set_attr "type" "lea")
5768    (set_attr "mode" "SI")])
5769
5770 (define_insn "*adddi_1_rex64"
5771   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5772         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5773                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5774    (clobber (reg:CC FLAGS_REG))]
5775   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776 {
5777   switch (get_attr_type (insn))
5778     {
5779     case TYPE_LEA:
5780       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5781       return "lea{q}\t{%a2, %0|%0, %a2}";
5782
5783     case TYPE_INCDEC:
5784       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785       if (operands[2] == const1_rtx)
5786         return "inc{q}\t%0";
5787       else
5788         {
5789           gcc_assert (operands[2] == constm1_rtx);
5790           return "dec{q}\t%0";
5791         }
5792
5793     default:
5794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5795
5796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5798       if (CONST_INT_P (operands[2])
5799           /* Avoid overflows.  */
5800           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{q}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{q}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (cond [(eq_attr "alternative" "2")
5813               (const_string "lea")
5814             ; Current assemblers are broken and do not allow @GOTOFF in
5815             ; ought but a memory context.
5816             (match_operand:DI 2 "pic_symbolic_operand" "")
5817               (const_string "lea")
5818             (match_operand:DI 2 "incdec_operand" "")
5819               (const_string "incdec")
5820            ]
5821            (const_string "alu")))
5822    (set_attr "mode" "DI")])
5823
5824 ;; Convert lea to the lea pattern to avoid flags dependency.
5825 (define_split
5826   [(set (match_operand:DI 0 "register_operand" "")
5827         (plus:DI (match_operand:DI 1 "register_operand" "")
5828                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "TARGET_64BIT && reload_completed
5831    && true_regnum (operands[0]) != true_regnum (operands[1])"
5832   [(set (match_dup 0)
5833         (plus:DI (match_dup 1)
5834                  (match_dup 2)))]
5835   "")
5836
5837 (define_insn "*adddi_2_rex64"
5838   [(set (reg FLAGS_REG)
5839         (compare
5840           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5841                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5842           (const_int 0)))
5843    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5844         (plus:DI (match_dup 1) (match_dup 2)))]
5845   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5846    && ix86_binary_operator_ok (PLUS, DImode, operands)
5847    /* Current assemblers are broken and do not allow @GOTOFF in
5848       ought but a memory context.  */
5849    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5850 {
5851   switch (get_attr_type (insn))
5852     {
5853     case TYPE_INCDEC:
5854       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5855       if (operands[2] == const1_rtx)
5856         return "inc{q}\t%0";
5857       else
5858         {
5859           gcc_assert (operands[2] == constm1_rtx);
5860           return "dec{q}\t%0";
5861         }
5862
5863     default:
5864       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5865       /* ???? We ought to handle there the 32bit case too
5866          - do we need new constraint?  */
5867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5869       if (CONST_INT_P (operands[2])
5870           /* Avoid overflows.  */
5871           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5872           && (INTVAL (operands[2]) == 128
5873               || (INTVAL (operands[2]) < 0
5874                   && INTVAL (operands[2]) != -128)))
5875         {
5876           operands[2] = GEN_INT (-INTVAL (operands[2]));
5877           return "sub{q}\t{%2, %0|%0, %2}";
5878         }
5879       return "add{q}\t{%2, %0|%0, %2}";
5880     }
5881 }
5882   [(set (attr "type")
5883      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5884         (const_string "incdec")
5885         (const_string "alu")))
5886    (set_attr "mode" "DI")])
5887
5888 (define_insn "*adddi_3_rex64"
5889   [(set (reg FLAGS_REG)
5890         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5891                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5892    (clobber (match_scratch:DI 0 "=r"))]
5893   "TARGET_64BIT
5894    && ix86_match_ccmode (insn, CCZmode)
5895    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5896    /* Current assemblers are broken and do not allow @GOTOFF in
5897       ought but a memory context.  */
5898    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5899 {
5900   switch (get_attr_type (insn))
5901     {
5902     case TYPE_INCDEC:
5903       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5904       if (operands[2] == const1_rtx)
5905         return "inc{q}\t%0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{q}\t%0";
5910         }
5911
5912     default:
5913       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5914       /* ???? We ought to handle there the 32bit case too
5915          - do we need new constraint?  */
5916       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5917          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5918       if (CONST_INT_P (operands[2])
5919           /* Avoid overflows.  */
5920           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5921           && (INTVAL (operands[2]) == 128
5922               || (INTVAL (operands[2]) < 0
5923                   && INTVAL (operands[2]) != -128)))
5924         {
5925           operands[2] = GEN_INT (-INTVAL (operands[2]));
5926           return "sub{q}\t{%2, %0|%0, %2}";
5927         }
5928       return "add{q}\t{%2, %0|%0, %2}";
5929     }
5930 }
5931   [(set (attr "type")
5932      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5933         (const_string "incdec")
5934         (const_string "alu")))
5935    (set_attr "mode" "DI")])
5936
5937 ; For comparisons against 1, -1 and 128, we may generate better code
5938 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5939 ; is matched then.  We can't accept general immediate, because for
5940 ; case of overflows,  the result is messed up.
5941 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5942 ; when negated.
5943 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5944 ; only for comparisons not depending on it.
5945 (define_insn "*adddi_4_rex64"
5946   [(set (reg FLAGS_REG)
5947         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5948                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5949    (clobber (match_scratch:DI 0 "=rm"))]
5950   "TARGET_64BIT
5951    &&  ix86_match_ccmode (insn, CCGCmode)"
5952 {
5953   switch (get_attr_type (insn))
5954     {
5955     case TYPE_INCDEC:
5956       if (operands[2] == constm1_rtx)
5957         return "inc{q}\t%0";
5958       else
5959         {
5960           gcc_assert (operands[2] == const1_rtx);
5961           return "dec{q}\t%0";
5962         }
5963
5964     default:
5965       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5968       if ((INTVAL (operands[2]) == -128
5969            || (INTVAL (operands[2]) > 0
5970                && INTVAL (operands[2]) != 128))
5971           /* Avoid overflows.  */
5972           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5973         return "sub{q}\t{%2, %0|%0, %2}";
5974       operands[2] = GEN_INT (-INTVAL (operands[2]));
5975       return "add{q}\t{%2, %0|%0, %2}";
5976     }
5977 }
5978   [(set (attr "type")
5979      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5980         (const_string "incdec")
5981         (const_string "alu")))
5982    (set_attr "mode" "DI")])
5983
5984 (define_insn "*adddi_5_rex64"
5985   [(set (reg FLAGS_REG)
5986         (compare
5987           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5988                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5989           (const_int 0)))
5990    (clobber (match_scratch:DI 0 "=r"))]
5991   "TARGET_64BIT
5992    && ix86_match_ccmode (insn, CCGOCmode)
5993    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5994    /* Current assemblers are broken and do not allow @GOTOFF in
5995       ought but a memory context.  */
5996    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5997 {
5998   switch (get_attr_type (insn))
5999     {
6000     case TYPE_INCDEC:
6001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002       if (operands[2] == const1_rtx)
6003         return "inc{q}\t%0";
6004       else
6005         {
6006           gcc_assert (operands[2] == constm1_rtx);
6007           return "dec{q}\t%0";
6008         }
6009
6010     default:
6011       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6012       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6013          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6014       if (CONST_INT_P (operands[2])
6015           /* Avoid overflows.  */
6016           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6017           && (INTVAL (operands[2]) == 128
6018               || (INTVAL (operands[2]) < 0
6019                   && INTVAL (operands[2]) != -128)))
6020         {
6021           operands[2] = GEN_INT (-INTVAL (operands[2]));
6022           return "sub{q}\t{%2, %0|%0, %2}";
6023         }
6024       return "add{q}\t{%2, %0|%0, %2}";
6025     }
6026 }
6027   [(set (attr "type")
6028      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6029         (const_string "incdec")
6030         (const_string "alu")))
6031    (set_attr "mode" "DI")])
6032
6033
6034 (define_insn "*addsi_1"
6035   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6036         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6037                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6038    (clobber (reg:CC FLAGS_REG))]
6039   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6040 {
6041   switch (get_attr_type (insn))
6042     {
6043     case TYPE_LEA:
6044       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6045       return "lea{l}\t{%a2, %0|%0, %a2}";
6046
6047     case TYPE_INCDEC:
6048       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049       if (operands[2] == const1_rtx)
6050         return "inc{l}\t%0";
6051       else
6052         {
6053           gcc_assert (operands[2] == constm1_rtx);
6054           return "dec{l}\t%0";
6055         }
6056
6057     default:
6058       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6059
6060       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6062       if (CONST_INT_P (operands[2])
6063           && (INTVAL (operands[2]) == 128
6064               || (INTVAL (operands[2]) < 0
6065                   && INTVAL (operands[2]) != -128)))
6066         {
6067           operands[2] = GEN_INT (-INTVAL (operands[2]));
6068           return "sub{l}\t{%2, %0|%0, %2}";
6069         }
6070       return "add{l}\t{%2, %0|%0, %2}";
6071     }
6072 }
6073   [(set (attr "type")
6074      (cond [(eq_attr "alternative" "2")
6075               (const_string "lea")
6076             ; Current assemblers are broken and do not allow @GOTOFF in
6077             ; ought but a memory context.
6078             (match_operand:SI 2 "pic_symbolic_operand" "")
6079               (const_string "lea")
6080             (match_operand:SI 2 "incdec_operand" "")
6081               (const_string "incdec")
6082            ]
6083            (const_string "alu")))
6084    (set_attr "mode" "SI")])
6085
6086 ;; Convert lea to the lea pattern to avoid flags dependency.
6087 (define_split
6088   [(set (match_operand 0 "register_operand" "")
6089         (plus (match_operand 1 "register_operand" "")
6090               (match_operand 2 "nonmemory_operand" "")))
6091    (clobber (reg:CC FLAGS_REG))]
6092   "reload_completed
6093    && true_regnum (operands[0]) != true_regnum (operands[1])"
6094   [(const_int 0)]
6095 {
6096   rtx pat;
6097   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6098      may confuse gen_lowpart.  */
6099   if (GET_MODE (operands[0]) != Pmode)
6100     {
6101       operands[1] = gen_lowpart (Pmode, operands[1]);
6102       operands[2] = gen_lowpart (Pmode, operands[2]);
6103     }
6104   operands[0] = gen_lowpart (SImode, operands[0]);
6105   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6106   if (Pmode != SImode)
6107     pat = gen_rtx_SUBREG (SImode, pat, 0);
6108   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6109   DONE;
6110 })
6111
6112 ;; It may seem that nonimmediate operand is proper one for operand 1.
6113 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6114 ;; we take care in ix86_binary_operator_ok to not allow two memory
6115 ;; operands so proper swapping will be done in reload.  This allow
6116 ;; patterns constructed from addsi_1 to match.
6117 (define_insn "addsi_1_zext"
6118   [(set (match_operand:DI 0 "register_operand" "=r,r")
6119         (zero_extend:DI
6120           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6121                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6122    (clobber (reg:CC FLAGS_REG))]
6123   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6124 {
6125   switch (get_attr_type (insn))
6126     {
6127     case TYPE_LEA:
6128       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6129       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6130
6131     case TYPE_INCDEC:
6132       if (operands[2] == const1_rtx)
6133         return "inc{l}\t%k0";
6134       else
6135         {
6136           gcc_assert (operands[2] == constm1_rtx);
6137           return "dec{l}\t%k0";
6138         }
6139
6140     default:
6141       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6143       if (CONST_INT_P (operands[2])
6144           && (INTVAL (operands[2]) == 128
6145               || (INTVAL (operands[2]) < 0
6146                   && INTVAL (operands[2]) != -128)))
6147         {
6148           operands[2] = GEN_INT (-INTVAL (operands[2]));
6149           return "sub{l}\t{%2, %k0|%k0, %2}";
6150         }
6151       return "add{l}\t{%2, %k0|%k0, %2}";
6152     }
6153 }
6154   [(set (attr "type")
6155      (cond [(eq_attr "alternative" "1")
6156               (const_string "lea")
6157             ; Current assemblers are broken and do not allow @GOTOFF in
6158             ; ought but a memory context.
6159             (match_operand:SI 2 "pic_symbolic_operand" "")
6160               (const_string "lea")
6161             (match_operand:SI 2 "incdec_operand" "")
6162               (const_string "incdec")
6163            ]
6164            (const_string "alu")))
6165    (set_attr "mode" "SI")])
6166
6167 ;; Convert lea to the lea pattern to avoid flags dependency.
6168 (define_split
6169   [(set (match_operand:DI 0 "register_operand" "")
6170         (zero_extend:DI
6171           (plus:SI (match_operand:SI 1 "register_operand" "")
6172                    (match_operand:SI 2 "nonmemory_operand" ""))))
6173    (clobber (reg:CC FLAGS_REG))]
6174   "TARGET_64BIT && reload_completed
6175    && true_regnum (operands[0]) != true_regnum (operands[1])"
6176   [(set (match_dup 0)
6177         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6178 {
6179   operands[1] = gen_lowpart (Pmode, operands[1]);
6180   operands[2] = gen_lowpart (Pmode, operands[2]);
6181 })
6182
6183 (define_insn "*addsi_2"
6184   [(set (reg FLAGS_REG)
6185         (compare
6186           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6187                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6188           (const_int 0)))
6189    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6190         (plus:SI (match_dup 1) (match_dup 2)))]
6191   "ix86_match_ccmode (insn, CCGOCmode)
6192    && ix86_binary_operator_ok (PLUS, SImode, operands)
6193    /* Current assemblers are broken and do not allow @GOTOFF in
6194       ought but a memory context.  */
6195    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6196 {
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201       if (operands[2] == const1_rtx)
6202         return "inc{l}\t%0";
6203       else
6204         {
6205           gcc_assert (operands[2] == constm1_rtx);
6206           return "dec{l}\t%0";
6207         }
6208
6209     default:
6210       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6212          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6213       if (CONST_INT_P (operands[2])
6214           && (INTVAL (operands[2]) == 128
6215               || (INTVAL (operands[2]) < 0
6216                   && INTVAL (operands[2]) != -128)))
6217         {
6218           operands[2] = GEN_INT (-INTVAL (operands[2]));
6219           return "sub{l}\t{%2, %0|%0, %2}";
6220         }
6221       return "add{l}\t{%2, %0|%0, %2}";
6222     }
6223 }
6224   [(set (attr "type")
6225      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6226         (const_string "incdec")
6227         (const_string "alu")))
6228    (set_attr "mode" "SI")])
6229
6230 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6231 (define_insn "*addsi_2_zext"
6232   [(set (reg FLAGS_REG)
6233         (compare
6234           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6235                    (match_operand:SI 2 "general_operand" "rmni"))
6236           (const_int 0)))
6237    (set (match_operand:DI 0 "register_operand" "=r")
6238         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6239   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6240    && ix86_binary_operator_ok (PLUS, SImode, operands)
6241    /* Current assemblers are broken and do not allow @GOTOFF in
6242       ought but a memory context.  */
6243    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6244 {
6245   switch (get_attr_type (insn))
6246     {
6247     case TYPE_INCDEC:
6248       if (operands[2] == const1_rtx)
6249         return "inc{l}\t%k0";
6250       else
6251         {
6252           gcc_assert (operands[2] == constm1_rtx);
6253           return "dec{l}\t%k0";
6254         }
6255
6256     default:
6257       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6258          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6259       if (CONST_INT_P (operands[2])
6260           && (INTVAL (operands[2]) == 128
6261               || (INTVAL (operands[2]) < 0
6262                   && INTVAL (operands[2]) != -128)))
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           return "sub{l}\t{%2, %k0|%k0, %2}";
6266         }
6267       return "add{l}\t{%2, %k0|%k0, %2}";
6268     }
6269 }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set_attr "mode" "SI")])
6275
6276 (define_insn "*addsi_3"
6277   [(set (reg FLAGS_REG)
6278         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6279                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6280    (clobber (match_scratch:SI 0 "=r"))]
6281   "ix86_match_ccmode (insn, CCZmode)
6282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6283    /* Current assemblers are broken and do not allow @GOTOFF in
6284       ought but a memory context.  */
6285    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6286 {
6287   switch (get_attr_type (insn))
6288     {
6289     case TYPE_INCDEC:
6290       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6291       if (operands[2] == const1_rtx)
6292         return "inc{l}\t%0";
6293       else
6294         {
6295           gcc_assert (operands[2] == constm1_rtx);
6296           return "dec{l}\t%0";
6297         }
6298
6299     default:
6300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6302          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6303       if (CONST_INT_P (operands[2])
6304           && (INTVAL (operands[2]) == 128
6305               || (INTVAL (operands[2]) < 0
6306                   && INTVAL (operands[2]) != -128)))
6307         {
6308           operands[2] = GEN_INT (-INTVAL (operands[2]));
6309           return "sub{l}\t{%2, %0|%0, %2}";
6310         }
6311       return "add{l}\t{%2, %0|%0, %2}";
6312     }
6313 }
6314   [(set (attr "type")
6315      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6316         (const_string "incdec")
6317         (const_string "alu")))
6318    (set_attr "mode" "SI")])
6319
6320 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6321 (define_insn "*addsi_3_zext"
6322   [(set (reg FLAGS_REG)
6323         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6324                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6325    (set (match_operand:DI 0 "register_operand" "=r")
6326         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6327   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6328    && ix86_binary_operator_ok (PLUS, SImode, operands)
6329    /* Current assemblers are broken and do not allow @GOTOFF in
6330       ought but a memory context.  */
6331    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6332 {
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[2] == const1_rtx)
6337         return "inc{l}\t%k0";
6338       else
6339         {
6340           gcc_assert (operands[2] == constm1_rtx);
6341           return "dec{l}\t%k0";
6342         }
6343
6344     default:
6345       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6346          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6347       if (CONST_INT_P (operands[2])
6348           && (INTVAL (operands[2]) == 128
6349               || (INTVAL (operands[2]) < 0
6350                   && INTVAL (operands[2]) != -128)))
6351         {
6352           operands[2] = GEN_INT (-INTVAL (operands[2]));
6353           return "sub{l}\t{%2, %k0|%k0, %2}";
6354         }
6355       return "add{l}\t{%2, %k0|%k0, %2}";
6356     }
6357 }
6358   [(set (attr "type")
6359      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6360         (const_string "incdec")
6361         (const_string "alu")))
6362    (set_attr "mode" "SI")])
6363
6364 ; For comparisons against 1, -1 and 128, we may generate better code
6365 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6366 ; is matched then.  We can't accept general immediate, because for
6367 ; case of overflows,  the result is messed up.
6368 ; This pattern also don't hold of 0x80000000, since the value overflows
6369 ; when negated.
6370 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6371 ; only for comparisons not depending on it.
6372 (define_insn "*addsi_4"
6373   [(set (reg FLAGS_REG)
6374         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6375                  (match_operand:SI 2 "const_int_operand" "n")))
6376    (clobber (match_scratch:SI 0 "=rm"))]
6377   "ix86_match_ccmode (insn, CCGCmode)
6378    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6379 {
6380   switch (get_attr_type (insn))
6381     {
6382     case TYPE_INCDEC:
6383       if (operands[2] == constm1_rtx)
6384         return "inc{l}\t%0";
6385       else
6386         {
6387           gcc_assert (operands[2] == const1_rtx);
6388           return "dec{l}\t%0";
6389         }
6390
6391     default:
6392       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6393       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6394          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6395       if ((INTVAL (operands[2]) == -128
6396            || (INTVAL (operands[2]) > 0
6397                && INTVAL (operands[2]) != 128)))
6398         return "sub{l}\t{%2, %0|%0, %2}";
6399       operands[2] = GEN_INT (-INTVAL (operands[2]));
6400       return "add{l}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set_attr "mode" "SI")])
6408
6409 (define_insn "*addsi_5"
6410   [(set (reg FLAGS_REG)
6411         (compare
6412           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6413                    (match_operand:SI 2 "general_operand" "rmni"))
6414           (const_int 0)))
6415    (clobber (match_scratch:SI 0 "=r"))]
6416   "ix86_match_ccmode (insn, CCGOCmode)
6417    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6418    /* Current assemblers are broken and do not allow @GOTOFF in
6419       ought but a memory context.  */
6420    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6421 {
6422   switch (get_attr_type (insn))
6423     {
6424     case TYPE_INCDEC:
6425       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6426       if (operands[2] == const1_rtx)
6427         return "inc{l}\t%0";
6428       else
6429         {
6430           gcc_assert (operands[2] == constm1_rtx);
6431           return "dec{l}\t%0";
6432         }
6433
6434     default:
6435       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6436       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6437          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6438       if (CONST_INT_P (operands[2])
6439           && (INTVAL (operands[2]) == 128
6440               || (INTVAL (operands[2]) < 0
6441                   && INTVAL (operands[2]) != -128)))
6442         {
6443           operands[2] = GEN_INT (-INTVAL (operands[2]));
6444           return "sub{l}\t{%2, %0|%0, %2}";
6445         }
6446       return "add{l}\t{%2, %0|%0, %2}";
6447     }
6448 }
6449   [(set (attr "type")
6450      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6451         (const_string "incdec")
6452         (const_string "alu")))
6453    (set_attr "mode" "SI")])
6454
6455 (define_expand "addhi3"
6456   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6457                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6458                             (match_operand:HI 2 "general_operand" "")))
6459               (clobber (reg:CC FLAGS_REG))])]
6460   "TARGET_HIMODE_MATH"
6461   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6462
6463 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6464 ;; type optimizations enabled by define-splits.  This is not important
6465 ;; for PII, and in fact harmful because of partial register stalls.
6466
6467 (define_insn "*addhi_1_lea"
6468   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6469         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6470                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6471    (clobber (reg:CC FLAGS_REG))]
6472   "!TARGET_PARTIAL_REG_STALL
6473    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6474 {
6475   switch (get_attr_type (insn))
6476     {
6477     case TYPE_LEA:
6478       return "#";
6479     case TYPE_INCDEC:
6480       if (operands[2] == const1_rtx)
6481         return "inc{w}\t%0";
6482       else
6483         {
6484           gcc_assert (operands[2] == constm1_rtx);
6485           return "dec{w}\t%0";
6486         }
6487
6488     default:
6489       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6490          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6491       if (CONST_INT_P (operands[2])
6492           && (INTVAL (operands[2]) == 128
6493               || (INTVAL (operands[2]) < 0
6494                   && INTVAL (operands[2]) != -128)))
6495         {
6496           operands[2] = GEN_INT (-INTVAL (operands[2]));
6497           return "sub{w}\t{%2, %0|%0, %2}";
6498         }
6499       return "add{w}\t{%2, %0|%0, %2}";
6500     }
6501 }
6502   [(set (attr "type")
6503      (if_then_else (eq_attr "alternative" "2")
6504         (const_string "lea")
6505         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6506            (const_string "incdec")
6507            (const_string "alu"))))
6508    (set_attr "mode" "HI,HI,SI")])
6509
6510 (define_insn "*addhi_1"
6511   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6512         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6513                  (match_operand:HI 2 "general_operand" "ri,rm")))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "TARGET_PARTIAL_REG_STALL
6516    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6517 {
6518   switch (get_attr_type (insn))
6519     {
6520     case TYPE_INCDEC:
6521       if (operands[2] == const1_rtx)
6522         return "inc{w}\t%0";
6523       else
6524         {
6525           gcc_assert (operands[2] == constm1_rtx);
6526           return "dec{w}\t%0";
6527         }
6528
6529     default:
6530       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6531          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6532       if (CONST_INT_P (operands[2])
6533           && (INTVAL (operands[2]) == 128
6534               || (INTVAL (operands[2]) < 0
6535                   && INTVAL (operands[2]) != -128)))
6536         {
6537           operands[2] = GEN_INT (-INTVAL (operands[2]));
6538           return "sub{w}\t{%2, %0|%0, %2}";
6539         }
6540       return "add{w}\t{%2, %0|%0, %2}";
6541     }
6542 }
6543   [(set (attr "type")
6544      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6545         (const_string "incdec")
6546         (const_string "alu")))
6547    (set_attr "mode" "HI")])
6548
6549 (define_insn "*addhi_2"
6550   [(set (reg FLAGS_REG)
6551         (compare
6552           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6553                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6554           (const_int 0)))
6555    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6556         (plus:HI (match_dup 1) (match_dup 2)))]
6557   "ix86_match_ccmode (insn, CCGOCmode)
6558    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6559 {
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{w}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx);
6568           return "dec{w}\t%0";
6569         }
6570
6571     default:
6572       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6573          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6574       if (CONST_INT_P (operands[2])
6575           && (INTVAL (operands[2]) == 128
6576               || (INTVAL (operands[2]) < 0
6577                   && INTVAL (operands[2]) != -128)))
6578         {
6579           operands[2] = GEN_INT (-INTVAL (operands[2]));
6580           return "sub{w}\t{%2, %0|%0, %2}";
6581         }
6582       return "add{w}\t{%2, %0|%0, %2}";
6583     }
6584 }
6585   [(set (attr "type")
6586      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6587         (const_string "incdec")
6588         (const_string "alu")))
6589    (set_attr "mode" "HI")])
6590
6591 (define_insn "*addhi_3"
6592   [(set (reg FLAGS_REG)
6593         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6594                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6595    (clobber (match_scratch:HI 0 "=r"))]
6596   "ix86_match_ccmode (insn, CCZmode)
6597    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6598 {
6599   switch (get_attr_type (insn))
6600     {
6601     case TYPE_INCDEC:
6602       if (operands[2] == const1_rtx)
6603         return "inc{w}\t%0";
6604       else
6605         {
6606           gcc_assert (operands[2] == constm1_rtx);
6607           return "dec{w}\t%0";
6608         }
6609
6610     default:
6611       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6612          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6613       if (CONST_INT_P (operands[2])
6614           && (INTVAL (operands[2]) == 128
6615               || (INTVAL (operands[2]) < 0
6616                   && INTVAL (operands[2]) != -128)))
6617         {
6618           operands[2] = GEN_INT (-INTVAL (operands[2]));
6619           return "sub{w}\t{%2, %0|%0, %2}";
6620         }
6621       return "add{w}\t{%2, %0|%0, %2}";
6622     }
6623 }
6624   [(set (attr "type")
6625      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6626         (const_string "incdec")
6627         (const_string "alu")))
6628    (set_attr "mode" "HI")])
6629
6630 ; See comments above addsi_4 for details.
6631 (define_insn "*addhi_4"
6632   [(set (reg FLAGS_REG)
6633         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6634                  (match_operand:HI 2 "const_int_operand" "n")))
6635    (clobber (match_scratch:HI 0 "=rm"))]
6636   "ix86_match_ccmode (insn, CCGCmode)
6637    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6638 {
6639   switch (get_attr_type (insn))
6640     {
6641     case TYPE_INCDEC:
6642       if (operands[2] == constm1_rtx)
6643         return "inc{w}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == const1_rtx);
6647           return "dec{w}\t%0";
6648         }
6649
6650     default:
6651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6653          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6654       if ((INTVAL (operands[2]) == -128
6655            || (INTVAL (operands[2]) > 0
6656                && INTVAL (operands[2]) != 128)))
6657         return "sub{w}\t{%2, %0|%0, %2}";
6658       operands[2] = GEN_INT (-INTVAL (operands[2]));
6659       return "add{w}\t{%2, %0|%0, %2}";
6660     }
6661 }
6662   [(set (attr "type")
6663      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6664         (const_string "incdec")
6665         (const_string "alu")))
6666    (set_attr "mode" "SI")])
6667
6668
6669 (define_insn "*addhi_5"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6673                    (match_operand:HI 2 "general_operand" "rmni"))
6674           (const_int 0)))
6675    (clobber (match_scratch:HI 0 "=r"))]
6676   "ix86_match_ccmode (insn, CCGOCmode)
6677    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678 {
6679   switch (get_attr_type (insn))
6680     {
6681     case TYPE_INCDEC:
6682       if (operands[2] == const1_rtx)
6683         return "inc{w}\t%0";
6684       else
6685         {
6686           gcc_assert (operands[2] == constm1_rtx);
6687           return "dec{w}\t%0";
6688         }
6689
6690     default:
6691       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6693       if (CONST_INT_P (operands[2])
6694           && (INTVAL (operands[2]) == 128
6695               || (INTVAL (operands[2]) < 0
6696                   && INTVAL (operands[2]) != -128)))
6697         {
6698           operands[2] = GEN_INT (-INTVAL (operands[2]));
6699           return "sub{w}\t{%2, %0|%0, %2}";
6700         }
6701       return "add{w}\t{%2, %0|%0, %2}";
6702     }
6703 }
6704   [(set (attr "type")
6705      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6706         (const_string "incdec")
6707         (const_string "alu")))
6708    (set_attr "mode" "HI")])
6709
6710 (define_expand "addqi3"
6711   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6712                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6713                             (match_operand:QI 2 "general_operand" "")))
6714               (clobber (reg:CC FLAGS_REG))])]
6715   "TARGET_QIMODE_MATH"
6716   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6717
6718 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6719 (define_insn "*addqi_1_lea"
6720   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6721         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6722                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "!TARGET_PARTIAL_REG_STALL
6725    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6726 {
6727   int widen = (which_alternative == 2);
6728   switch (get_attr_type (insn))
6729     {
6730     case TYPE_LEA:
6731       return "#";
6732     case TYPE_INCDEC:
6733       if (operands[2] == const1_rtx)
6734         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6735       else
6736         {
6737           gcc_assert (operands[2] == constm1_rtx);
6738           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6739         }
6740
6741     default:
6742       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6743          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6744       if (CONST_INT_P (operands[2])
6745           && (INTVAL (operands[2]) == 128
6746               || (INTVAL (operands[2]) < 0
6747                   && INTVAL (operands[2]) != -128)))
6748         {
6749           operands[2] = GEN_INT (-INTVAL (operands[2]));
6750           if (widen)
6751             return "sub{l}\t{%2, %k0|%k0, %2}";
6752           else
6753             return "sub{b}\t{%2, %0|%0, %2}";
6754         }
6755       if (widen)
6756         return "add{l}\t{%k2, %k0|%k0, %k2}";
6757       else
6758         return "add{b}\t{%2, %0|%0, %2}";
6759     }
6760 }
6761   [(set (attr "type")
6762      (if_then_else (eq_attr "alternative" "3")
6763         (const_string "lea")
6764         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6765            (const_string "incdec")
6766            (const_string "alu"))))
6767    (set_attr "mode" "QI,QI,SI,SI")])
6768
6769 (define_insn "*addqi_1"
6770   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6771         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6772                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6773    (clobber (reg:CC FLAGS_REG))]
6774   "TARGET_PARTIAL_REG_STALL
6775    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6776 {
6777   int widen = (which_alternative == 2);
6778   switch (get_attr_type (insn))
6779     {
6780     case TYPE_INCDEC:
6781       if (operands[2] == const1_rtx)
6782         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6783       else
6784         {
6785           gcc_assert (operands[2] == constm1_rtx);
6786           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6787         }
6788
6789     default:
6790       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6791          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6792       if (CONST_INT_P (operands[2])
6793           && (INTVAL (operands[2]) == 128
6794               || (INTVAL (operands[2]) < 0
6795                   && INTVAL (operands[2]) != -128)))
6796         {
6797           operands[2] = GEN_INT (-INTVAL (operands[2]));
6798           if (widen)
6799             return "sub{l}\t{%2, %k0|%k0, %2}";
6800           else
6801             return "sub{b}\t{%2, %0|%0, %2}";
6802         }
6803       if (widen)
6804         return "add{l}\t{%k2, %k0|%k0, %k2}";
6805       else
6806         return "add{b}\t{%2, %0|%0, %2}";
6807     }
6808 }
6809   [(set (attr "type")
6810      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6811         (const_string "incdec")
6812         (const_string "alu")))
6813    (set_attr "mode" "QI,QI,SI")])
6814
6815 (define_insn "*addqi_1_slp"
6816   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6817         (plus:QI (match_dup 0)
6818                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6819    (clobber (reg:CC FLAGS_REG))]
6820   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6821    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6822 {
6823   switch (get_attr_type (insn))
6824     {
6825     case TYPE_INCDEC:
6826       if (operands[1] == const1_rtx)
6827         return "inc{b}\t%0";
6828       else
6829         {
6830           gcc_assert (operands[1] == constm1_rtx);
6831           return "dec{b}\t%0";
6832         }
6833
6834     default:
6835       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6836       if (CONST_INT_P (operands[1])
6837           && INTVAL (operands[1]) < 0)
6838         {
6839           operands[1] = GEN_INT (-INTVAL (operands[1]));
6840           return "sub{b}\t{%1, %0|%0, %1}";
6841         }
6842       return "add{b}\t{%1, %0|%0, %1}";
6843     }
6844 }
6845   [(set (attr "type")
6846      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6847         (const_string "incdec")
6848         (const_string "alu1")))
6849    (set (attr "memory")
6850      (if_then_else (match_operand 1 "memory_operand" "")
6851         (const_string "load")
6852         (const_string "none")))
6853    (set_attr "mode" "QI")])
6854
6855 (define_insn "*addqi_2"
6856   [(set (reg FLAGS_REG)
6857         (compare
6858           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6859                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6860           (const_int 0)))
6861    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6862         (plus:QI (match_dup 1) (match_dup 2)))]
6863   "ix86_match_ccmode (insn, CCGOCmode)
6864    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6865 {
6866   switch (get_attr_type (insn))
6867     {
6868     case TYPE_INCDEC:
6869       if (operands[2] == const1_rtx)
6870         return "inc{b}\t%0";
6871       else
6872         {
6873           gcc_assert (operands[2] == constm1_rtx
6874                       || (CONST_INT_P (operands[2])
6875                           && INTVAL (operands[2]) == 255));
6876           return "dec{b}\t%0";
6877         }
6878
6879     default:
6880       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6881       if (CONST_INT_P (operands[2])
6882           && INTVAL (operands[2]) < 0)
6883         {
6884           operands[2] = GEN_INT (-INTVAL (operands[2]));
6885           return "sub{b}\t{%2, %0|%0, %2}";
6886         }
6887       return "add{b}\t{%2, %0|%0, %2}";
6888     }
6889 }
6890   [(set (attr "type")
6891      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6892         (const_string "incdec")
6893         (const_string "alu")))
6894    (set_attr "mode" "QI")])
6895
6896 (define_insn "*addqi_3"
6897   [(set (reg FLAGS_REG)
6898         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6899                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6900    (clobber (match_scratch:QI 0 "=q"))]
6901   "ix86_match_ccmode (insn, CCZmode)
6902    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6903 {
6904   switch (get_attr_type (insn))
6905     {
6906     case TYPE_INCDEC:
6907       if (operands[2] == const1_rtx)
6908         return "inc{b}\t%0";
6909       else
6910         {
6911           gcc_assert (operands[2] == constm1_rtx
6912                       || (CONST_INT_P (operands[2])
6913                           && INTVAL (operands[2]) == 255));
6914           return "dec{b}\t%0";
6915         }
6916
6917     default:
6918       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6919       if (CONST_INT_P (operands[2])
6920           && INTVAL (operands[2]) < 0)
6921         {
6922           operands[2] = GEN_INT (-INTVAL (operands[2]));
6923           return "sub{b}\t{%2, %0|%0, %2}";
6924         }
6925       return "add{b}\t{%2, %0|%0, %2}";
6926     }
6927 }
6928   [(set (attr "type")
6929      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6930         (const_string "incdec")
6931         (const_string "alu")))
6932    (set_attr "mode" "QI")])
6933
6934 ; See comments above addsi_4 for details.
6935 (define_insn "*addqi_4"
6936   [(set (reg FLAGS_REG)
6937         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6938                  (match_operand:QI 2 "const_int_operand" "n")))
6939    (clobber (match_scratch:QI 0 "=qm"))]
6940   "ix86_match_ccmode (insn, CCGCmode)
6941    && (INTVAL (operands[2]) & 0xff) != 0x80"
6942 {
6943   switch (get_attr_type (insn))
6944     {
6945     case TYPE_INCDEC:
6946       if (operands[2] == constm1_rtx
6947           || (CONST_INT_P (operands[2])
6948               && INTVAL (operands[2]) == 255))
6949         return "inc{b}\t%0";
6950       else
6951         {
6952           gcc_assert (operands[2] == const1_rtx);
6953           return "dec{b}\t%0";
6954         }
6955
6956     default:
6957       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6958       if (INTVAL (operands[2]) < 0)
6959         {
6960           operands[2] = GEN_INT (-INTVAL (operands[2]));
6961           return "add{b}\t{%2, %0|%0, %2}";
6962         }
6963       return "sub{b}\t{%2, %0|%0, %2}";
6964     }
6965 }
6966   [(set (attr "type")
6967      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6968         (const_string "incdec")
6969         (const_string "alu")))
6970    (set_attr "mode" "QI")])
6971
6972
6973 (define_insn "*addqi_5"
6974   [(set (reg FLAGS_REG)
6975         (compare
6976           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6977                    (match_operand:QI 2 "general_operand" "qmni"))
6978           (const_int 0)))
6979    (clobber (match_scratch:QI 0 "=q"))]
6980   "ix86_match_ccmode (insn, CCGOCmode)
6981    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6982 {
6983   switch (get_attr_type (insn))
6984     {
6985     case TYPE_INCDEC:
6986       if (operands[2] == const1_rtx)
6987         return "inc{b}\t%0";
6988       else
6989         {
6990           gcc_assert (operands[2] == constm1_rtx
6991                       || (CONST_INT_P (operands[2])
6992                           && INTVAL (operands[2]) == 255));
6993           return "dec{b}\t%0";
6994         }
6995
6996     default:
6997       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6998       if (CONST_INT_P (operands[2])
6999           && INTVAL (operands[2]) < 0)
7000         {
7001           operands[2] = GEN_INT (-INTVAL (operands[2]));
7002           return "sub{b}\t{%2, %0|%0, %2}";
7003         }
7004       return "add{b}\t{%2, %0|%0, %2}";
7005     }
7006 }
7007   [(set (attr "type")
7008      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7009         (const_string "incdec")
7010         (const_string "alu")))
7011    (set_attr "mode" "QI")])
7012
7013
7014 (define_insn "addqi_ext_1"
7015   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7016                          (const_int 8)
7017                          (const_int 8))
7018         (plus:SI
7019           (zero_extract:SI
7020             (match_operand 1 "ext_register_operand" "0")
7021             (const_int 8)
7022             (const_int 8))
7023           (match_operand:QI 2 "general_operand" "Qmn")))
7024    (clobber (reg:CC FLAGS_REG))]
7025   "!TARGET_64BIT"
7026 {
7027   switch (get_attr_type (insn))
7028     {
7029     case TYPE_INCDEC:
7030       if (operands[2] == const1_rtx)
7031         return "inc{b}\t%h0";
7032       else
7033         {
7034           gcc_assert (operands[2] == constm1_rtx
7035                       || (CONST_INT_P (operands[2])
7036                           && INTVAL (operands[2]) == 255));
7037           return "dec{b}\t%h0";
7038         }
7039
7040     default:
7041       return "add{b}\t{%2, %h0|%h0, %2}";
7042     }
7043 }
7044   [(set (attr "type")
7045      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7046         (const_string "incdec")
7047         (const_string "alu")))
7048    (set_attr "mode" "QI")])
7049
7050 (define_insn "*addqi_ext_1_rex64"
7051   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7052                          (const_int 8)
7053                          (const_int 8))
7054         (plus:SI
7055           (zero_extract:SI
7056             (match_operand 1 "ext_register_operand" "0")
7057             (const_int 8)
7058             (const_int 8))
7059           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7060    (clobber (reg:CC FLAGS_REG))]
7061   "TARGET_64BIT"
7062 {
7063   switch (get_attr_type (insn))
7064     {
7065     case TYPE_INCDEC:
7066       if (operands[2] == const1_rtx)
7067         return "inc{b}\t%h0";
7068       else
7069         {
7070           gcc_assert (operands[2] == constm1_rtx
7071                       || (CONST_INT_P (operands[2])
7072                           && INTVAL (operands[2]) == 255));
7073           return "dec{b}\t%h0";
7074         }
7075
7076     default:
7077       return "add{b}\t{%2, %h0|%h0, %2}";
7078     }
7079 }
7080   [(set (attr "type")
7081      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7082         (const_string "incdec")
7083         (const_string "alu")))
7084    (set_attr "mode" "QI")])
7085
7086 (define_insn "*addqi_ext_2"
7087   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7088                          (const_int 8)
7089                          (const_int 8))
7090         (plus:SI
7091           (zero_extract:SI
7092             (match_operand 1 "ext_register_operand" "%0")
7093             (const_int 8)
7094             (const_int 8))
7095           (zero_extract:SI
7096             (match_operand 2 "ext_register_operand" "Q")
7097             (const_int 8)
7098             (const_int 8))))
7099    (clobber (reg:CC FLAGS_REG))]
7100   ""
7101   "add{b}\t{%h2, %h0|%h0, %h2}"
7102   [(set_attr "type" "alu")
7103    (set_attr "mode" "QI")])
7104
7105 ;; The patterns that match these are at the end of this file.
7106
7107 (define_expand "addxf3"
7108   [(set (match_operand:XF 0 "register_operand" "")
7109         (plus:XF (match_operand:XF 1 "register_operand" "")
7110                  (match_operand:XF 2 "register_operand" "")))]
7111   "TARGET_80387"
7112   "")
7113
7114 (define_expand "add<mode>3"
7115   [(set (match_operand:MODEF 0 "register_operand" "")
7116         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7117                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7118   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7119   "")
7120 \f
7121 ;; Subtract instructions
7122
7123 ;; %%% splits for subditi3
7124
7125 (define_expand "subti3"
7126   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7127                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7128                              (match_operand:TI 2 "x86_64_general_operand" "")))
7129               (clobber (reg:CC FLAGS_REG))])]
7130   "TARGET_64BIT"
7131   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7132
7133 (define_insn "*subti3_1"
7134   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7135         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7136                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7137    (clobber (reg:CC FLAGS_REG))]
7138   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7139   "#")
7140
7141 (define_split
7142   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7143         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7144                   (match_operand:TI 2 "x86_64_general_operand" "")))
7145    (clobber (reg:CC FLAGS_REG))]
7146   "TARGET_64BIT && reload_completed"
7147   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7148               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7149    (parallel [(set (match_dup 3)
7150                    (minus:DI (match_dup 4)
7151                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7152                                       (match_dup 5))))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "split_ti (operands+0, 1, operands+0, operands+3);
7155    split_ti (operands+1, 1, operands+1, operands+4);
7156    split_ti (operands+2, 1, operands+2, operands+5);")
7157
7158 ;; %%% splits for subsidi3
7159
7160 (define_expand "subdi3"
7161   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7162                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7163                              (match_operand:DI 2 "x86_64_general_operand" "")))
7164               (clobber (reg:CC FLAGS_REG))])]
7165   ""
7166   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7167
7168 (define_insn "*subdi3_1"
7169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7170         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7171                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7174   "#")
7175
7176 (define_split
7177   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7178         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7179                   (match_operand:DI 2 "general_operand" "")))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "!TARGET_64BIT && reload_completed"
7182   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7183               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7184    (parallel [(set (match_dup 3)
7185                    (minus:SI (match_dup 4)
7186                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7187                                       (match_dup 5))))
7188               (clobber (reg:CC FLAGS_REG))])]
7189   "split_di (operands+0, 1, operands+0, operands+3);
7190    split_di (operands+1, 1, operands+1, operands+4);
7191    split_di (operands+2, 1, operands+2, operands+5);")
7192
7193 (define_insn "subdi3_carry_rex64"
7194   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7195           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7196             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7197                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7198    (clobber (reg:CC FLAGS_REG))]
7199   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7200   "sbb{q}\t{%2, %0|%0, %2}"
7201   [(set_attr "type" "alu")
7202    (set_attr "pent_pair" "pu")
7203    (set_attr "mode" "DI")])
7204
7205 (define_insn "*subdi_1_rex64"
7206   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7207         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7208                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7209    (clobber (reg:CC FLAGS_REG))]
7210   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7211   "sub{q}\t{%2, %0|%0, %2}"
7212   [(set_attr "type" "alu")
7213    (set_attr "mode" "DI")])
7214
7215 (define_insn "*subdi_2_rex64"
7216   [(set (reg FLAGS_REG)
7217         (compare
7218           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7219                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7220           (const_int 0)))
7221    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7222         (minus:DI (match_dup 1) (match_dup 2)))]
7223   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7224    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7225   "sub{q}\t{%2, %0|%0, %2}"
7226   [(set_attr "type" "alu")
7227    (set_attr "mode" "DI")])
7228
7229 (define_insn "*subdi_3_rex63"
7230   [(set (reg FLAGS_REG)
7231         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7232                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7233    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7234         (minus:DI (match_dup 1) (match_dup 2)))]
7235   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7236    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7237   "sub{q}\t{%2, %0|%0, %2}"
7238   [(set_attr "type" "alu")
7239    (set_attr "mode" "DI")])
7240
7241 (define_insn "subqi3_carry"
7242   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7243           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7244             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7245                (match_operand:QI 2 "general_operand" "qi,qm"))))
7246    (clobber (reg:CC FLAGS_REG))]
7247   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7248   "sbb{b}\t{%2, %0|%0, %2}"
7249   [(set_attr "type" "alu")
7250    (set_attr "pent_pair" "pu")
7251    (set_attr "mode" "QI")])
7252
7253 (define_insn "subhi3_carry"
7254   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7255           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7256             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7257                (match_operand:HI 2 "general_operand" "ri,rm"))))
7258    (clobber (reg:CC FLAGS_REG))]
7259   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7260   "sbb{w}\t{%2, %0|%0, %2}"
7261   [(set_attr "type" "alu")
7262    (set_attr "pent_pair" "pu")
7263    (set_attr "mode" "HI")])
7264
7265 (define_insn "subsi3_carry"
7266   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7267           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7268             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7269                (match_operand:SI 2 "general_operand" "ri,rm"))))
7270    (clobber (reg:CC FLAGS_REG))]
7271   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7272   "sbb{l}\t{%2, %0|%0, %2}"
7273   [(set_attr "type" "alu")
7274    (set_attr "pent_pair" "pu")
7275    (set_attr "mode" "SI")])
7276
7277 (define_insn "subsi3_carry_zext"
7278   [(set (match_operand:DI 0 "register_operand" "=r")
7279           (zero_extend:DI
7280             (minus:SI (match_operand:SI 1 "register_operand" "0")
7281               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7282                  (match_operand:SI 2 "general_operand" "g")))))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7285   "sbb{l}\t{%2, %k0|%k0, %2}"
7286   [(set_attr "type" "alu")
7287    (set_attr "pent_pair" "pu")
7288    (set_attr "mode" "SI")])
7289
7290 (define_expand "subsi3"
7291   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7292                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7293                              (match_operand:SI 2 "general_operand" "")))
7294               (clobber (reg:CC FLAGS_REG))])]
7295   ""
7296   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7297
7298 (define_insn "*subsi_1"
7299   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7300         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7301                   (match_operand:SI 2 "general_operand" "ri,rm")))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7304   "sub{l}\t{%2, %0|%0, %2}"
7305   [(set_attr "type" "alu")
7306    (set_attr "mode" "SI")])
7307
7308 (define_insn "*subsi_1_zext"
7309   [(set (match_operand:DI 0 "register_operand" "=r")
7310         (zero_extend:DI
7311           (minus:SI (match_operand:SI 1 "register_operand" "0")
7312                     (match_operand:SI 2 "general_operand" "g"))))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7315   "sub{l}\t{%2, %k0|%k0, %2}"
7316   [(set_attr "type" "alu")
7317    (set_attr "mode" "SI")])
7318
7319 (define_insn "*subsi_2"
7320   [(set (reg FLAGS_REG)
7321         (compare
7322           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7323                     (match_operand:SI 2 "general_operand" "ri,rm"))
7324           (const_int 0)))
7325    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7326         (minus:SI (match_dup 1) (match_dup 2)))]
7327   "ix86_match_ccmode (insn, CCGOCmode)
7328    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7329   "sub{l}\t{%2, %0|%0, %2}"
7330   [(set_attr "type" "alu")
7331    (set_attr "mode" "SI")])
7332
7333 (define_insn "*subsi_2_zext"
7334   [(set (reg FLAGS_REG)
7335         (compare
7336           (minus:SI (match_operand:SI 1 "register_operand" "0")
7337                     (match_operand:SI 2 "general_operand" "g"))
7338           (const_int 0)))
7339    (set (match_operand:DI 0 "register_operand" "=r")
7340         (zero_extend:DI
7341           (minus:SI (match_dup 1)
7342                     (match_dup 2))))]
7343   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7344    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7345   "sub{l}\t{%2, %k0|%k0, %2}"
7346   [(set_attr "type" "alu")
7347    (set_attr "mode" "SI")])
7348
7349 (define_insn "*subsi_3"
7350   [(set (reg FLAGS_REG)
7351         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7352                  (match_operand:SI 2 "general_operand" "ri,rm")))
7353    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7354         (minus:SI (match_dup 1) (match_dup 2)))]
7355   "ix86_match_ccmode (insn, CCmode)
7356    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7357   "sub{l}\t{%2, %0|%0, %2}"
7358   [(set_attr "type" "alu")
7359    (set_attr "mode" "SI")])
7360
7361 (define_insn "*subsi_3_zext"
7362   [(set (reg FLAGS_REG)
7363         (compare (match_operand:SI 1 "register_operand" "0")
7364                  (match_operand:SI 2 "general_operand" "g")))
7365    (set (match_operand:DI 0 "register_operand" "=r")
7366         (zero_extend:DI
7367           (minus:SI (match_dup 1)
7368                     (match_dup 2))))]
7369   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7370    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7371   "sub{l}\t{%2, %1|%1, %2}"
7372   [(set_attr "type" "alu")
7373    (set_attr "mode" "DI")])
7374
7375 (define_expand "subhi3"
7376   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7377                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7378                              (match_operand:HI 2 "general_operand" "")))
7379               (clobber (reg:CC FLAGS_REG))])]
7380   "TARGET_HIMODE_MATH"
7381   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7382
7383 (define_insn "*subhi_1"
7384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7385         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7386                   (match_operand:HI 2 "general_operand" "ri,rm")))
7387    (clobber (reg:CC FLAGS_REG))]
7388   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7389   "sub{w}\t{%2, %0|%0, %2}"
7390   [(set_attr "type" "alu")
7391    (set_attr "mode" "HI")])
7392
7393 (define_insn "*subhi_2"
7394   [(set (reg FLAGS_REG)
7395         (compare
7396           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7397                     (match_operand:HI 2 "general_operand" "ri,rm"))
7398           (const_int 0)))
7399    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7400         (minus:HI (match_dup 1) (match_dup 2)))]
7401   "ix86_match_ccmode (insn, CCGOCmode)
7402    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7403   "sub{w}\t{%2, %0|%0, %2}"
7404   [(set_attr "type" "alu")
7405    (set_attr "mode" "HI")])
7406
7407 (define_insn "*subhi_3"
7408   [(set (reg FLAGS_REG)
7409         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7410                  (match_operand:HI 2 "general_operand" "ri,rm")))
7411    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7412         (minus:HI (match_dup 1) (match_dup 2)))]
7413   "ix86_match_ccmode (insn, CCmode)
7414    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7415   "sub{w}\t{%2, %0|%0, %2}"
7416   [(set_attr "type" "alu")
7417    (set_attr "mode" "HI")])
7418
7419 (define_expand "subqi3"
7420   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7421                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7422                              (match_operand:QI 2 "general_operand" "")))
7423               (clobber (reg:CC FLAGS_REG))])]
7424   "TARGET_QIMODE_MATH"
7425   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7426
7427 (define_insn "*subqi_1"
7428   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7429         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7430                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7433   "sub{b}\t{%2, %0|%0, %2}"
7434   [(set_attr "type" "alu")
7435    (set_attr "mode" "QI")])
7436
7437 (define_insn "*subqi_1_slp"
7438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7439         (minus:QI (match_dup 0)
7440                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7443    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7444   "sub{b}\t{%1, %0|%0, %1}"
7445   [(set_attr "type" "alu1")
7446    (set_attr "mode" "QI")])
7447
7448 (define_insn "*subqi_2"
7449   [(set (reg FLAGS_REG)
7450         (compare
7451           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7452                     (match_operand:QI 2 "general_operand" "qi,qm"))
7453           (const_int 0)))
7454    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7455         (minus:HI (match_dup 1) (match_dup 2)))]
7456   "ix86_match_ccmode (insn, CCGOCmode)
7457    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7458   "sub{b}\t{%2, %0|%0, %2}"
7459   [(set_attr "type" "alu")
7460    (set_attr "mode" "QI")])
7461
7462 (define_insn "*subqi_3"
7463   [(set (reg FLAGS_REG)
7464         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7465                  (match_operand:QI 2 "general_operand" "qi,qm")))
7466    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7467         (minus:HI (match_dup 1) (match_dup 2)))]
7468   "ix86_match_ccmode (insn, CCmode)
7469    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7470   "sub{b}\t{%2, %0|%0, %2}"
7471   [(set_attr "type" "alu")
7472    (set_attr "mode" "QI")])
7473
7474 ;; The patterns that match these are at the end of this file.
7475
7476 (define_expand "subxf3"
7477   [(set (match_operand:XF 0 "register_operand" "")
7478         (minus:XF (match_operand:XF 1 "register_operand" "")
7479                   (match_operand:XF 2 "register_operand" "")))]
7480   "TARGET_80387"
7481   "")
7482
7483 (define_expand "sub<mode>3"
7484   [(set (match_operand:MODEF 0 "register_operand" "")
7485         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7486                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7487   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7488   "")
7489 \f
7490 ;; Multiply instructions
7491
7492 (define_expand "muldi3"
7493   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7494                    (mult:DI (match_operand:DI 1 "register_operand" "")
7495                             (match_operand:DI 2 "x86_64_general_operand" "")))
7496               (clobber (reg:CC FLAGS_REG))])]
7497   "TARGET_64BIT"
7498   "")
7499
7500 ;; On AMDFAM10
7501 ;; IMUL reg64, reg64, imm8      Direct
7502 ;; IMUL reg64, mem64, imm8      VectorPath
7503 ;; IMUL reg64, reg64, imm32     Direct
7504 ;; IMUL reg64, mem64, imm32     VectorPath
7505 ;; IMUL reg64, reg64            Direct
7506 ;; IMUL reg64, mem64            Direct
7507
7508 (define_insn "*muldi3_1_rex64"
7509   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7510         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7511                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7512    (clobber (reg:CC FLAGS_REG))]
7513   "TARGET_64BIT
7514    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7515   "@
7516    imul{q}\t{%2, %1, %0|%0, %1, %2}
7517    imul{q}\t{%2, %1, %0|%0, %1, %2}
7518    imul{q}\t{%2, %0|%0, %2}"
7519   [(set_attr "type" "imul")
7520    (set_attr "prefix_0f" "0,0,1")
7521    (set (attr "athlon_decode")
7522         (cond [(eq_attr "cpu" "athlon")
7523                   (const_string "vector")
7524                (eq_attr "alternative" "1")
7525                   (const_string "vector")
7526                (and (eq_attr "alternative" "2")
7527                     (match_operand 1 "memory_operand" ""))
7528                   (const_string "vector")]
7529               (const_string "direct")))
7530    (set (attr "amdfam10_decode")
7531         (cond [(and (eq_attr "alternative" "0,1")
7532                     (match_operand 1 "memory_operand" ""))
7533                   (const_string "vector")]
7534               (const_string "direct")))
7535    (set_attr "mode" "DI")])
7536
7537 (define_expand "mulsi3"
7538   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7539                    (mult:SI (match_operand:SI 1 "register_operand" "")
7540                             (match_operand:SI 2 "general_operand" "")))
7541               (clobber (reg:CC FLAGS_REG))])]
7542   ""
7543   "")
7544
7545 ;; On AMDFAM10
7546 ;; IMUL reg32, reg32, imm8      Direct
7547 ;; IMUL reg32, mem32, imm8      VectorPath
7548 ;; IMUL reg32, reg32, imm32     Direct
7549 ;; IMUL reg32, mem32, imm32     VectorPath
7550 ;; IMUL reg32, reg32            Direct
7551 ;; IMUL reg32, mem32            Direct
7552
7553 (define_insn "*mulsi3_1"
7554   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7555         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7556                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7557    (clobber (reg:CC FLAGS_REG))]
7558   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7559   "@
7560    imul{l}\t{%2, %1, %0|%0, %1, %2}
7561    imul{l}\t{%2, %1, %0|%0, %1, %2}
7562    imul{l}\t{%2, %0|%0, %2}"
7563   [(set_attr "type" "imul")
7564    (set_attr "prefix_0f" "0,0,1")
7565    (set (attr "athlon_decode")
7566         (cond [(eq_attr "cpu" "athlon")
7567                   (const_string "vector")
7568                (eq_attr "alternative" "1")
7569                   (const_string "vector")
7570                (and (eq_attr "alternative" "2")
7571                     (match_operand 1 "memory_operand" ""))
7572                   (const_string "vector")]
7573               (const_string "direct")))
7574    (set (attr "amdfam10_decode")
7575         (cond [(and (eq_attr "alternative" "0,1")
7576                     (match_operand 1 "memory_operand" ""))
7577                   (const_string "vector")]
7578               (const_string "direct")))
7579    (set_attr "mode" "SI")])
7580
7581 (define_insn "*mulsi3_1_zext"
7582   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7583         (zero_extend:DI
7584           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7585                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7586    (clobber (reg:CC FLAGS_REG))]
7587   "TARGET_64BIT
7588    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7589   "@
7590    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7591    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7592    imul{l}\t{%2, %k0|%k0, %2}"
7593   [(set_attr "type" "imul")
7594    (set_attr "prefix_0f" "0,0,1")
7595    (set (attr "athlon_decode")
7596         (cond [(eq_attr "cpu" "athlon")
7597                   (const_string "vector")
7598                (eq_attr "alternative" "1")
7599                   (const_string "vector")
7600                (and (eq_attr "alternative" "2")
7601                     (match_operand 1 "memory_operand" ""))
7602                   (const_string "vector")]
7603               (const_string "direct")))
7604    (set (attr "amdfam10_decode")
7605         (cond [(and (eq_attr "alternative" "0,1")
7606                     (match_operand 1 "memory_operand" ""))
7607                   (const_string "vector")]
7608               (const_string "direct")))
7609    (set_attr "mode" "SI")])
7610
7611 (define_expand "mulhi3"
7612   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7613                    (mult:HI (match_operand:HI 1 "register_operand" "")
7614                             (match_operand:HI 2 "general_operand" "")))
7615               (clobber (reg:CC FLAGS_REG))])]
7616   "TARGET_HIMODE_MATH"
7617   "")
7618
7619 ;; On AMDFAM10
7620 ;; IMUL reg16, reg16, imm8      VectorPath
7621 ;; IMUL reg16, mem16, imm8      VectorPath
7622 ;; IMUL reg16, reg16, imm16     VectorPath
7623 ;; IMUL reg16, mem16, imm16     VectorPath
7624 ;; IMUL reg16, reg16            Direct
7625 ;; IMUL reg16, mem16            Direct
7626 (define_insn "*mulhi3_1"
7627   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7628         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7629                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632   "@
7633    imul{w}\t{%2, %1, %0|%0, %1, %2}
7634    imul{w}\t{%2, %1, %0|%0, %1, %2}
7635    imul{w}\t{%2, %0|%0, %2}"
7636   [(set_attr "type" "imul")
7637    (set_attr "prefix_0f" "0,0,1")
7638    (set (attr "athlon_decode")
7639         (cond [(eq_attr "cpu" "athlon")
7640                   (const_string "vector")
7641                (eq_attr "alternative" "1,2")
7642                   (const_string "vector")]
7643               (const_string "direct")))
7644    (set (attr "amdfam10_decode")
7645         (cond [(eq_attr "alternative" "0,1")
7646                   (const_string "vector")]
7647               (const_string "direct")))
7648    (set_attr "mode" "HI")])
7649
7650 (define_expand "mulqi3"
7651   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7652                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7653                             (match_operand:QI 2 "register_operand" "")))
7654               (clobber (reg:CC FLAGS_REG))])]
7655   "TARGET_QIMODE_MATH"
7656   "")
7657
7658 ;;On AMDFAM10
7659 ;; MUL reg8     Direct
7660 ;; MUL mem8     Direct
7661
7662 (define_insn "*mulqi3_1"
7663   [(set (match_operand:QI 0 "register_operand" "=a")
7664         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7665                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "TARGET_QIMODE_MATH
7668    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7669   "mul{b}\t%2"
7670   [(set_attr "type" "imul")
7671    (set_attr "length_immediate" "0")
7672    (set (attr "athlon_decode")
7673      (if_then_else (eq_attr "cpu" "athlon")
7674         (const_string "vector")
7675         (const_string "direct")))
7676    (set_attr "amdfam10_decode" "direct")
7677    (set_attr "mode" "QI")])
7678
7679 (define_expand "umulqihi3"
7680   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7681                    (mult:HI (zero_extend:HI
7682                               (match_operand:QI 1 "nonimmediate_operand" ""))
7683                             (zero_extend:HI
7684                               (match_operand:QI 2 "register_operand" ""))))
7685               (clobber (reg:CC FLAGS_REG))])]
7686   "TARGET_QIMODE_MATH"
7687   "")
7688
7689 (define_insn "*umulqihi3_1"
7690   [(set (match_operand:HI 0 "register_operand" "=a")
7691         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7692                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7693    (clobber (reg:CC FLAGS_REG))]
7694   "TARGET_QIMODE_MATH
7695    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696   "mul{b}\t%2"
7697   [(set_attr "type" "imul")
7698    (set_attr "length_immediate" "0")
7699    (set (attr "athlon_decode")
7700      (if_then_else (eq_attr "cpu" "athlon")
7701         (const_string "vector")
7702         (const_string "direct")))
7703    (set_attr "amdfam10_decode" "direct")
7704    (set_attr "mode" "QI")])
7705
7706 (define_expand "mulqihi3"
7707   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7708                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7709                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7710               (clobber (reg:CC FLAGS_REG))])]
7711   "TARGET_QIMODE_MATH"
7712   "")
7713
7714 (define_insn "*mulqihi3_insn"
7715   [(set (match_operand:HI 0 "register_operand" "=a")
7716         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7717                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7718    (clobber (reg:CC FLAGS_REG))]
7719   "TARGET_QIMODE_MATH
7720    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7721   "imul{b}\t%2"
7722   [(set_attr "type" "imul")
7723    (set_attr "length_immediate" "0")
7724    (set (attr "athlon_decode")
7725      (if_then_else (eq_attr "cpu" "athlon")
7726         (const_string "vector")
7727         (const_string "direct")))
7728    (set_attr "amdfam10_decode" "direct")
7729    (set_attr "mode" "QI")])
7730
7731 (define_expand "umulditi3"
7732   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7733                    (mult:TI (zero_extend:TI
7734                               (match_operand:DI 1 "nonimmediate_operand" ""))
7735                             (zero_extend:TI
7736                               (match_operand:DI 2 "register_operand" ""))))
7737               (clobber (reg:CC FLAGS_REG))])]
7738   "TARGET_64BIT"
7739   "")
7740
7741 (define_insn "*umulditi3_insn"
7742   [(set (match_operand:TI 0 "register_operand" "=A")
7743         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7744                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7745    (clobber (reg:CC FLAGS_REG))]
7746   "TARGET_64BIT
7747    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7748   "mul{q}\t%2"
7749   [(set_attr "type" "imul")
7750    (set_attr "length_immediate" "0")
7751    (set (attr "athlon_decode")
7752      (if_then_else (eq_attr "cpu" "athlon")
7753         (const_string "vector")
7754         (const_string "double")))
7755    (set_attr "amdfam10_decode" "double")
7756    (set_attr "mode" "DI")])
7757
7758 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7759 (define_expand "umulsidi3"
7760   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7761                    (mult:DI (zero_extend:DI
7762                               (match_operand:SI 1 "nonimmediate_operand" ""))
7763                             (zero_extend:DI
7764                               (match_operand:SI 2 "register_operand" ""))))
7765               (clobber (reg:CC FLAGS_REG))])]
7766   "!TARGET_64BIT"
7767   "")
7768
7769 (define_insn "*umulsidi3_insn"
7770   [(set (match_operand:DI 0 "register_operand" "=A")
7771         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7772                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "!TARGET_64BIT
7775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776   "mul{l}\t%2"
7777   [(set_attr "type" "imul")
7778    (set_attr "length_immediate" "0")
7779    (set (attr "athlon_decode")
7780      (if_then_else (eq_attr "cpu" "athlon")
7781         (const_string "vector")
7782         (const_string "double")))
7783    (set_attr "amdfam10_decode" "double")
7784    (set_attr "mode" "SI")])
7785
7786 (define_expand "mulditi3"
7787   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7788                    (mult:TI (sign_extend:TI
7789                               (match_operand:DI 1 "nonimmediate_operand" ""))
7790                             (sign_extend:TI
7791                               (match_operand:DI 2 "register_operand" ""))))
7792               (clobber (reg:CC FLAGS_REG))])]
7793   "TARGET_64BIT"
7794   "")
7795
7796 (define_insn "*mulditi3_insn"
7797   [(set (match_operand:TI 0 "register_operand" "=A")
7798         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7799                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7800    (clobber (reg:CC FLAGS_REG))]
7801   "TARGET_64BIT
7802    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7803   "imul{q}\t%2"
7804   [(set_attr "type" "imul")
7805    (set_attr "length_immediate" "0")
7806    (set (attr "athlon_decode")
7807      (if_then_else (eq_attr "cpu" "athlon")
7808         (const_string "vector")
7809         (const_string "double")))
7810    (set_attr "amdfam10_decode" "double")
7811    (set_attr "mode" "DI")])
7812
7813 (define_expand "mulsidi3"
7814   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7815                    (mult:DI (sign_extend:DI
7816                               (match_operand:SI 1 "nonimmediate_operand" ""))
7817                             (sign_extend:DI
7818                               (match_operand:SI 2 "register_operand" ""))))
7819               (clobber (reg:CC FLAGS_REG))])]
7820   "!TARGET_64BIT"
7821   "")
7822
7823 (define_insn "*mulsidi3_insn"
7824   [(set (match_operand:DI 0 "register_operand" "=A")
7825         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7826                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7827    (clobber (reg:CC FLAGS_REG))]
7828   "!TARGET_64BIT
7829    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7830   "imul{l}\t%2"
7831   [(set_attr "type" "imul")
7832    (set_attr "length_immediate" "0")
7833    (set (attr "athlon_decode")
7834      (if_then_else (eq_attr "cpu" "athlon")
7835         (const_string "vector")
7836         (const_string "double")))
7837    (set_attr "amdfam10_decode" "double")
7838    (set_attr "mode" "SI")])
7839
7840 (define_expand "umuldi3_highpart"
7841   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7842                    (truncate:DI
7843                      (lshiftrt:TI
7844                        (mult:TI (zero_extend:TI
7845                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7846                                 (zero_extend:TI
7847                                   (match_operand:DI 2 "register_operand" "")))
7848                        (const_int 64))))
7849               (clobber (match_scratch:DI 3 ""))
7850               (clobber (reg:CC FLAGS_REG))])]
7851   "TARGET_64BIT"
7852   "")
7853
7854 (define_insn "*umuldi3_highpart_rex64"
7855   [(set (match_operand:DI 0 "register_operand" "=d")
7856         (truncate:DI
7857           (lshiftrt:TI
7858             (mult:TI (zero_extend:TI
7859                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7860                      (zero_extend:TI
7861                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7862             (const_int 64))))
7863    (clobber (match_scratch:DI 3 "=1"))
7864    (clobber (reg:CC FLAGS_REG))]
7865   "TARGET_64BIT
7866    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7867   "mul{q}\t%2"
7868   [(set_attr "type" "imul")
7869    (set_attr "length_immediate" "0")
7870    (set (attr "athlon_decode")
7871      (if_then_else (eq_attr "cpu" "athlon")
7872         (const_string "vector")
7873         (const_string "double")))
7874    (set_attr "amdfam10_decode" "double")
7875    (set_attr "mode" "DI")])
7876
7877 (define_expand "umulsi3_highpart"
7878   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7879                    (truncate:SI
7880                      (lshiftrt:DI
7881                        (mult:DI (zero_extend:DI
7882                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7883                                 (zero_extend:DI
7884                                   (match_operand:SI 2 "register_operand" "")))
7885                        (const_int 32))))
7886               (clobber (match_scratch:SI 3 ""))
7887               (clobber (reg:CC FLAGS_REG))])]
7888   ""
7889   "")
7890
7891 (define_insn "*umulsi3_highpart_insn"
7892   [(set (match_operand:SI 0 "register_operand" "=d")
7893         (truncate:SI
7894           (lshiftrt:DI
7895             (mult:DI (zero_extend:DI
7896                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7897                      (zero_extend:DI
7898                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7899             (const_int 32))))
7900    (clobber (match_scratch:SI 3 "=1"))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7903   "mul{l}\t%2"
7904   [(set_attr "type" "imul")
7905    (set_attr "length_immediate" "0")
7906    (set (attr "athlon_decode")
7907      (if_then_else (eq_attr "cpu" "athlon")
7908         (const_string "vector")
7909         (const_string "double")))
7910    (set_attr "amdfam10_decode" "double")
7911    (set_attr "mode" "SI")])
7912
7913 (define_insn "*umulsi3_highpart_zext"
7914   [(set (match_operand:DI 0 "register_operand" "=d")
7915         (zero_extend:DI (truncate:SI
7916           (lshiftrt:DI
7917             (mult:DI (zero_extend:DI
7918                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7919                      (zero_extend:DI
7920                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7921             (const_int 32)))))
7922    (clobber (match_scratch:SI 3 "=1"))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "TARGET_64BIT
7925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926   "mul{l}\t%2"
7927   [(set_attr "type" "imul")
7928    (set_attr "length_immediate" "0")
7929    (set (attr "athlon_decode")
7930      (if_then_else (eq_attr "cpu" "athlon")
7931         (const_string "vector")
7932         (const_string "double")))
7933    (set_attr "amdfam10_decode" "double")
7934    (set_attr "mode" "SI")])
7935
7936 (define_expand "smuldi3_highpart"
7937   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7938                    (truncate:DI
7939                      (lshiftrt:TI
7940                        (mult:TI (sign_extend:TI
7941                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7942                                 (sign_extend:TI
7943                                   (match_operand:DI 2 "register_operand" "")))
7944                        (const_int 64))))
7945               (clobber (match_scratch:DI 3 ""))
7946               (clobber (reg:CC FLAGS_REG))])]
7947   "TARGET_64BIT"
7948   "")
7949
7950 (define_insn "*smuldi3_highpart_rex64"
7951   [(set (match_operand:DI 0 "register_operand" "=d")
7952         (truncate:DI
7953           (lshiftrt:TI
7954             (mult:TI (sign_extend:TI
7955                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7956                      (sign_extend:TI
7957                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7958             (const_int 64))))
7959    (clobber (match_scratch:DI 3 "=1"))
7960    (clobber (reg:CC FLAGS_REG))]
7961   "TARGET_64BIT
7962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7963   "imul{q}\t%2"
7964   [(set_attr "type" "imul")
7965    (set (attr "athlon_decode")
7966      (if_then_else (eq_attr "cpu" "athlon")
7967         (const_string "vector")
7968         (const_string "double")))
7969    (set_attr "amdfam10_decode" "double")
7970    (set_attr "mode" "DI")])
7971
7972 (define_expand "smulsi3_highpart"
7973   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7974                    (truncate:SI
7975                      (lshiftrt:DI
7976                        (mult:DI (sign_extend:DI
7977                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7978                                 (sign_extend:DI
7979                                   (match_operand:SI 2 "register_operand" "")))
7980                        (const_int 32))))
7981               (clobber (match_scratch:SI 3 ""))
7982               (clobber (reg:CC FLAGS_REG))])]
7983   ""
7984   "")
7985
7986 (define_insn "*smulsi3_highpart_insn"
7987   [(set (match_operand:SI 0 "register_operand" "=d")
7988         (truncate:SI
7989           (lshiftrt:DI
7990             (mult:DI (sign_extend:DI
7991                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7992                      (sign_extend:DI
7993                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994             (const_int 32))))
7995    (clobber (match_scratch:SI 3 "=1"))
7996    (clobber (reg:CC FLAGS_REG))]
7997   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7998   "imul{l}\t%2"
7999   [(set_attr "type" "imul")
8000    (set (attr "athlon_decode")
8001      (if_then_else (eq_attr "cpu" "athlon")
8002         (const_string "vector")
8003         (const_string "double")))
8004    (set_attr "amdfam10_decode" "double")
8005    (set_attr "mode" "SI")])
8006
8007 (define_insn "*smulsi3_highpart_zext"
8008   [(set (match_operand:DI 0 "register_operand" "=d")
8009         (zero_extend:DI (truncate:SI
8010           (lshiftrt:DI
8011             (mult:DI (sign_extend:DI
8012                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8013                      (sign_extend:DI
8014                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015             (const_int 32)))))
8016    (clobber (match_scratch:SI 3 "=1"))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "TARGET_64BIT
8019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020   "imul{l}\t%2"
8021   [(set_attr "type" "imul")
8022    (set (attr "athlon_decode")
8023      (if_then_else (eq_attr "cpu" "athlon")
8024         (const_string "vector")
8025         (const_string "double")))
8026    (set_attr "amdfam10_decode" "double")
8027    (set_attr "mode" "SI")])
8028
8029 ;; The patterns that match these are at the end of this file.
8030
8031 (define_expand "mulxf3"
8032   [(set (match_operand:XF 0 "register_operand" "")
8033         (mult:XF (match_operand:XF 1 "register_operand" "")
8034                  (match_operand:XF 2 "register_operand" "")))]
8035   "TARGET_80387"
8036   "")
8037
8038 (define_expand "mul<mode>3"
8039   [(set (match_operand:MODEF 0 "register_operand" "")
8040         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8041                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8042   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8043   "")
8044
8045 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8046
8047 \f
8048 ;; Divide instructions
8049
8050 (define_insn "divqi3"
8051   [(set (match_operand:QI 0 "register_operand" "=a")
8052         (div:QI (match_operand:HI 1 "register_operand" "0")
8053                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_QIMODE_MATH"
8056   "idiv{b}\t%2"
8057   [(set_attr "type" "idiv")
8058    (set_attr "mode" "QI")])
8059
8060 (define_insn "udivqi3"
8061   [(set (match_operand:QI 0 "register_operand" "=a")
8062         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8063                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8064    (clobber (reg:CC FLAGS_REG))]
8065   "TARGET_QIMODE_MATH"
8066   "div{b}\t%2"
8067   [(set_attr "type" "idiv")
8068    (set_attr "mode" "QI")])
8069
8070 ;; The patterns that match these are at the end of this file.
8071
8072 (define_expand "divxf3"
8073   [(set (match_operand:XF 0 "register_operand" "")
8074         (div:XF (match_operand:XF 1 "register_operand" "")
8075                 (match_operand:XF 2 "register_operand" "")))]
8076   "TARGET_80387"
8077   "")
8078
8079 (define_expand "divdf3"
8080   [(set (match_operand:DF 0 "register_operand" "")
8081         (div:DF (match_operand:DF 1 "register_operand" "")
8082                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8083    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8084    "")
8085
8086 (define_expand "divsf3"
8087   [(set (match_operand:SF 0 "register_operand" "")
8088         (div:SF (match_operand:SF 1 "register_operand" "")
8089                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8090   "TARGET_80387 || TARGET_SSE_MATH"
8091 {
8092   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8093       && flag_finite_math_only && !flag_trapping_math
8094       && flag_unsafe_math_optimizations)
8095     {
8096       ix86_emit_swdivsf (operands[0], operands[1],
8097                          operands[2], SFmode);
8098       DONE;
8099     }
8100 })
8101 \f
8102 ;; Remainder instructions.
8103
8104 (define_expand "divmoddi4"
8105   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8106                    (div:DI (match_operand:DI 1 "register_operand" "")
8107                            (match_operand:DI 2 "nonimmediate_operand" "")))
8108               (set (match_operand:DI 3 "register_operand" "")
8109                    (mod:DI (match_dup 1) (match_dup 2)))
8110               (clobber (reg:CC FLAGS_REG))])]
8111   "TARGET_64BIT"
8112   "")
8113
8114 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8115 ;; Penalize eax case slightly because it results in worse scheduling
8116 ;; of code.
8117 (define_insn "*divmoddi4_nocltd_rex64"
8118   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8119         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8120                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8121    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8122         (mod:DI (match_dup 2) (match_dup 3)))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8125   "#"
8126   [(set_attr "type" "multi")])
8127
8128 (define_insn "*divmoddi4_cltd_rex64"
8129   [(set (match_operand:DI 0 "register_operand" "=a")
8130         (div:DI (match_operand:DI 2 "register_operand" "a")
8131                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8132    (set (match_operand:DI 1 "register_operand" "=&d")
8133         (mod:DI (match_dup 2) (match_dup 3)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8136   "#"
8137   [(set_attr "type" "multi")])
8138
8139 (define_insn "*divmoddi_noext_rex64"
8140   [(set (match_operand:DI 0 "register_operand" "=a")
8141         (div:DI (match_operand:DI 1 "register_operand" "0")
8142                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8143    (set (match_operand:DI 3 "register_operand" "=d")
8144         (mod:DI (match_dup 1) (match_dup 2)))
8145    (use (match_operand:DI 4 "register_operand" "3"))
8146    (clobber (reg:CC FLAGS_REG))]
8147   "TARGET_64BIT"
8148   "idiv{q}\t%2"
8149   [(set_attr "type" "idiv")
8150    (set_attr "mode" "DI")])
8151
8152 (define_split
8153   [(set (match_operand:DI 0 "register_operand" "")
8154         (div:DI (match_operand:DI 1 "register_operand" "")
8155                 (match_operand:DI 2 "nonimmediate_operand" "")))
8156    (set (match_operand:DI 3 "register_operand" "")
8157         (mod:DI (match_dup 1) (match_dup 2)))
8158    (clobber (reg:CC FLAGS_REG))]
8159   "TARGET_64BIT && reload_completed"
8160   [(parallel [(set (match_dup 3)
8161                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8162               (clobber (reg:CC FLAGS_REG))])
8163    (parallel [(set (match_dup 0)
8164                    (div:DI (reg:DI 0) (match_dup 2)))
8165               (set (match_dup 3)
8166                    (mod:DI (reg:DI 0) (match_dup 2)))
8167               (use (match_dup 3))
8168               (clobber (reg:CC FLAGS_REG))])]
8169 {
8170   /* Avoid use of cltd in favor of a mov+shift.  */
8171   if (!TARGET_USE_CLTD && !optimize_size)
8172     {
8173       if (true_regnum (operands[1]))
8174         emit_move_insn (operands[0], operands[1]);
8175       else
8176         emit_move_insn (operands[3], operands[1]);
8177       operands[4] = operands[3];
8178     }
8179   else
8180     {
8181       gcc_assert (!true_regnum (operands[1]));
8182       operands[4] = operands[1];
8183     }
8184 })
8185
8186
8187 (define_expand "divmodsi4"
8188   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8189                    (div:SI (match_operand:SI 1 "register_operand" "")
8190                            (match_operand:SI 2 "nonimmediate_operand" "")))
8191               (set (match_operand:SI 3 "register_operand" "")
8192                    (mod:SI (match_dup 1) (match_dup 2)))
8193               (clobber (reg:CC FLAGS_REG))])]
8194   ""
8195   "")
8196
8197 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8198 ;; Penalize eax case slightly because it results in worse scheduling
8199 ;; of code.
8200 (define_insn "*divmodsi4_nocltd"
8201   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8202         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8203                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8204    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8205         (mod:SI (match_dup 2) (match_dup 3)))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "!optimize_size && !TARGET_USE_CLTD"
8208   "#"
8209   [(set_attr "type" "multi")])
8210
8211 (define_insn "*divmodsi4_cltd"
8212   [(set (match_operand:SI 0 "register_operand" "=a")
8213         (div:SI (match_operand:SI 2 "register_operand" "a")
8214                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8215    (set (match_operand:SI 1 "register_operand" "=&d")
8216         (mod:SI (match_dup 2) (match_dup 3)))
8217    (clobber (reg:CC FLAGS_REG))]
8218   "optimize_size || TARGET_USE_CLTD"
8219   "#"
8220   [(set_attr "type" "multi")])
8221
8222 (define_insn "*divmodsi_noext"
8223   [(set (match_operand:SI 0 "register_operand" "=a")
8224         (div:SI (match_operand:SI 1 "register_operand" "0")
8225                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8226    (set (match_operand:SI 3 "register_operand" "=d")
8227         (mod:SI (match_dup 1) (match_dup 2)))
8228    (use (match_operand:SI 4 "register_operand" "3"))
8229    (clobber (reg:CC FLAGS_REG))]
8230   ""
8231   "idiv{l}\t%2"
8232   [(set_attr "type" "idiv")
8233    (set_attr "mode" "SI")])
8234
8235 (define_split
8236   [(set (match_operand:SI 0 "register_operand" "")
8237         (div:SI (match_operand:SI 1 "register_operand" "")
8238                 (match_operand:SI 2 "nonimmediate_operand" "")))
8239    (set (match_operand:SI 3 "register_operand" "")
8240         (mod:SI (match_dup 1) (match_dup 2)))
8241    (clobber (reg:CC FLAGS_REG))]
8242   "reload_completed"
8243   [(parallel [(set (match_dup 3)
8244                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8245               (clobber (reg:CC FLAGS_REG))])
8246    (parallel [(set (match_dup 0)
8247                    (div:SI (reg:SI 0) (match_dup 2)))
8248               (set (match_dup 3)
8249                    (mod:SI (reg:SI 0) (match_dup 2)))
8250               (use (match_dup 3))
8251               (clobber (reg:CC FLAGS_REG))])]
8252 {
8253   /* Avoid use of cltd in favor of a mov+shift.  */
8254   if (!TARGET_USE_CLTD && !optimize_size)
8255     {
8256       if (true_regnum (operands[1]))
8257         emit_move_insn (operands[0], operands[1]);
8258       else
8259         emit_move_insn (operands[3], operands[1]);
8260       operands[4] = operands[3];
8261     }
8262   else
8263     {
8264       gcc_assert (!true_regnum (operands[1]));
8265       operands[4] = operands[1];
8266     }
8267 })
8268 ;; %%% Split me.
8269 (define_insn "divmodhi4"
8270   [(set (match_operand:HI 0 "register_operand" "=a")
8271         (div:HI (match_operand:HI 1 "register_operand" "0")
8272                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8273    (set (match_operand:HI 3 "register_operand" "=&d")
8274         (mod:HI (match_dup 1) (match_dup 2)))
8275    (clobber (reg:CC FLAGS_REG))]
8276   "TARGET_HIMODE_MATH"
8277   "cwtd\;idiv{w}\t%2"
8278   [(set_attr "type" "multi")
8279    (set_attr "length_immediate" "0")
8280    (set_attr "mode" "SI")])
8281
8282 (define_insn "udivmoddi4"
8283   [(set (match_operand:DI 0 "register_operand" "=a")
8284         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8285                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8286    (set (match_operand:DI 3 "register_operand" "=&d")
8287         (umod:DI (match_dup 1) (match_dup 2)))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "TARGET_64BIT"
8290   "xor{q}\t%3, %3\;div{q}\t%2"
8291   [(set_attr "type" "multi")
8292    (set_attr "length_immediate" "0")
8293    (set_attr "mode" "DI")])
8294
8295 (define_insn "*udivmoddi4_noext"
8296   [(set (match_operand:DI 0 "register_operand" "=a")
8297         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8298                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8299    (set (match_operand:DI 3 "register_operand" "=d")
8300         (umod:DI (match_dup 1) (match_dup 2)))
8301    (use (match_dup 3))
8302    (clobber (reg:CC FLAGS_REG))]
8303   "TARGET_64BIT"
8304   "div{q}\t%2"
8305   [(set_attr "type" "idiv")
8306    (set_attr "mode" "DI")])
8307
8308 (define_split
8309   [(set (match_operand:DI 0 "register_operand" "")
8310         (udiv:DI (match_operand:DI 1 "register_operand" "")
8311                  (match_operand:DI 2 "nonimmediate_operand" "")))
8312    (set (match_operand:DI 3 "register_operand" "")
8313         (umod:DI (match_dup 1) (match_dup 2)))
8314    (clobber (reg:CC FLAGS_REG))]
8315   "TARGET_64BIT && reload_completed"
8316   [(set (match_dup 3) (const_int 0))
8317    (parallel [(set (match_dup 0)
8318                    (udiv:DI (match_dup 1) (match_dup 2)))
8319               (set (match_dup 3)
8320                    (umod:DI (match_dup 1) (match_dup 2)))
8321               (use (match_dup 3))
8322               (clobber (reg:CC FLAGS_REG))])]
8323   "")
8324
8325 (define_insn "udivmodsi4"
8326   [(set (match_operand:SI 0 "register_operand" "=a")
8327         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8328                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8329    (set (match_operand:SI 3 "register_operand" "=&d")
8330         (umod:SI (match_dup 1) (match_dup 2)))
8331    (clobber (reg:CC FLAGS_REG))]
8332   ""
8333   "xor{l}\t%3, %3\;div{l}\t%2"
8334   [(set_attr "type" "multi")
8335    (set_attr "length_immediate" "0")
8336    (set_attr "mode" "SI")])
8337
8338 (define_insn "*udivmodsi4_noext"
8339   [(set (match_operand:SI 0 "register_operand" "=a")
8340         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8341                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8342    (set (match_operand:SI 3 "register_operand" "=d")
8343         (umod:SI (match_dup 1) (match_dup 2)))
8344    (use (match_dup 3))
8345    (clobber (reg:CC FLAGS_REG))]
8346   ""
8347   "div{l}\t%2"
8348   [(set_attr "type" "idiv")
8349    (set_attr "mode" "SI")])
8350
8351 (define_split
8352   [(set (match_operand:SI 0 "register_operand" "")
8353         (udiv:SI (match_operand:SI 1 "register_operand" "")
8354                  (match_operand:SI 2 "nonimmediate_operand" "")))
8355    (set (match_operand:SI 3 "register_operand" "")
8356         (umod:SI (match_dup 1) (match_dup 2)))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "reload_completed"
8359   [(set (match_dup 3) (const_int 0))
8360    (parallel [(set (match_dup 0)
8361                    (udiv:SI (match_dup 1) (match_dup 2)))
8362               (set (match_dup 3)
8363                    (umod:SI (match_dup 1) (match_dup 2)))
8364               (use (match_dup 3))
8365               (clobber (reg:CC FLAGS_REG))])]
8366   "")
8367
8368 (define_expand "udivmodhi4"
8369   [(set (match_dup 4) (const_int 0))
8370    (parallel [(set (match_operand:HI 0 "register_operand" "")
8371                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8372                             (match_operand:HI 2 "nonimmediate_operand" "")))
8373               (set (match_operand:HI 3 "register_operand" "")
8374                    (umod:HI (match_dup 1) (match_dup 2)))
8375               (use (match_dup 4))
8376               (clobber (reg:CC FLAGS_REG))])]
8377   "TARGET_HIMODE_MATH"
8378   "operands[4] = gen_reg_rtx (HImode);")
8379
8380 (define_insn "*udivmodhi_noext"
8381   [(set (match_operand:HI 0 "register_operand" "=a")
8382         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8383                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8384    (set (match_operand:HI 3 "register_operand" "=d")
8385         (umod:HI (match_dup 1) (match_dup 2)))
8386    (use (match_operand:HI 4 "register_operand" "3"))
8387    (clobber (reg:CC FLAGS_REG))]
8388   ""
8389   "div{w}\t%2"
8390   [(set_attr "type" "idiv")
8391    (set_attr "mode" "HI")])
8392
8393 ;; We cannot use div/idiv for double division, because it causes
8394 ;; "division by zero" on the overflow and that's not what we expect
8395 ;; from truncate.  Because true (non truncating) double division is
8396 ;; never generated, we can't create this insn anyway.
8397 ;
8398 ;(define_insn ""
8399 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8400 ;       (truncate:SI
8401 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8402 ;                  (zero_extend:DI
8403 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8404 ;   (set (match_operand:SI 3 "register_operand" "=d")
8405 ;       (truncate:SI
8406 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8407 ;   (clobber (reg:CC FLAGS_REG))]
8408 ;  ""
8409 ;  "div{l}\t{%2, %0|%0, %2}"
8410 ;  [(set_attr "type" "idiv")])
8411 \f
8412 ;;- Logical AND instructions
8413
8414 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8415 ;; Note that this excludes ah.
8416
8417 (define_insn "*testdi_1_rex64"
8418   [(set (reg FLAGS_REG)
8419         (compare
8420           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8421                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8422           (const_int 0)))]
8423   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8424    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425   "@
8426    test{l}\t{%k1, %k0|%k0, %k1}
8427    test{l}\t{%k1, %k0|%k0, %k1}
8428    test{q}\t{%1, %0|%0, %1}
8429    test{q}\t{%1, %0|%0, %1}
8430    test{q}\t{%1, %0|%0, %1}"
8431   [(set_attr "type" "test")
8432    (set_attr "modrm" "0,1,0,1,1")
8433    (set_attr "mode" "SI,SI,DI,DI,DI")
8434    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8435
8436 (define_insn "testsi_1"
8437   [(set (reg FLAGS_REG)
8438         (compare
8439           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8440                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8441           (const_int 0)))]
8442   "ix86_match_ccmode (insn, CCNOmode)
8443    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444   "test{l}\t{%1, %0|%0, %1}"
8445   [(set_attr "type" "test")
8446    (set_attr "modrm" "0,1,1")
8447    (set_attr "mode" "SI")
8448    (set_attr "pent_pair" "uv,np,uv")])
8449
8450 (define_expand "testsi_ccno_1"
8451   [(set (reg:CCNO FLAGS_REG)
8452         (compare:CCNO
8453           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8454                   (match_operand:SI 1 "nonmemory_operand" ""))
8455           (const_int 0)))]
8456   ""
8457   "")
8458
8459 (define_insn "*testhi_1"
8460   [(set (reg FLAGS_REG)
8461         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8462                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8463                  (const_int 0)))]
8464   "ix86_match_ccmode (insn, CCNOmode)
8465    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8466   "test{w}\t{%1, %0|%0, %1}"
8467   [(set_attr "type" "test")
8468    (set_attr "modrm" "0,1,1")
8469    (set_attr "mode" "HI")
8470    (set_attr "pent_pair" "uv,np,uv")])
8471
8472 (define_expand "testqi_ccz_1"
8473   [(set (reg:CCZ FLAGS_REG)
8474         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8475                              (match_operand:QI 1 "nonmemory_operand" ""))
8476                  (const_int 0)))]
8477   ""
8478   "")
8479
8480 (define_insn "*testqi_1_maybe_si"
8481   [(set (reg FLAGS_REG)
8482         (compare
8483           (and:QI
8484             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8485             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8486           (const_int 0)))]
8487    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8488     && ix86_match_ccmode (insn,
8489                          CONST_INT_P (operands[1])
8490                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8491 {
8492   if (which_alternative == 3)
8493     {
8494       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8495         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8496       return "test{l}\t{%1, %k0|%k0, %1}";
8497     }
8498   return "test{b}\t{%1, %0|%0, %1}";
8499 }
8500   [(set_attr "type" "test")
8501    (set_attr "modrm" "0,1,1,1")
8502    (set_attr "mode" "QI,QI,QI,SI")
8503    (set_attr "pent_pair" "uv,np,uv,np")])
8504
8505 (define_insn "*testqi_1"
8506   [(set (reg FLAGS_REG)
8507         (compare
8508           (and:QI
8509             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8510             (match_operand:QI 1 "general_operand" "n,n,qn"))
8511           (const_int 0)))]
8512   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8513    && ix86_match_ccmode (insn, CCNOmode)"
8514   "test{b}\t{%1, %0|%0, %1}"
8515   [(set_attr "type" "test")
8516    (set_attr "modrm" "0,1,1")
8517    (set_attr "mode" "QI")
8518    (set_attr "pent_pair" "uv,np,uv")])
8519
8520 (define_expand "testqi_ext_ccno_0"
8521   [(set (reg:CCNO FLAGS_REG)
8522         (compare:CCNO
8523           (and:SI
8524             (zero_extract:SI
8525               (match_operand 0 "ext_register_operand" "")
8526               (const_int 8)
8527               (const_int 8))
8528             (match_operand 1 "const_int_operand" ""))
8529           (const_int 0)))]
8530   ""
8531   "")
8532
8533 (define_insn "*testqi_ext_0"
8534   [(set (reg FLAGS_REG)
8535         (compare
8536           (and:SI
8537             (zero_extract:SI
8538               (match_operand 0 "ext_register_operand" "Q")
8539               (const_int 8)
8540               (const_int 8))
8541             (match_operand 1 "const_int_operand" "n"))
8542           (const_int 0)))]
8543   "ix86_match_ccmode (insn, CCNOmode)"
8544   "test{b}\t{%1, %h0|%h0, %1}"
8545   [(set_attr "type" "test")
8546    (set_attr "mode" "QI")
8547    (set_attr "length_immediate" "1")
8548    (set_attr "pent_pair" "np")])
8549
8550 (define_insn "*testqi_ext_1"
8551   [(set (reg FLAGS_REG)
8552         (compare
8553           (and:SI
8554             (zero_extract:SI
8555               (match_operand 0 "ext_register_operand" "Q")
8556               (const_int 8)
8557               (const_int 8))
8558             (zero_extend:SI
8559               (match_operand:QI 1 "general_operand" "Qm")))
8560           (const_int 0)))]
8561   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8562    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8563   "test{b}\t{%1, %h0|%h0, %1}"
8564   [(set_attr "type" "test")
8565    (set_attr "mode" "QI")])
8566
8567 (define_insn "*testqi_ext_1_rex64"
8568   [(set (reg FLAGS_REG)
8569         (compare
8570           (and:SI
8571             (zero_extract:SI
8572               (match_operand 0 "ext_register_operand" "Q")
8573               (const_int 8)
8574               (const_int 8))
8575             (zero_extend:SI
8576               (match_operand:QI 1 "register_operand" "Q")))
8577           (const_int 0)))]
8578   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8579   "test{b}\t{%1, %h0|%h0, %1}"
8580   [(set_attr "type" "test")
8581    (set_attr "mode" "QI")])
8582
8583 (define_insn "*testqi_ext_2"
8584   [(set (reg FLAGS_REG)
8585         (compare
8586           (and:SI
8587             (zero_extract:SI
8588               (match_operand 0 "ext_register_operand" "Q")
8589               (const_int 8)
8590               (const_int 8))
8591             (zero_extract:SI
8592               (match_operand 1 "ext_register_operand" "Q")
8593               (const_int 8)
8594               (const_int 8)))
8595           (const_int 0)))]
8596   "ix86_match_ccmode (insn, CCNOmode)"
8597   "test{b}\t{%h1, %h0|%h0, %h1}"
8598   [(set_attr "type" "test")
8599    (set_attr "mode" "QI")])
8600
8601 ;; Combine likes to form bit extractions for some tests.  Humor it.
8602 (define_insn "*testqi_ext_3"
8603   [(set (reg FLAGS_REG)
8604         (compare (zero_extract:SI
8605                    (match_operand 0 "nonimmediate_operand" "rm")
8606                    (match_operand:SI 1 "const_int_operand" "")
8607                    (match_operand:SI 2 "const_int_operand" ""))
8608                  (const_int 0)))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && INTVAL (operands[1]) > 0
8611    && INTVAL (operands[2]) >= 0
8612    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8613    && (GET_MODE (operands[0]) == SImode
8614        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8615        || GET_MODE (operands[0]) == HImode
8616        || GET_MODE (operands[0]) == QImode)"
8617   "#")
8618
8619 (define_insn "*testqi_ext_3_rex64"
8620   [(set (reg FLAGS_REG)
8621         (compare (zero_extract:DI
8622                    (match_operand 0 "nonimmediate_operand" "rm")
8623                    (match_operand:DI 1 "const_int_operand" "")
8624                    (match_operand:DI 2 "const_int_operand" ""))
8625                  (const_int 0)))]
8626   "TARGET_64BIT
8627    && ix86_match_ccmode (insn, CCNOmode)
8628    && INTVAL (operands[1]) > 0
8629    && INTVAL (operands[2]) >= 0
8630    /* Ensure that resulting mask is zero or sign extended operand.  */
8631    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8632        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8633            && INTVAL (operands[1]) > 32))
8634    && (GET_MODE (operands[0]) == SImode
8635        || GET_MODE (operands[0]) == DImode
8636        || GET_MODE (operands[0]) == HImode
8637        || GET_MODE (operands[0]) == QImode)"
8638   "#")
8639
8640 (define_split
8641   [(set (match_operand 0 "flags_reg_operand" "")
8642         (match_operator 1 "compare_operator"
8643           [(zero_extract
8644              (match_operand 2 "nonimmediate_operand" "")
8645              (match_operand 3 "const_int_operand" "")
8646              (match_operand 4 "const_int_operand" ""))
8647            (const_int 0)]))]
8648   "ix86_match_ccmode (insn, CCNOmode)"
8649   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8650 {
8651   rtx val = operands[2];
8652   HOST_WIDE_INT len = INTVAL (operands[3]);
8653   HOST_WIDE_INT pos = INTVAL (operands[4]);
8654   HOST_WIDE_INT mask;
8655   enum machine_mode mode, submode;
8656
8657   mode = GET_MODE (val);
8658   if (MEM_P (val))
8659     {
8660       /* ??? Combine likes to put non-volatile mem extractions in QImode
8661          no matter the size of the test.  So find a mode that works.  */
8662       if (! MEM_VOLATILE_P (val))
8663         {
8664           mode = smallest_mode_for_size (pos + len, MODE_INT);
8665           val = adjust_address (val, mode, 0);
8666         }
8667     }
8668   else if (GET_CODE (val) == SUBREG
8669            && (submode = GET_MODE (SUBREG_REG (val)),
8670                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8671            && pos + len <= GET_MODE_BITSIZE (submode))
8672     {
8673       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8674       mode = submode;
8675       val = SUBREG_REG (val);
8676     }
8677   else if (mode == HImode && pos + len <= 8)
8678     {
8679       /* Small HImode tests can be converted to QImode.  */
8680       mode = QImode;
8681       val = gen_lowpart (QImode, val);
8682     }
8683
8684   if (len == HOST_BITS_PER_WIDE_INT)
8685     mask = -1;
8686   else
8687     mask = ((HOST_WIDE_INT)1 << len) - 1;
8688   mask <<= pos;
8689
8690   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8691 })
8692
8693 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8694 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8695 ;; this is relatively important trick.
8696 ;; Do the conversion only post-reload to avoid limiting of the register class
8697 ;; to QI regs.
8698 (define_split
8699   [(set (match_operand 0 "flags_reg_operand" "")
8700         (match_operator 1 "compare_operator"
8701           [(and (match_operand 2 "register_operand" "")
8702                 (match_operand 3 "const_int_operand" ""))
8703            (const_int 0)]))]
8704    "reload_completed
8705     && QI_REG_P (operands[2])
8706     && GET_MODE (operands[2]) != QImode
8707     && ((ix86_match_ccmode (insn, CCZmode)
8708          && !(INTVAL (operands[3]) & ~(255 << 8)))
8709         || (ix86_match_ccmode (insn, CCNOmode)
8710             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8711   [(set (match_dup 0)
8712         (match_op_dup 1
8713           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8714                    (match_dup 3))
8715            (const_int 0)]))]
8716   "operands[2] = gen_lowpart (SImode, operands[2]);
8717    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8718
8719 (define_split
8720   [(set (match_operand 0 "flags_reg_operand" "")
8721         (match_operator 1 "compare_operator"
8722           [(and (match_operand 2 "nonimmediate_operand" "")
8723                 (match_operand 3 "const_int_operand" ""))
8724            (const_int 0)]))]
8725    "reload_completed
8726     && GET_MODE (operands[2]) != QImode
8727     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8728     && ((ix86_match_ccmode (insn, CCZmode)
8729          && !(INTVAL (operands[3]) & ~255))
8730         || (ix86_match_ccmode (insn, CCNOmode)
8731             && !(INTVAL (operands[3]) & ~127)))"
8732   [(set (match_dup 0)
8733         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8734                          (const_int 0)]))]
8735   "operands[2] = gen_lowpart (QImode, operands[2]);
8736    operands[3] = gen_lowpart (QImode, operands[3]);")
8737
8738
8739 ;; %%% This used to optimize known byte-wide and operations to memory,
8740 ;; and sometimes to QImode registers.  If this is considered useful,
8741 ;; it should be done with splitters.
8742
8743 (define_expand "anddi3"
8744   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8745         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8746                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8747    (clobber (reg:CC FLAGS_REG))]
8748   "TARGET_64BIT"
8749   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8750
8751 (define_insn "*anddi_1_rex64"
8752   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8753         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8754                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8755    (clobber (reg:CC FLAGS_REG))]
8756   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8757 {
8758   switch (get_attr_type (insn))
8759     {
8760     case TYPE_IMOVX:
8761       {
8762         enum machine_mode mode;
8763
8764         gcc_assert (CONST_INT_P (operands[2]));
8765         if (INTVAL (operands[2]) == 0xff)
8766           mode = QImode;
8767         else
8768           {
8769             gcc_assert (INTVAL (operands[2]) == 0xffff);
8770             mode = HImode;
8771           }
8772
8773         operands[1] = gen_lowpart (mode, operands[1]);
8774         if (mode == QImode)
8775           return "movz{bq|x}\t{%1,%0|%0, %1}";
8776         else
8777           return "movz{wq|x}\t{%1,%0|%0, %1}";
8778       }
8779
8780     default:
8781       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8782       if (get_attr_mode (insn) == MODE_SI)
8783         return "and{l}\t{%k2, %k0|%k0, %k2}";
8784       else
8785         return "and{q}\t{%2, %0|%0, %2}";
8786     }
8787 }
8788   [(set_attr "type" "alu,alu,alu,imovx")
8789    (set_attr "length_immediate" "*,*,*,0")
8790    (set_attr "mode" "SI,DI,DI,DI")])
8791
8792 (define_insn "*anddi_2"
8793   [(set (reg FLAGS_REG)
8794         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8795                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8796                  (const_int 0)))
8797    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8798         (and:DI (match_dup 1) (match_dup 2)))]
8799   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8800    && ix86_binary_operator_ok (AND, DImode, operands)"
8801   "@
8802    and{l}\t{%k2, %k0|%k0, %k2}
8803    and{q}\t{%2, %0|%0, %2}
8804    and{q}\t{%2, %0|%0, %2}"
8805   [(set_attr "type" "alu")
8806    (set_attr "mode" "SI,DI,DI")])
8807
8808 (define_expand "andsi3"
8809   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8810         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8811                 (match_operand:SI 2 "general_operand" "")))
8812    (clobber (reg:CC FLAGS_REG))]
8813   ""
8814   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8815
8816 (define_insn "*andsi_1"
8817   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8818         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8819                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8820    (clobber (reg:CC FLAGS_REG))]
8821   "ix86_binary_operator_ok (AND, SImode, operands)"
8822 {
8823   switch (get_attr_type (insn))
8824     {
8825     case TYPE_IMOVX:
8826       {
8827         enum machine_mode mode;
8828
8829         gcc_assert (CONST_INT_P (operands[2]));
8830         if (INTVAL (operands[2]) == 0xff)
8831           mode = QImode;
8832         else
8833           {
8834             gcc_assert (INTVAL (operands[2]) == 0xffff);
8835             mode = HImode;
8836           }
8837
8838         operands[1] = gen_lowpart (mode, operands[1]);
8839         if (mode == QImode)
8840           return "movz{bl|x}\t{%1,%0|%0, %1}";
8841         else
8842           return "movz{wl|x}\t{%1,%0|%0, %1}";
8843       }
8844
8845     default:
8846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8847       return "and{l}\t{%2, %0|%0, %2}";
8848     }
8849 }
8850   [(set_attr "type" "alu,alu,imovx")
8851    (set_attr "length_immediate" "*,*,0")
8852    (set_attr "mode" "SI")])
8853
8854 (define_split
8855   [(set (match_operand 0 "register_operand" "")
8856         (and (match_dup 0)
8857              (const_int -65536)))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8860   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8861   "operands[1] = gen_lowpart (HImode, operands[0]);")
8862
8863 (define_split
8864   [(set (match_operand 0 "ext_register_operand" "")
8865         (and (match_dup 0)
8866              (const_int -256)))
8867    (clobber (reg:CC FLAGS_REG))]
8868   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8869   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8870   "operands[1] = gen_lowpart (QImode, operands[0]);")
8871
8872 (define_split
8873   [(set (match_operand 0 "ext_register_operand" "")
8874         (and (match_dup 0)
8875              (const_int -65281)))
8876    (clobber (reg:CC FLAGS_REG))]
8877   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8878   [(parallel [(set (zero_extract:SI (match_dup 0)
8879                                     (const_int 8)
8880                                     (const_int 8))
8881                    (xor:SI
8882                      (zero_extract:SI (match_dup 0)
8883                                       (const_int 8)
8884                                       (const_int 8))
8885                      (zero_extract:SI (match_dup 0)
8886                                       (const_int 8)
8887                                       (const_int 8))))
8888               (clobber (reg:CC FLAGS_REG))])]
8889   "operands[0] = gen_lowpart (SImode, operands[0]);")
8890
8891 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8892 (define_insn "*andsi_1_zext"
8893   [(set (match_operand:DI 0 "register_operand" "=r")
8894         (zero_extend:DI
8895           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8896                   (match_operand:SI 2 "general_operand" "g"))))
8897    (clobber (reg:CC FLAGS_REG))]
8898   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8899   "and{l}\t{%2, %k0|%k0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "SI")])
8902
8903 (define_insn "*andsi_2"
8904   [(set (reg FLAGS_REG)
8905         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8906                          (match_operand:SI 2 "general_operand" "g,ri"))
8907                  (const_int 0)))
8908    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8909         (and:SI (match_dup 1) (match_dup 2)))]
8910   "ix86_match_ccmode (insn, CCNOmode)
8911    && ix86_binary_operator_ok (AND, SImode, operands)"
8912   "and{l}\t{%2, %0|%0, %2}"
8913   [(set_attr "type" "alu")
8914    (set_attr "mode" "SI")])
8915
8916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8917 (define_insn "*andsi_2_zext"
8918   [(set (reg FLAGS_REG)
8919         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8920                          (match_operand:SI 2 "general_operand" "g"))
8921                  (const_int 0)))
8922    (set (match_operand:DI 0 "register_operand" "=r")
8923         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8924   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925    && ix86_binary_operator_ok (AND, SImode, operands)"
8926   "and{l}\t{%2, %k0|%k0, %2}"
8927   [(set_attr "type" "alu")
8928    (set_attr "mode" "SI")])
8929
8930 (define_expand "andhi3"
8931   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8932         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8933                 (match_operand:HI 2 "general_operand" "")))
8934    (clobber (reg:CC FLAGS_REG))]
8935   "TARGET_HIMODE_MATH"
8936   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8937
8938 (define_insn "*andhi_1"
8939   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8940         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8941                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8942    (clobber (reg:CC FLAGS_REG))]
8943   "ix86_binary_operator_ok (AND, HImode, operands)"
8944 {
8945   switch (get_attr_type (insn))
8946     {
8947     case TYPE_IMOVX:
8948       gcc_assert (CONST_INT_P (operands[2]));
8949       gcc_assert (INTVAL (operands[2]) == 0xff);
8950       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8951
8952     default:
8953       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8954
8955       return "and{w}\t{%2, %0|%0, %2}";
8956     }
8957 }
8958   [(set_attr "type" "alu,alu,imovx")
8959    (set_attr "length_immediate" "*,*,0")
8960    (set_attr "mode" "HI,HI,SI")])
8961
8962 (define_insn "*andhi_2"
8963   [(set (reg FLAGS_REG)
8964         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8965                          (match_operand:HI 2 "general_operand" "g,ri"))
8966                  (const_int 0)))
8967    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8968         (and:HI (match_dup 1) (match_dup 2)))]
8969   "ix86_match_ccmode (insn, CCNOmode)
8970    && ix86_binary_operator_ok (AND, HImode, operands)"
8971   "and{w}\t{%2, %0|%0, %2}"
8972   [(set_attr "type" "alu")
8973    (set_attr "mode" "HI")])
8974
8975 (define_expand "andqi3"
8976   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8977         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8978                 (match_operand:QI 2 "general_operand" "")))
8979    (clobber (reg:CC FLAGS_REG))]
8980   "TARGET_QIMODE_MATH"
8981   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8982
8983 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8984 (define_insn "*andqi_1"
8985   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8986         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8987                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8988    (clobber (reg:CC FLAGS_REG))]
8989   "ix86_binary_operator_ok (AND, QImode, operands)"
8990   "@
8991    and{b}\t{%2, %0|%0, %2}
8992    and{b}\t{%2, %0|%0, %2}
8993    and{l}\t{%k2, %k0|%k0, %k2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "mode" "QI,QI,SI")])
8996
8997 (define_insn "*andqi_1_slp"
8998   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8999         (and:QI (match_dup 0)
9000                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9001    (clobber (reg:CC FLAGS_REG))]
9002   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9003    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9004   "and{b}\t{%1, %0|%0, %1}"
9005   [(set_attr "type" "alu1")
9006    (set_attr "mode" "QI")])
9007
9008 (define_insn "*andqi_2_maybe_si"
9009   [(set (reg FLAGS_REG)
9010         (compare (and:QI
9011                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9012                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9013                  (const_int 0)))
9014    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9015         (and:QI (match_dup 1) (match_dup 2)))]
9016   "ix86_binary_operator_ok (AND, QImode, operands)
9017    && ix86_match_ccmode (insn,
9018                          CONST_INT_P (operands[2])
9019                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9020 {
9021   if (which_alternative == 2)
9022     {
9023       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9024         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9025       return "and{l}\t{%2, %k0|%k0, %2}";
9026     }
9027   return "and{b}\t{%2, %0|%0, %2}";
9028 }
9029   [(set_attr "type" "alu")
9030    (set_attr "mode" "QI,QI,SI")])
9031
9032 (define_insn "*andqi_2"
9033   [(set (reg FLAGS_REG)
9034         (compare (and:QI
9035                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9036                    (match_operand:QI 2 "general_operand" "qim,qi"))
9037                  (const_int 0)))
9038    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9039         (and:QI (match_dup 1) (match_dup 2)))]
9040   "ix86_match_ccmode (insn, CCNOmode)
9041    && ix86_binary_operator_ok (AND, QImode, operands)"
9042   "and{b}\t{%2, %0|%0, %2}"
9043   [(set_attr "type" "alu")
9044    (set_attr "mode" "QI")])
9045
9046 (define_insn "*andqi_2_slp"
9047   [(set (reg FLAGS_REG)
9048         (compare (and:QI
9049                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9050                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9051                  (const_int 0)))
9052    (set (strict_low_part (match_dup 0))
9053         (and:QI (match_dup 0) (match_dup 1)))]
9054   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9055    && ix86_match_ccmode (insn, CCNOmode)
9056    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9057   "and{b}\t{%1, %0|%0, %1}"
9058   [(set_attr "type" "alu1")
9059    (set_attr "mode" "QI")])
9060
9061 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9062 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9063 ;; for a QImode operand, which of course failed.
9064
9065 (define_insn "andqi_ext_0"
9066   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9067                          (const_int 8)
9068                          (const_int 8))
9069         (and:SI
9070           (zero_extract:SI
9071             (match_operand 1 "ext_register_operand" "0")
9072             (const_int 8)
9073             (const_int 8))
9074           (match_operand 2 "const_int_operand" "n")))
9075    (clobber (reg:CC FLAGS_REG))]
9076   ""
9077   "and{b}\t{%2, %h0|%h0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "length_immediate" "1")
9080    (set_attr "mode" "QI")])
9081
9082 ;; Generated by peephole translating test to and.  This shows up
9083 ;; often in fp comparisons.
9084
9085 (define_insn "*andqi_ext_0_cc"
9086   [(set (reg FLAGS_REG)
9087         (compare
9088           (and:SI
9089             (zero_extract:SI
9090               (match_operand 1 "ext_register_operand" "0")
9091               (const_int 8)
9092               (const_int 8))
9093             (match_operand 2 "const_int_operand" "n"))
9094           (const_int 0)))
9095    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9096                          (const_int 8)
9097                          (const_int 8))
9098         (and:SI
9099           (zero_extract:SI
9100             (match_dup 1)
9101             (const_int 8)
9102             (const_int 8))
9103           (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)"
9105   "and{b}\t{%2, %h0|%h0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "length_immediate" "1")
9108    (set_attr "mode" "QI")])
9109
9110 (define_insn "*andqi_ext_1"
9111   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9112                          (const_int 8)
9113                          (const_int 8))
9114         (and:SI
9115           (zero_extract:SI
9116             (match_operand 1 "ext_register_operand" "0")
9117             (const_int 8)
9118             (const_int 8))
9119           (zero_extend:SI
9120             (match_operand:QI 2 "general_operand" "Qm"))))
9121    (clobber (reg:CC FLAGS_REG))]
9122   "!TARGET_64BIT"
9123   "and{b}\t{%2, %h0|%h0, %2}"
9124   [(set_attr "type" "alu")
9125    (set_attr "length_immediate" "0")
9126    (set_attr "mode" "QI")])
9127
9128 (define_insn "*andqi_ext_1_rex64"
9129   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9130                          (const_int 8)
9131                          (const_int 8))
9132         (and:SI
9133           (zero_extract:SI
9134             (match_operand 1 "ext_register_operand" "0")
9135             (const_int 8)
9136             (const_int 8))
9137           (zero_extend:SI
9138             (match_operand 2 "ext_register_operand" "Q"))))
9139    (clobber (reg:CC FLAGS_REG))]
9140   "TARGET_64BIT"
9141   "and{b}\t{%2, %h0|%h0, %2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "length_immediate" "0")
9144    (set_attr "mode" "QI")])
9145
9146 (define_insn "*andqi_ext_2"
9147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9148                          (const_int 8)
9149                          (const_int 8))
9150         (and:SI
9151           (zero_extract:SI
9152             (match_operand 1 "ext_register_operand" "%0")
9153             (const_int 8)
9154             (const_int 8))
9155           (zero_extract:SI
9156             (match_operand 2 "ext_register_operand" "Q")
9157             (const_int 8)
9158             (const_int 8))))
9159    (clobber (reg:CC FLAGS_REG))]
9160   ""
9161   "and{b}\t{%h2, %h0|%h0, %h2}"
9162   [(set_attr "type" "alu")
9163    (set_attr "length_immediate" "0")
9164    (set_attr "mode" "QI")])
9165
9166 ;; Convert wide AND instructions with immediate operand to shorter QImode
9167 ;; equivalents when possible.
9168 ;; Don't do the splitting with memory operands, since it introduces risk
9169 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9170 ;; for size, but that can (should?) be handled by generic code instead.
9171 (define_split
9172   [(set (match_operand 0 "register_operand" "")
9173         (and (match_operand 1 "register_operand" "")
9174              (match_operand 2 "const_int_operand" "")))
9175    (clobber (reg:CC FLAGS_REG))]
9176    "reload_completed
9177     && QI_REG_P (operands[0])
9178     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9179     && !(~INTVAL (operands[2]) & ~(255 << 8))
9180     && GET_MODE (operands[0]) != QImode"
9181   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9182                    (and:SI (zero_extract:SI (match_dup 1)
9183                                             (const_int 8) (const_int 8))
9184                            (match_dup 2)))
9185               (clobber (reg:CC FLAGS_REG))])]
9186   "operands[0] = gen_lowpart (SImode, operands[0]);
9187    operands[1] = gen_lowpart (SImode, operands[1]);
9188    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9189
9190 ;; Since AND can be encoded with sign extended immediate, this is only
9191 ;; profitable when 7th bit is not set.
9192 (define_split
9193   [(set (match_operand 0 "register_operand" "")
9194         (and (match_operand 1 "general_operand" "")
9195              (match_operand 2 "const_int_operand" "")))
9196    (clobber (reg:CC FLAGS_REG))]
9197    "reload_completed
9198     && ANY_QI_REG_P (operands[0])
9199     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9200     && !(~INTVAL (operands[2]) & ~255)
9201     && !(INTVAL (operands[2]) & 128)
9202     && GET_MODE (operands[0]) != QImode"
9203   [(parallel [(set (strict_low_part (match_dup 0))
9204                    (and:QI (match_dup 1)
9205                            (match_dup 2)))
9206               (clobber (reg:CC FLAGS_REG))])]
9207   "operands[0] = gen_lowpart (QImode, operands[0]);
9208    operands[1] = gen_lowpart (QImode, operands[1]);
9209    operands[2] = gen_lowpart (QImode, operands[2]);")
9210 \f
9211 ;; Logical inclusive OR instructions
9212
9213 ;; %%% This used to optimize known byte-wide and operations to memory.
9214 ;; If this is considered useful, it should be done with splitters.
9215
9216 (define_expand "iordi3"
9217   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9218         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9219                 (match_operand:DI 2 "x86_64_general_operand" "")))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "TARGET_64BIT"
9222   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9223
9224 (define_insn "*iordi_1_rex64"
9225   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9226         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9227                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9228    (clobber (reg:CC FLAGS_REG))]
9229   "TARGET_64BIT
9230    && ix86_binary_operator_ok (IOR, DImode, operands)"
9231   "or{q}\t{%2, %0|%0, %2}"
9232   [(set_attr "type" "alu")
9233    (set_attr "mode" "DI")])
9234
9235 (define_insn "*iordi_2_rex64"
9236   [(set (reg FLAGS_REG)
9237         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9239                  (const_int 0)))
9240    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9241         (ior:DI (match_dup 1) (match_dup 2)))]
9242   "TARGET_64BIT
9243    && ix86_match_ccmode (insn, CCNOmode)
9244    && ix86_binary_operator_ok (IOR, DImode, operands)"
9245   "or{q}\t{%2, %0|%0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "mode" "DI")])
9248
9249 (define_insn "*iordi_3_rex64"
9250   [(set (reg FLAGS_REG)
9251         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9252                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9253                  (const_int 0)))
9254    (clobber (match_scratch:DI 0 "=r"))]
9255   "TARGET_64BIT
9256    && ix86_match_ccmode (insn, CCNOmode)
9257    && ix86_binary_operator_ok (IOR, DImode, operands)"
9258   "or{q}\t{%2, %0|%0, %2}"
9259   [(set_attr "type" "alu")
9260    (set_attr "mode" "DI")])
9261
9262
9263 (define_expand "iorsi3"
9264   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9265         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9266                 (match_operand:SI 2 "general_operand" "")))
9267    (clobber (reg:CC FLAGS_REG))]
9268   ""
9269   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9270
9271 (define_insn "*iorsi_1"
9272   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9273         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9274                 (match_operand:SI 2 "general_operand" "ri,g")))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "ix86_binary_operator_ok (IOR, SImode, operands)"
9277   "or{l}\t{%2, %0|%0, %2}"
9278   [(set_attr "type" "alu")
9279    (set_attr "mode" "SI")])
9280
9281 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9282 (define_insn "*iorsi_1_zext"
9283   [(set (match_operand:DI 0 "register_operand" "=r")
9284         (zero_extend:DI
9285           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9286                   (match_operand:SI 2 "general_operand" "g"))))
9287    (clobber (reg:CC FLAGS_REG))]
9288   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9289   "or{l}\t{%2, %k0|%k0, %2}"
9290   [(set_attr "type" "alu")
9291    (set_attr "mode" "SI")])
9292
9293 (define_insn "*iorsi_1_zext_imm"
9294   [(set (match_operand:DI 0 "register_operand" "=r")
9295         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9296                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9297    (clobber (reg:CC FLAGS_REG))]
9298   "TARGET_64BIT"
9299   "or{l}\t{%2, %k0|%k0, %2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "mode" "SI")])
9302
9303 (define_insn "*iorsi_2"
9304   [(set (reg FLAGS_REG)
9305         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9306                          (match_operand:SI 2 "general_operand" "g,ri"))
9307                  (const_int 0)))
9308    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9309         (ior:SI (match_dup 1) (match_dup 2)))]
9310   "ix86_match_ccmode (insn, CCNOmode)
9311    && ix86_binary_operator_ok (IOR, SImode, operands)"
9312   "or{l}\t{%2, %0|%0, %2}"
9313   [(set_attr "type" "alu")
9314    (set_attr "mode" "SI")])
9315
9316 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9317 ;; ??? Special case for immediate operand is missing - it is tricky.
9318 (define_insn "*iorsi_2_zext"
9319   [(set (reg FLAGS_REG)
9320         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9321                          (match_operand:SI 2 "general_operand" "g"))
9322                  (const_int 0)))
9323    (set (match_operand:DI 0 "register_operand" "=r")
9324         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9325   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9326    && ix86_binary_operator_ok (IOR, SImode, operands)"
9327   "or{l}\t{%2, %k0|%k0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "SI")])
9330
9331 (define_insn "*iorsi_2_zext_imm"
9332   [(set (reg FLAGS_REG)
9333         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9334                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9335                  (const_int 0)))
9336    (set (match_operand:DI 0 "register_operand" "=r")
9337         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9338   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9339    && ix86_binary_operator_ok (IOR, SImode, operands)"
9340   "or{l}\t{%2, %k0|%k0, %2}"
9341   [(set_attr "type" "alu")
9342    (set_attr "mode" "SI")])
9343
9344 (define_insn "*iorsi_3"
9345   [(set (reg FLAGS_REG)
9346         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9347                          (match_operand:SI 2 "general_operand" "g"))
9348                  (const_int 0)))
9349    (clobber (match_scratch:SI 0 "=r"))]
9350   "ix86_match_ccmode (insn, CCNOmode)
9351    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9352   "or{l}\t{%2, %0|%0, %2}"
9353   [(set_attr "type" "alu")
9354    (set_attr "mode" "SI")])
9355
9356 (define_expand "iorhi3"
9357   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9358         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9359                 (match_operand:HI 2 "general_operand" "")))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "TARGET_HIMODE_MATH"
9362   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9363
9364 (define_insn "*iorhi_1"
9365   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9366         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9367                 (match_operand:HI 2 "general_operand" "g,ri")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "ix86_binary_operator_ok (IOR, HImode, operands)"
9370   "or{w}\t{%2, %0|%0, %2}"
9371   [(set_attr "type" "alu")
9372    (set_attr "mode" "HI")])
9373
9374 (define_insn "*iorhi_2"
9375   [(set (reg FLAGS_REG)
9376         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9377                          (match_operand:HI 2 "general_operand" "g,ri"))
9378                  (const_int 0)))
9379    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9380         (ior:HI (match_dup 1) (match_dup 2)))]
9381   "ix86_match_ccmode (insn, CCNOmode)
9382    && ix86_binary_operator_ok (IOR, HImode, operands)"
9383   "or{w}\t{%2, %0|%0, %2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "HI")])
9386
9387 (define_insn "*iorhi_3"
9388   [(set (reg FLAGS_REG)
9389         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9390                          (match_operand:HI 2 "general_operand" "g"))
9391                  (const_int 0)))
9392    (clobber (match_scratch:HI 0 "=r"))]
9393   "ix86_match_ccmode (insn, CCNOmode)
9394    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9395   "or{w}\t{%2, %0|%0, %2}"
9396   [(set_attr "type" "alu")
9397    (set_attr "mode" "HI")])
9398
9399 (define_expand "iorqi3"
9400   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9401         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9402                 (match_operand:QI 2 "general_operand" "")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   "TARGET_QIMODE_MATH"
9405   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9406
9407 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9408 (define_insn "*iorqi_1"
9409   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9410         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9411                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "ix86_binary_operator_ok (IOR, QImode, operands)"
9414   "@
9415    or{b}\t{%2, %0|%0, %2}
9416    or{b}\t{%2, %0|%0, %2}
9417    or{l}\t{%k2, %k0|%k0, %k2}"
9418   [(set_attr "type" "alu")
9419    (set_attr "mode" "QI,QI,SI")])
9420
9421 (define_insn "*iorqi_1_slp"
9422   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9423         (ior:QI (match_dup 0)
9424                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9425    (clobber (reg:CC FLAGS_REG))]
9426   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9427    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9428   "or{b}\t{%1, %0|%0, %1}"
9429   [(set_attr "type" "alu1")
9430    (set_attr "mode" "QI")])
9431
9432 (define_insn "*iorqi_2"
9433   [(set (reg FLAGS_REG)
9434         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9435                          (match_operand:QI 2 "general_operand" "qim,qi"))
9436                  (const_int 0)))
9437    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9438         (ior:QI (match_dup 1) (match_dup 2)))]
9439   "ix86_match_ccmode (insn, CCNOmode)
9440    && ix86_binary_operator_ok (IOR, QImode, operands)"
9441   "or{b}\t{%2, %0|%0, %2}"
9442   [(set_attr "type" "alu")
9443    (set_attr "mode" "QI")])
9444
9445 (define_insn "*iorqi_2_slp"
9446   [(set (reg FLAGS_REG)
9447         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9448                          (match_operand:QI 1 "general_operand" "qim,qi"))
9449                  (const_int 0)))
9450    (set (strict_low_part (match_dup 0))
9451         (ior:QI (match_dup 0) (match_dup 1)))]
9452   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9453    && ix86_match_ccmode (insn, CCNOmode)
9454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9455   "or{b}\t{%1, %0|%0, %1}"
9456   [(set_attr "type" "alu1")
9457    (set_attr "mode" "QI")])
9458
9459 (define_insn "*iorqi_3"
9460   [(set (reg FLAGS_REG)
9461         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9462                          (match_operand:QI 2 "general_operand" "qim"))
9463                  (const_int 0)))
9464    (clobber (match_scratch:QI 0 "=q"))]
9465   "ix86_match_ccmode (insn, CCNOmode)
9466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9467   "or{b}\t{%2, %0|%0, %2}"
9468   [(set_attr "type" "alu")
9469    (set_attr "mode" "QI")])
9470
9471 (define_insn "iorqi_ext_0"
9472   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9473                          (const_int 8)
9474                          (const_int 8))
9475         (ior:SI
9476           (zero_extract:SI
9477             (match_operand 1 "ext_register_operand" "0")
9478             (const_int 8)
9479             (const_int 8))
9480           (match_operand 2 "const_int_operand" "n")))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9483   "or{b}\t{%2, %h0|%h0, %2}"
9484   [(set_attr "type" "alu")
9485    (set_attr "length_immediate" "1")
9486    (set_attr "mode" "QI")])
9487
9488 (define_insn "*iorqi_ext_1"
9489   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9490                          (const_int 8)
9491                          (const_int 8))
9492         (ior:SI
9493           (zero_extract:SI
9494             (match_operand 1 "ext_register_operand" "0")
9495             (const_int 8)
9496             (const_int 8))
9497           (zero_extend:SI
9498             (match_operand:QI 2 "general_operand" "Qm"))))
9499    (clobber (reg:CC FLAGS_REG))]
9500   "!TARGET_64BIT
9501    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9502   "or{b}\t{%2, %h0|%h0, %2}"
9503   [(set_attr "type" "alu")
9504    (set_attr "length_immediate" "0")
9505    (set_attr "mode" "QI")])
9506
9507 (define_insn "*iorqi_ext_1_rex64"
9508   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9509                          (const_int 8)
9510                          (const_int 8))
9511         (ior:SI
9512           (zero_extract:SI
9513             (match_operand 1 "ext_register_operand" "0")
9514             (const_int 8)
9515             (const_int 8))
9516           (zero_extend:SI
9517             (match_operand 2 "ext_register_operand" "Q"))))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "TARGET_64BIT
9520    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9521   "or{b}\t{%2, %h0|%h0, %2}"
9522   [(set_attr "type" "alu")
9523    (set_attr "length_immediate" "0")
9524    (set_attr "mode" "QI")])
9525
9526 (define_insn "*iorqi_ext_2"
9527   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9528                          (const_int 8)
9529                          (const_int 8))
9530         (ior:SI
9531           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9532                            (const_int 8)
9533                            (const_int 8))
9534           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9535                            (const_int 8)
9536                            (const_int 8))))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9539   "ior{b}\t{%h2, %h0|%h0, %h2}"
9540   [(set_attr "type" "alu")
9541    (set_attr "length_immediate" "0")
9542    (set_attr "mode" "QI")])
9543
9544 (define_split
9545   [(set (match_operand 0 "register_operand" "")
9546         (ior (match_operand 1 "register_operand" "")
9547              (match_operand 2 "const_int_operand" "")))
9548    (clobber (reg:CC FLAGS_REG))]
9549    "reload_completed
9550     && QI_REG_P (operands[0])
9551     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9552     && !(INTVAL (operands[2]) & ~(255 << 8))
9553     && GET_MODE (operands[0]) != QImode"
9554   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9555                    (ior:SI (zero_extract:SI (match_dup 1)
9556                                             (const_int 8) (const_int 8))
9557                            (match_dup 2)))
9558               (clobber (reg:CC FLAGS_REG))])]
9559   "operands[0] = gen_lowpart (SImode, operands[0]);
9560    operands[1] = gen_lowpart (SImode, operands[1]);
9561    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9562
9563 ;; Since OR can be encoded with sign extended immediate, this is only
9564 ;; profitable when 7th bit is set.
9565 (define_split
9566   [(set (match_operand 0 "register_operand" "")
9567         (ior (match_operand 1 "general_operand" "")
9568              (match_operand 2 "const_int_operand" "")))
9569    (clobber (reg:CC FLAGS_REG))]
9570    "reload_completed
9571     && ANY_QI_REG_P (operands[0])
9572     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9573     && !(INTVAL (operands[2]) & ~255)
9574     && (INTVAL (operands[2]) & 128)
9575     && GET_MODE (operands[0]) != QImode"
9576   [(parallel [(set (strict_low_part (match_dup 0))
9577                    (ior:QI (match_dup 1)
9578                            (match_dup 2)))
9579               (clobber (reg:CC FLAGS_REG))])]
9580   "operands[0] = gen_lowpart (QImode, operands[0]);
9581    operands[1] = gen_lowpart (QImode, operands[1]);
9582    operands[2] = gen_lowpart (QImode, operands[2]);")
9583 \f
9584 ;; Logical XOR instructions
9585
9586 ;; %%% This used to optimize known byte-wide and operations to memory.
9587 ;; If this is considered useful, it should be done with splitters.
9588
9589 (define_expand "xordi3"
9590   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9591         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9592                 (match_operand:DI 2 "x86_64_general_operand" "")))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "TARGET_64BIT"
9595   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9596
9597 (define_insn "*xordi_1_rex64"
9598   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9599         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9600                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "TARGET_64BIT
9603    && ix86_binary_operator_ok (XOR, DImode, operands)"
9604   "@
9605    xor{q}\t{%2, %0|%0, %2}
9606    xor{q}\t{%2, %0|%0, %2}"
9607   [(set_attr "type" "alu")
9608    (set_attr "mode" "DI,DI")])
9609
9610 (define_insn "*xordi_2_rex64"
9611   [(set (reg FLAGS_REG)
9612         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9613                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9614                  (const_int 0)))
9615    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9616         (xor:DI (match_dup 1) (match_dup 2)))]
9617   "TARGET_64BIT
9618    && ix86_match_ccmode (insn, CCNOmode)
9619    && ix86_binary_operator_ok (XOR, DImode, operands)"
9620   "@
9621    xor{q}\t{%2, %0|%0, %2}
9622    xor{q}\t{%2, %0|%0, %2}"
9623   [(set_attr "type" "alu")
9624    (set_attr "mode" "DI,DI")])
9625
9626 (define_insn "*xordi_3_rex64"
9627   [(set (reg FLAGS_REG)
9628         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9629                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9630                  (const_int 0)))
9631    (clobber (match_scratch:DI 0 "=r"))]
9632   "TARGET_64BIT
9633    && ix86_match_ccmode (insn, CCNOmode)
9634    && ix86_binary_operator_ok (XOR, DImode, operands)"
9635   "xor{q}\t{%2, %0|%0, %2}"
9636   [(set_attr "type" "alu")
9637    (set_attr "mode" "DI")])
9638
9639 (define_expand "xorsi3"
9640   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9641         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9642                 (match_operand:SI 2 "general_operand" "")))
9643    (clobber (reg:CC FLAGS_REG))]
9644   ""
9645   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9646
9647 (define_insn "*xorsi_1"
9648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9649         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9650                 (match_operand:SI 2 "general_operand" "ri,rm")))
9651    (clobber (reg:CC FLAGS_REG))]
9652   "ix86_binary_operator_ok (XOR, SImode, operands)"
9653   "xor{l}\t{%2, %0|%0, %2}"
9654   [(set_attr "type" "alu")
9655    (set_attr "mode" "SI")])
9656
9657 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9658 ;; Add speccase for immediates
9659 (define_insn "*xorsi_1_zext"
9660   [(set (match_operand:DI 0 "register_operand" "=r")
9661         (zero_extend:DI
9662           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663                   (match_operand:SI 2 "general_operand" "g"))))
9664    (clobber (reg:CC FLAGS_REG))]
9665   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9666   "xor{l}\t{%2, %k0|%k0, %2}"
9667   [(set_attr "type" "alu")
9668    (set_attr "mode" "SI")])
9669
9670 (define_insn "*xorsi_1_zext_imm"
9671   [(set (match_operand:DI 0 "register_operand" "=r")
9672         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9673                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9676   "xor{l}\t{%2, %k0|%k0, %2}"
9677   [(set_attr "type" "alu")
9678    (set_attr "mode" "SI")])
9679
9680 (define_insn "*xorsi_2"
9681   [(set (reg FLAGS_REG)
9682         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9683                          (match_operand:SI 2 "general_operand" "g,ri"))
9684                  (const_int 0)))
9685    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9686         (xor:SI (match_dup 1) (match_dup 2)))]
9687   "ix86_match_ccmode (insn, CCNOmode)
9688    && ix86_binary_operator_ok (XOR, SImode, operands)"
9689   "xor{l}\t{%2, %0|%0, %2}"
9690   [(set_attr "type" "alu")
9691    (set_attr "mode" "SI")])
9692
9693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9694 ;; ??? Special case for immediate operand is missing - it is tricky.
9695 (define_insn "*xorsi_2_zext"
9696   [(set (reg FLAGS_REG)
9697         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9698                          (match_operand:SI 2 "general_operand" "g"))
9699                  (const_int 0)))
9700    (set (match_operand:DI 0 "register_operand" "=r")
9701         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9702   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9703    && ix86_binary_operator_ok (XOR, SImode, operands)"
9704   "xor{l}\t{%2, %k0|%k0, %2}"
9705   [(set_attr "type" "alu")
9706    (set_attr "mode" "SI")])
9707
9708 (define_insn "*xorsi_2_zext_imm"
9709   [(set (reg FLAGS_REG)
9710         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9711                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9712                  (const_int 0)))
9713    (set (match_operand:DI 0 "register_operand" "=r")
9714         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9715   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9716    && ix86_binary_operator_ok (XOR, SImode, operands)"
9717   "xor{l}\t{%2, %k0|%k0, %2}"
9718   [(set_attr "type" "alu")
9719    (set_attr "mode" "SI")])
9720
9721 (define_insn "*xorsi_3"
9722   [(set (reg FLAGS_REG)
9723         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9724                          (match_operand:SI 2 "general_operand" "g"))
9725                  (const_int 0)))
9726    (clobber (match_scratch:SI 0 "=r"))]
9727   "ix86_match_ccmode (insn, CCNOmode)
9728    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9729   "xor{l}\t{%2, %0|%0, %2}"
9730   [(set_attr "type" "alu")
9731    (set_attr "mode" "SI")])
9732
9733 (define_expand "xorhi3"
9734   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9735         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9736                 (match_operand:HI 2 "general_operand" "")))
9737    (clobber (reg:CC FLAGS_REG))]
9738   "TARGET_HIMODE_MATH"
9739   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9740
9741 (define_insn "*xorhi_1"
9742   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9743         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9744                 (match_operand:HI 2 "general_operand" "g,ri")))
9745    (clobber (reg:CC FLAGS_REG))]
9746   "ix86_binary_operator_ok (XOR, HImode, operands)"
9747   "xor{w}\t{%2, %0|%0, %2}"
9748   [(set_attr "type" "alu")
9749    (set_attr "mode" "HI")])
9750
9751 (define_insn "*xorhi_2"
9752   [(set (reg FLAGS_REG)
9753         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9754                          (match_operand:HI 2 "general_operand" "g,ri"))
9755                  (const_int 0)))
9756    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9757         (xor:HI (match_dup 1) (match_dup 2)))]
9758   "ix86_match_ccmode (insn, CCNOmode)
9759    && ix86_binary_operator_ok (XOR, HImode, operands)"
9760   "xor{w}\t{%2, %0|%0, %2}"
9761   [(set_attr "type" "alu")
9762    (set_attr "mode" "HI")])
9763
9764 (define_insn "*xorhi_3"
9765   [(set (reg FLAGS_REG)
9766         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9767                          (match_operand:HI 2 "general_operand" "g"))
9768                  (const_int 0)))
9769    (clobber (match_scratch:HI 0 "=r"))]
9770   "ix86_match_ccmode (insn, CCNOmode)
9771    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9772   "xor{w}\t{%2, %0|%0, %2}"
9773   [(set_attr "type" "alu")
9774    (set_attr "mode" "HI")])
9775
9776 (define_expand "xorqi3"
9777   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9778         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9779                 (match_operand:QI 2 "general_operand" "")))
9780    (clobber (reg:CC FLAGS_REG))]
9781   "TARGET_QIMODE_MATH"
9782   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9783
9784 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9785 (define_insn "*xorqi_1"
9786   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9787         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9788                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9789    (clobber (reg:CC FLAGS_REG))]
9790   "ix86_binary_operator_ok (XOR, QImode, operands)"
9791   "@
9792    xor{b}\t{%2, %0|%0, %2}
9793    xor{b}\t{%2, %0|%0, %2}
9794    xor{l}\t{%k2, %k0|%k0, %k2}"
9795   [(set_attr "type" "alu")
9796    (set_attr "mode" "QI,QI,SI")])
9797
9798 (define_insn "*xorqi_1_slp"
9799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9800         (xor:QI (match_dup 0)
9801                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9802    (clobber (reg:CC FLAGS_REG))]
9803   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9804    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9805   "xor{b}\t{%1, %0|%0, %1}"
9806   [(set_attr "type" "alu1")
9807    (set_attr "mode" "QI")])
9808
9809 (define_insn "xorqi_ext_0"
9810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9811                          (const_int 8)
9812                          (const_int 8))
9813         (xor:SI
9814           (zero_extract:SI
9815             (match_operand 1 "ext_register_operand" "0")
9816             (const_int 8)
9817             (const_int 8))
9818           (match_operand 2 "const_int_operand" "n")))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9821   "xor{b}\t{%2, %h0|%h0, %2}"
9822   [(set_attr "type" "alu")
9823    (set_attr "length_immediate" "1")
9824    (set_attr "mode" "QI")])
9825
9826 (define_insn "*xorqi_ext_1"
9827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9828                          (const_int 8)
9829                          (const_int 8))
9830         (xor:SI
9831           (zero_extract:SI
9832             (match_operand 1 "ext_register_operand" "0")
9833             (const_int 8)
9834             (const_int 8))
9835           (zero_extend:SI
9836             (match_operand:QI 2 "general_operand" "Qm"))))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "!TARGET_64BIT
9839    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9840   "xor{b}\t{%2, %h0|%h0, %2}"
9841   [(set_attr "type" "alu")
9842    (set_attr "length_immediate" "0")
9843    (set_attr "mode" "QI")])
9844
9845 (define_insn "*xorqi_ext_1_rex64"
9846   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9847                          (const_int 8)
9848                          (const_int 8))
9849         (xor:SI
9850           (zero_extract:SI
9851             (match_operand 1 "ext_register_operand" "0")
9852             (const_int 8)
9853             (const_int 8))
9854           (zero_extend:SI
9855             (match_operand 2 "ext_register_operand" "Q"))))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "TARGET_64BIT
9858    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9859   "xor{b}\t{%2, %h0|%h0, %2}"
9860   [(set_attr "type" "alu")
9861    (set_attr "length_immediate" "0")
9862    (set_attr "mode" "QI")])
9863
9864 (define_insn "*xorqi_ext_2"
9865   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9866                          (const_int 8)
9867                          (const_int 8))
9868         (xor:SI
9869           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9870                            (const_int 8)
9871                            (const_int 8))
9872           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9873                            (const_int 8)
9874                            (const_int 8))))
9875    (clobber (reg:CC FLAGS_REG))]
9876   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9877   "xor{b}\t{%h2, %h0|%h0, %h2}"
9878   [(set_attr "type" "alu")
9879    (set_attr "length_immediate" "0")
9880    (set_attr "mode" "QI")])
9881
9882 (define_insn "*xorqi_cc_1"
9883   [(set (reg FLAGS_REG)
9884         (compare
9885           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9886                   (match_operand:QI 2 "general_operand" "qim,qi"))
9887           (const_int 0)))
9888    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9889         (xor:QI (match_dup 1) (match_dup 2)))]
9890   "ix86_match_ccmode (insn, CCNOmode)
9891    && ix86_binary_operator_ok (XOR, QImode, operands)"
9892   "xor{b}\t{%2, %0|%0, %2}"
9893   [(set_attr "type" "alu")
9894    (set_attr "mode" "QI")])
9895
9896 (define_insn "*xorqi_2_slp"
9897   [(set (reg FLAGS_REG)
9898         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9899                          (match_operand:QI 1 "general_operand" "qim,qi"))
9900                  (const_int 0)))
9901    (set (strict_low_part (match_dup 0))
9902         (xor:QI (match_dup 0) (match_dup 1)))]
9903   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9904    && ix86_match_ccmode (insn, CCNOmode)
9905    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9906   "xor{b}\t{%1, %0|%0, %1}"
9907   [(set_attr "type" "alu1")
9908    (set_attr "mode" "QI")])
9909
9910 (define_insn "*xorqi_cc_2"
9911   [(set (reg FLAGS_REG)
9912         (compare
9913           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9914                   (match_operand:QI 2 "general_operand" "qim"))
9915           (const_int 0)))
9916    (clobber (match_scratch:QI 0 "=q"))]
9917   "ix86_match_ccmode (insn, CCNOmode)
9918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9919   "xor{b}\t{%2, %0|%0, %2}"
9920   [(set_attr "type" "alu")
9921    (set_attr "mode" "QI")])
9922
9923 (define_insn "*xorqi_cc_ext_1"
9924   [(set (reg FLAGS_REG)
9925         (compare
9926           (xor:SI
9927             (zero_extract:SI
9928               (match_operand 1 "ext_register_operand" "0")
9929               (const_int 8)
9930               (const_int 8))
9931             (match_operand:QI 2 "general_operand" "qmn"))
9932           (const_int 0)))
9933    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9934                          (const_int 8)
9935                          (const_int 8))
9936         (xor:SI
9937           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9938           (match_dup 2)))]
9939   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9940   "xor{b}\t{%2, %h0|%h0, %2}"
9941   [(set_attr "type" "alu")
9942    (set_attr "mode" "QI")])
9943
9944 (define_insn "*xorqi_cc_ext_1_rex64"
9945   [(set (reg FLAGS_REG)
9946         (compare
9947           (xor:SI
9948             (zero_extract:SI
9949               (match_operand 1 "ext_register_operand" "0")
9950               (const_int 8)
9951               (const_int 8))
9952             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9953           (const_int 0)))
9954    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9955                          (const_int 8)
9956                          (const_int 8))
9957         (xor:SI
9958           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9959           (match_dup 2)))]
9960   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9961   "xor{b}\t{%2, %h0|%h0, %2}"
9962   [(set_attr "type" "alu")
9963    (set_attr "mode" "QI")])
9964
9965 (define_expand "xorqi_cc_ext_1"
9966   [(parallel [
9967      (set (reg:CCNO FLAGS_REG)
9968           (compare:CCNO
9969             (xor:SI
9970               (zero_extract:SI
9971                 (match_operand 1 "ext_register_operand" "")
9972                 (const_int 8)
9973                 (const_int 8))
9974               (match_operand:QI 2 "general_operand" ""))
9975             (const_int 0)))
9976      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9977                            (const_int 8)
9978                            (const_int 8))
9979           (xor:SI
9980             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9981             (match_dup 2)))])]
9982   ""
9983   "")
9984
9985 (define_split
9986   [(set (match_operand 0 "register_operand" "")
9987         (xor (match_operand 1 "register_operand" "")
9988              (match_operand 2 "const_int_operand" "")))
9989    (clobber (reg:CC FLAGS_REG))]
9990    "reload_completed
9991     && QI_REG_P (operands[0])
9992     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9993     && !(INTVAL (operands[2]) & ~(255 << 8))
9994     && GET_MODE (operands[0]) != QImode"
9995   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9996                    (xor:SI (zero_extract:SI (match_dup 1)
9997                                             (const_int 8) (const_int 8))
9998                            (match_dup 2)))
9999               (clobber (reg:CC FLAGS_REG))])]
10000   "operands[0] = gen_lowpart (SImode, operands[0]);
10001    operands[1] = gen_lowpart (SImode, operands[1]);
10002    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10003
10004 ;; Since XOR can be encoded with sign extended immediate, this is only
10005 ;; profitable when 7th bit is set.
10006 (define_split
10007   [(set (match_operand 0 "register_operand" "")
10008         (xor (match_operand 1 "general_operand" "")
10009              (match_operand 2 "const_int_operand" "")))
10010    (clobber (reg:CC FLAGS_REG))]
10011    "reload_completed
10012     && ANY_QI_REG_P (operands[0])
10013     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10014     && !(INTVAL (operands[2]) & ~255)
10015     && (INTVAL (operands[2]) & 128)
10016     && GET_MODE (operands[0]) != QImode"
10017   [(parallel [(set (strict_low_part (match_dup 0))
10018                    (xor:QI (match_dup 1)
10019                            (match_dup 2)))
10020               (clobber (reg:CC FLAGS_REG))])]
10021   "operands[0] = gen_lowpart (QImode, operands[0]);
10022    operands[1] = gen_lowpart (QImode, operands[1]);
10023    operands[2] = gen_lowpart (QImode, operands[2]);")
10024 \f
10025 ;; Negation instructions
10026
10027 (define_expand "negti2"
10028   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10029                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10030               (clobber (reg:CC FLAGS_REG))])]
10031   "TARGET_64BIT"
10032   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10033
10034 (define_insn "*negti2_1"
10035   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10036         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10037    (clobber (reg:CC FLAGS_REG))]
10038   "TARGET_64BIT
10039    && ix86_unary_operator_ok (NEG, TImode, operands)"
10040   "#")
10041
10042 (define_split
10043   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10044         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10045    (clobber (reg:CC FLAGS_REG))]
10046   "TARGET_64BIT && reload_completed"
10047   [(parallel
10048     [(set (reg:CCZ FLAGS_REG)
10049           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10050      (set (match_dup 0) (neg:DI (match_dup 2)))])
10051    (parallel
10052     [(set (match_dup 1)
10053           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10054                             (match_dup 3))
10055                    (const_int 0)))
10056      (clobber (reg:CC FLAGS_REG))])
10057    (parallel
10058     [(set (match_dup 1)
10059           (neg:DI (match_dup 1)))
10060      (clobber (reg:CC FLAGS_REG))])]
10061   "split_ti (operands+1, 1, operands+2, operands+3);
10062    split_ti (operands+0, 1, operands+0, operands+1);")
10063
10064 (define_expand "negdi2"
10065   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10067               (clobber (reg:CC FLAGS_REG))])]
10068   ""
10069   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10070
10071 (define_insn "*negdi2_1"
10072   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10073         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10074    (clobber (reg:CC FLAGS_REG))]
10075   "!TARGET_64BIT
10076    && ix86_unary_operator_ok (NEG, DImode, operands)"
10077   "#")
10078
10079 (define_split
10080   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10081         (neg:DI (match_operand:DI 1 "general_operand" "")))
10082    (clobber (reg:CC FLAGS_REG))]
10083   "!TARGET_64BIT && reload_completed"
10084   [(parallel
10085     [(set (reg:CCZ FLAGS_REG)
10086           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10087      (set (match_dup 0) (neg:SI (match_dup 2)))])
10088    (parallel
10089     [(set (match_dup 1)
10090           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10091                             (match_dup 3))
10092                    (const_int 0)))
10093      (clobber (reg:CC FLAGS_REG))])
10094    (parallel
10095     [(set (match_dup 1)
10096           (neg:SI (match_dup 1)))
10097      (clobber (reg:CC FLAGS_REG))])]
10098   "split_di (operands+1, 1, operands+2, operands+3);
10099    split_di (operands+0, 1, operands+0, operands+1);")
10100
10101 (define_insn "*negdi2_1_rex64"
10102   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10103         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10104    (clobber (reg:CC FLAGS_REG))]
10105   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10106   "neg{q}\t%0"
10107   [(set_attr "type" "negnot")
10108    (set_attr "mode" "DI")])
10109
10110 ;; The problem with neg is that it does not perform (compare x 0),
10111 ;; it really performs (compare 0 x), which leaves us with the zero
10112 ;; flag being the only useful item.
10113
10114 (define_insn "*negdi2_cmpz_rex64"
10115   [(set (reg:CCZ FLAGS_REG)
10116         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10117                      (const_int 0)))
10118    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10119         (neg:DI (match_dup 1)))]
10120   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10121   "neg{q}\t%0"
10122   [(set_attr "type" "negnot")
10123    (set_attr "mode" "DI")])
10124
10125
10126 (define_expand "negsi2"
10127   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10128                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10129               (clobber (reg:CC FLAGS_REG))])]
10130   ""
10131   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10132
10133 (define_insn "*negsi2_1"
10134   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "ix86_unary_operator_ok (NEG, SImode, operands)"
10138   "neg{l}\t%0"
10139   [(set_attr "type" "negnot")
10140    (set_attr "mode" "SI")])
10141
10142 ;; Combine is quite creative about this pattern.
10143 (define_insn "*negsi2_1_zext"
10144   [(set (match_operand:DI 0 "register_operand" "=r")
10145         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10146                                         (const_int 32)))
10147                      (const_int 32)))
10148    (clobber (reg:CC FLAGS_REG))]
10149   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10150   "neg{l}\t%k0"
10151   [(set_attr "type" "negnot")
10152    (set_attr "mode" "SI")])
10153
10154 ;; The problem with neg is that it does not perform (compare x 0),
10155 ;; it really performs (compare 0 x), which leaves us with the zero
10156 ;; flag being the only useful item.
10157
10158 (define_insn "*negsi2_cmpz"
10159   [(set (reg:CCZ FLAGS_REG)
10160         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10161                      (const_int 0)))
10162    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10163         (neg:SI (match_dup 1)))]
10164   "ix86_unary_operator_ok (NEG, SImode, operands)"
10165   "neg{l}\t%0"
10166   [(set_attr "type" "negnot")
10167    (set_attr "mode" "SI")])
10168
10169 (define_insn "*negsi2_cmpz_zext"
10170   [(set (reg:CCZ FLAGS_REG)
10171         (compare:CCZ (lshiftrt:DI
10172                        (neg:DI (ashift:DI
10173                                  (match_operand:DI 1 "register_operand" "0")
10174                                  (const_int 32)))
10175                        (const_int 32))
10176                      (const_int 0)))
10177    (set (match_operand:DI 0 "register_operand" "=r")
10178         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10179                                         (const_int 32)))
10180                      (const_int 32)))]
10181   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10182   "neg{l}\t%k0"
10183   [(set_attr "type" "negnot")
10184    (set_attr "mode" "SI")])
10185
10186 (define_expand "neghi2"
10187   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10188                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10189               (clobber (reg:CC FLAGS_REG))])]
10190   "TARGET_HIMODE_MATH"
10191   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10192
10193 (define_insn "*neghi2_1"
10194   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10195         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10196    (clobber (reg:CC FLAGS_REG))]
10197   "ix86_unary_operator_ok (NEG, HImode, operands)"
10198   "neg{w}\t%0"
10199   [(set_attr "type" "negnot")
10200    (set_attr "mode" "HI")])
10201
10202 (define_insn "*neghi2_cmpz"
10203   [(set (reg:CCZ FLAGS_REG)
10204         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10205                      (const_int 0)))
10206    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10207         (neg:HI (match_dup 1)))]
10208   "ix86_unary_operator_ok (NEG, HImode, operands)"
10209   "neg{w}\t%0"
10210   [(set_attr "type" "negnot")
10211    (set_attr "mode" "HI")])
10212
10213 (define_expand "negqi2"
10214   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10215                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10216               (clobber (reg:CC FLAGS_REG))])]
10217   "TARGET_QIMODE_MATH"
10218   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10219
10220 (define_insn "*negqi2_1"
10221   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10222         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "ix86_unary_operator_ok (NEG, QImode, operands)"
10225   "neg{b}\t%0"
10226   [(set_attr "type" "negnot")
10227    (set_attr "mode" "QI")])
10228
10229 (define_insn "*negqi2_cmpz"
10230   [(set (reg:CCZ FLAGS_REG)
10231         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10232                      (const_int 0)))
10233    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10234         (neg:QI (match_dup 1)))]
10235   "ix86_unary_operator_ok (NEG, QImode, operands)"
10236   "neg{b}\t%0"
10237   [(set_attr "type" "negnot")
10238    (set_attr "mode" "QI")])
10239
10240 ;; Changing of sign for FP values is doable using integer unit too.
10241
10242 (define_expand "neg<mode>2"
10243   [(set (match_operand:X87MODEF 0 "register_operand" "")
10244         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10245   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10246   "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10247
10248 (define_expand "abs<mode>2"
10249   [(set (match_operand:X87MODEF 0 "register_operand" "")
10250         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10251   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10252   "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10253
10254 (define_insn "*absneg<mode>2_mixed"
10255   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10256         (match_operator:MODEF 3 "absneg_operator"
10257           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10258    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10261   "#")
10262
10263 (define_insn "*absneg<mode>2_sse"
10264   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10265         (match_operator:MODEF 3 "absneg_operator"
10266           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10267    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10270   "#")
10271
10272 (define_insn "*absneg<mode>2_i387"
10273   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10274         (match_operator:X87MODEF 3 "absneg_operator"
10275           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10276    (use (match_operand 2 "" ""))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10279   "#")
10280
10281 (define_expand "negtf2"
10282   [(set (match_operand:TF 0 "register_operand" "")
10283         (neg:TF (match_operand:TF 1 "register_operand" "")))]
10284   "TARGET_64BIT"
10285   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10286
10287 (define_expand "abstf2"
10288   [(set (match_operand:TF 0 "register_operand" "")
10289         (abs:TF (match_operand:TF 1 "register_operand" "")))]
10290   "TARGET_64BIT"
10291   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10292
10293 (define_insn "*absnegtf2_sse"
10294   [(set (match_operand:TF 0 "register_operand" "=x,x")
10295         (match_operator:TF 3 "absneg_operator"
10296           [(match_operand:TF 1 "register_operand" "0,x")]))
10297    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10298    (clobber (reg:CC FLAGS_REG))]
10299   "TARGET_64BIT"
10300   "#")
10301
10302 ;; Splitters for fp abs and neg.
10303
10304 (define_split
10305   [(set (match_operand 0 "fp_register_operand" "")
10306         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10307    (use (match_operand 2 "" ""))
10308    (clobber (reg:CC FLAGS_REG))]
10309   "reload_completed"
10310   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10311
10312 (define_split
10313   [(set (match_operand 0 "register_operand" "")
10314         (match_operator 3 "absneg_operator"
10315           [(match_operand 1 "register_operand" "")]))
10316    (use (match_operand 2 "nonimmediate_operand" ""))
10317    (clobber (reg:CC FLAGS_REG))]
10318   "reload_completed && SSE_REG_P (operands[0])"
10319   [(set (match_dup 0) (match_dup 3))]
10320 {
10321   enum machine_mode mode = GET_MODE (operands[0]);
10322   enum machine_mode vmode = GET_MODE (operands[2]);
10323   rtx tmp;
10324
10325   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10326   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10327   if (operands_match_p (operands[0], operands[2]))
10328     {
10329       tmp = operands[1];
10330       operands[1] = operands[2];
10331       operands[2] = tmp;
10332     }
10333   if (GET_CODE (operands[3]) == ABS)
10334     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10335   else
10336     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10337   operands[3] = tmp;
10338 })
10339
10340 (define_split
10341   [(set (match_operand:SF 0 "register_operand" "")
10342         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10343    (use (match_operand:V4SF 2 "" ""))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "reload_completed"
10346   [(parallel [(set (match_dup 0) (match_dup 1))
10347               (clobber (reg:CC FLAGS_REG))])]
10348 {
10349   rtx tmp;
10350   operands[0] = gen_lowpart (SImode, operands[0]);
10351   if (GET_CODE (operands[1]) == ABS)
10352     {
10353       tmp = gen_int_mode (0x7fffffff, SImode);
10354       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10355     }
10356   else
10357     {
10358       tmp = gen_int_mode (0x80000000, SImode);
10359       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10360     }
10361   operands[1] = tmp;
10362 })
10363
10364 (define_split
10365   [(set (match_operand:DF 0 "register_operand" "")
10366         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10367    (use (match_operand 2 "" ""))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "reload_completed"
10370   [(parallel [(set (match_dup 0) (match_dup 1))
10371               (clobber (reg:CC FLAGS_REG))])]
10372 {
10373   rtx tmp;
10374   if (TARGET_64BIT)
10375     {
10376       tmp = gen_lowpart (DImode, operands[0]);
10377       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10378       operands[0] = tmp;
10379
10380       if (GET_CODE (operands[1]) == ABS)
10381         tmp = const0_rtx;
10382       else
10383         tmp = gen_rtx_NOT (DImode, tmp);
10384     }
10385   else
10386     {
10387       operands[0] = gen_highpart (SImode, operands[0]);
10388       if (GET_CODE (operands[1]) == ABS)
10389         {
10390           tmp = gen_int_mode (0x7fffffff, SImode);
10391           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10392         }
10393       else
10394         {
10395           tmp = gen_int_mode (0x80000000, SImode);
10396           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10397         }
10398     }
10399   operands[1] = tmp;
10400 })
10401
10402 (define_split
10403   [(set (match_operand:XF 0 "register_operand" "")
10404         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10405    (use (match_operand 2 "" ""))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "reload_completed"
10408   [(parallel [(set (match_dup 0) (match_dup 1))
10409               (clobber (reg:CC FLAGS_REG))])]
10410 {
10411   rtx tmp;
10412   operands[0] = gen_rtx_REG (SImode,
10413                              true_regnum (operands[0])
10414                              + (TARGET_64BIT ? 1 : 2));
10415   if (GET_CODE (operands[1]) == ABS)
10416     {
10417       tmp = GEN_INT (0x7fff);
10418       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10419     }
10420   else
10421     {
10422       tmp = GEN_INT (0x8000);
10423       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10424     }
10425   operands[1] = tmp;
10426 })
10427
10428 ;; Conditionalize these after reload. If they match before reload, we
10429 ;; lose the clobber and ability to use integer instructions.
10430
10431 (define_insn "*neg<mode>2_1"
10432   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10433         (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10434   "TARGET_80387
10435    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10436   "fchs"
10437   [(set_attr "type" "fsgn")
10438    (set_attr "mode" "<MODE>")])
10439
10440 (define_insn "*abs<mode>2_1"
10441   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10442         (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10443   "TARGET_80387
10444    && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10445   "fabs"
10446   [(set_attr "type" "fsgn")
10447    (set_attr "mode" "<MODE>")])
10448
10449 (define_insn "*negextendsfdf2"
10450   [(set (match_operand:DF 0 "register_operand" "=f")
10451         (neg:DF (float_extend:DF
10452                   (match_operand:SF 1 "register_operand" "0"))))]
10453   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10454   "fchs"
10455   [(set_attr "type" "fsgn")
10456    (set_attr "mode" "DF")])
10457
10458 (define_insn "*negextenddfxf2"
10459   [(set (match_operand:XF 0 "register_operand" "=f")
10460         (neg:XF (float_extend:XF
10461                   (match_operand:DF 1 "register_operand" "0"))))]
10462   "TARGET_80387"
10463   "fchs"
10464   [(set_attr "type" "fsgn")
10465    (set_attr "mode" "XF")])
10466
10467 (define_insn "*negextendsfxf2"
10468   [(set (match_operand:XF 0 "register_operand" "=f")
10469         (neg:XF (float_extend:XF
10470                   (match_operand:SF 1 "register_operand" "0"))))]
10471   "TARGET_80387"
10472   "fchs"
10473   [(set_attr "type" "fsgn")
10474    (set_attr "mode" "XF")])
10475
10476 (define_insn "*absextendsfdf2"
10477   [(set (match_operand:DF 0 "register_operand" "=f")
10478         (abs:DF (float_extend:DF
10479                   (match_operand:SF 1 "register_operand" "0"))))]
10480   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10481   "fabs"
10482   [(set_attr "type" "fsgn")
10483    (set_attr "mode" "DF")])
10484
10485 (define_insn "*absextenddfxf2"
10486   [(set (match_operand:XF 0 "register_operand" "=f")
10487         (abs:XF (float_extend:XF
10488           (match_operand:DF 1 "register_operand" "0"))))]
10489   "TARGET_80387"
10490   "fabs"
10491   [(set_attr "type" "fsgn")
10492    (set_attr "mode" "XF")])
10493
10494 (define_insn "*absextendsfxf2"
10495   [(set (match_operand:XF 0 "register_operand" "=f")
10496         (abs:XF (float_extend:XF
10497           (match_operand:SF 1 "register_operand" "0"))))]
10498   "TARGET_80387"
10499   "fabs"
10500   [(set_attr "type" "fsgn")
10501    (set_attr "mode" "XF")])
10502
10503 ;; Copysign instructions
10504
10505 (define_mode_iterator CSGNMODE [SF DF TF])
10506 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10507
10508 (define_expand "copysign<mode>3"
10509   [(match_operand:CSGNMODE 0 "register_operand" "")
10510    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10511    (match_operand:CSGNMODE 2 "register_operand" "")]
10512   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10513    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10514 {
10515   ix86_expand_copysign (operands);
10516   DONE;
10517 })
10518
10519 (define_insn_and_split "copysign<mode>3_const"
10520   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10521         (unspec:CSGNMODE
10522           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10523            (match_operand:CSGNMODE 2 "register_operand" "0")
10524            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10525           UNSPEC_COPYSIGN))]
10526   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10527    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10528   "#"
10529   "&& reload_completed"
10530   [(const_int 0)]
10531 {
10532   ix86_split_copysign_const (operands);
10533   DONE;
10534 })
10535
10536 (define_insn "copysign<mode>3_var"
10537   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10538         (unspec:CSGNMODE
10539           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10540            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10541            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10542            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10543           UNSPEC_COPYSIGN))
10544    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10545   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10546    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10547   "#")
10548
10549 (define_split
10550   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10551         (unspec:CSGNMODE
10552           [(match_operand:CSGNMODE 2 "register_operand" "")
10553            (match_operand:CSGNMODE 3 "register_operand" "")
10554            (match_operand:<CSGNVMODE> 4 "" "")
10555            (match_operand:<CSGNVMODE> 5 "" "")]
10556           UNSPEC_COPYSIGN))
10557    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10558   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10559     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10560    && reload_completed"
10561   [(const_int 0)]
10562 {
10563   ix86_split_copysign_var (operands);
10564   DONE;
10565 })
10566 \f
10567 ;; One complement instructions
10568
10569 (define_expand "one_cmpldi2"
10570   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10571         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10572   "TARGET_64BIT"
10573   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10574
10575 (define_insn "*one_cmpldi2_1_rex64"
10576   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10577         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10578   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10579   "not{q}\t%0"
10580   [(set_attr "type" "negnot")
10581    (set_attr "mode" "DI")])
10582
10583 (define_insn "*one_cmpldi2_2_rex64"
10584   [(set (reg FLAGS_REG)
10585         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10586                  (const_int 0)))
10587    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10588         (not:DI (match_dup 1)))]
10589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10590    && ix86_unary_operator_ok (NOT, DImode, operands)"
10591   "#"
10592   [(set_attr "type" "alu1")
10593    (set_attr "mode" "DI")])
10594
10595 (define_split
10596   [(set (match_operand 0 "flags_reg_operand" "")
10597         (match_operator 2 "compare_operator"
10598           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10599            (const_int 0)]))
10600    (set (match_operand:DI 1 "nonimmediate_operand" "")
10601         (not:DI (match_dup 3)))]
10602   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10603   [(parallel [(set (match_dup 0)
10604                    (match_op_dup 2
10605                      [(xor:DI (match_dup 3) (const_int -1))
10606                       (const_int 0)]))
10607               (set (match_dup 1)
10608                    (xor:DI (match_dup 3) (const_int -1)))])]
10609   "")
10610
10611 (define_expand "one_cmplsi2"
10612   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10613         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10614   ""
10615   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10616
10617 (define_insn "*one_cmplsi2_1"
10618   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10619         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10620   "ix86_unary_operator_ok (NOT, SImode, operands)"
10621   "not{l}\t%0"
10622   [(set_attr "type" "negnot")
10623    (set_attr "mode" "SI")])
10624
10625 ;; ??? Currently never generated - xor is used instead.
10626 (define_insn "*one_cmplsi2_1_zext"
10627   [(set (match_operand:DI 0 "register_operand" "=r")
10628         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10629   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10630   "not{l}\t%k0"
10631   [(set_attr "type" "negnot")
10632    (set_attr "mode" "SI")])
10633
10634 (define_insn "*one_cmplsi2_2"
10635   [(set (reg FLAGS_REG)
10636         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10637                  (const_int 0)))
10638    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10639         (not:SI (match_dup 1)))]
10640   "ix86_match_ccmode (insn, CCNOmode)
10641    && ix86_unary_operator_ok (NOT, SImode, operands)"
10642   "#"
10643   [(set_attr "type" "alu1")
10644    (set_attr "mode" "SI")])
10645
10646 (define_split
10647   [(set (match_operand 0 "flags_reg_operand" "")
10648         (match_operator 2 "compare_operator"
10649           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10650            (const_int 0)]))
10651    (set (match_operand:SI 1 "nonimmediate_operand" "")
10652         (not:SI (match_dup 3)))]
10653   "ix86_match_ccmode (insn, CCNOmode)"
10654   [(parallel [(set (match_dup 0)
10655                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10656                                     (const_int 0)]))
10657               (set (match_dup 1)
10658                    (xor:SI (match_dup 3) (const_int -1)))])]
10659   "")
10660
10661 ;; ??? Currently never generated - xor is used instead.
10662 (define_insn "*one_cmplsi2_2_zext"
10663   [(set (reg FLAGS_REG)
10664         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10665                  (const_int 0)))
10666    (set (match_operand:DI 0 "register_operand" "=r")
10667         (zero_extend:DI (not:SI (match_dup 1))))]
10668   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10669    && ix86_unary_operator_ok (NOT, SImode, operands)"
10670   "#"
10671   [(set_attr "type" "alu1")
10672    (set_attr "mode" "SI")])
10673
10674 (define_split
10675   [(set (match_operand 0 "flags_reg_operand" "")
10676         (match_operator 2 "compare_operator"
10677           [(not:SI (match_operand:SI 3 "register_operand" ""))
10678            (const_int 0)]))
10679    (set (match_operand:DI 1 "register_operand" "")
10680         (zero_extend:DI (not:SI (match_dup 3))))]
10681   "ix86_match_ccmode (insn, CCNOmode)"
10682   [(parallel [(set (match_dup 0)
10683                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10684                                     (const_int 0)]))
10685               (set (match_dup 1)
10686                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10687   "")
10688
10689 (define_expand "one_cmplhi2"
10690   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10691         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10692   "TARGET_HIMODE_MATH"
10693   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10694
10695 (define_insn "*one_cmplhi2_1"
10696   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10697         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10698   "ix86_unary_operator_ok (NOT, HImode, operands)"
10699   "not{w}\t%0"
10700   [(set_attr "type" "negnot")
10701    (set_attr "mode" "HI")])
10702
10703 (define_insn "*one_cmplhi2_2"
10704   [(set (reg FLAGS_REG)
10705         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10706                  (const_int 0)))
10707    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10708         (not:HI (match_dup 1)))]
10709   "ix86_match_ccmode (insn, CCNOmode)
10710    && ix86_unary_operator_ok (NEG, HImode, operands)"
10711   "#"
10712   [(set_attr "type" "alu1")
10713    (set_attr "mode" "HI")])
10714
10715 (define_split
10716   [(set (match_operand 0 "flags_reg_operand" "")
10717         (match_operator 2 "compare_operator"
10718           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10719            (const_int 0)]))
10720    (set (match_operand:HI 1 "nonimmediate_operand" "")
10721         (not:HI (match_dup 3)))]
10722   "ix86_match_ccmode (insn, CCNOmode)"
10723   [(parallel [(set (match_dup 0)
10724                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10725                                     (const_int 0)]))
10726               (set (match_dup 1)
10727                    (xor:HI (match_dup 3) (const_int -1)))])]
10728   "")
10729
10730 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10731 (define_expand "one_cmplqi2"
10732   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10733         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10734   "TARGET_QIMODE_MATH"
10735   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10736
10737 (define_insn "*one_cmplqi2_1"
10738   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10739         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10740   "ix86_unary_operator_ok (NOT, QImode, operands)"
10741   "@
10742    not{b}\t%0
10743    not{l}\t%k0"
10744   [(set_attr "type" "negnot")
10745    (set_attr "mode" "QI,SI")])
10746
10747 (define_insn "*one_cmplqi2_2"
10748   [(set (reg FLAGS_REG)
10749         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10750                  (const_int 0)))
10751    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10752         (not:QI (match_dup 1)))]
10753   "ix86_match_ccmode (insn, CCNOmode)
10754    && ix86_unary_operator_ok (NOT, QImode, operands)"
10755   "#"
10756   [(set_attr "type" "alu1")
10757    (set_attr "mode" "QI")])
10758
10759 (define_split
10760   [(set (match_operand 0 "flags_reg_operand" "")
10761         (match_operator 2 "compare_operator"
10762           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10763            (const_int 0)]))
10764    (set (match_operand:QI 1 "nonimmediate_operand" "")
10765         (not:QI (match_dup 3)))]
10766   "ix86_match_ccmode (insn, CCNOmode)"
10767   [(parallel [(set (match_dup 0)
10768                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10769                                     (const_int 0)]))
10770               (set (match_dup 1)
10771                    (xor:QI (match_dup 3) (const_int -1)))])]
10772   "")
10773 \f
10774 ;; Arithmetic shift instructions
10775
10776 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10777 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10778 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10779 ;; from the assembler input.
10780 ;;
10781 ;; This instruction shifts the target reg/mem as usual, but instead of
10782 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10783 ;; is a left shift double, bits are taken from the high order bits of
10784 ;; reg, else if the insn is a shift right double, bits are taken from the
10785 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10786 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10787 ;;
10788 ;; Since sh[lr]d does not change the `reg' operand, that is done
10789 ;; separately, making all shifts emit pairs of shift double and normal
10790 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10791 ;; support a 63 bit shift, each shift where the count is in a reg expands
10792 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10793 ;;
10794 ;; If the shift count is a constant, we need never emit more than one
10795 ;; shift pair, instead using moves and sign extension for counts greater
10796 ;; than 31.
10797
10798 (define_expand "ashlti3"
10799   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10800                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10801                               (match_operand:QI 2 "nonmemory_operand" "")))
10802               (clobber (reg:CC FLAGS_REG))])]
10803   "TARGET_64BIT"
10804 {
10805   if (! immediate_operand (operands[2], QImode))
10806     {
10807       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10808       DONE;
10809     }
10810   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10811   DONE;
10812 })
10813
10814 (define_insn "ashlti3_1"
10815   [(set (match_operand:TI 0 "register_operand" "=r")
10816         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10817                    (match_operand:QI 2 "register_operand" "c")))
10818    (clobber (match_scratch:DI 3 "=&r"))
10819    (clobber (reg:CC FLAGS_REG))]
10820   "TARGET_64BIT"
10821   "#"
10822   [(set_attr "type" "multi")])
10823
10824 ;; This pattern must be defined before *ashlti3_2 to prevent
10825 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10826
10827 (define_insn "sse2_ashlti3"
10828   [(set (match_operand:TI 0 "register_operand" "=x")
10829         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10830                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10831   "TARGET_SSE2"
10832 {
10833   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10834   return "pslldq\t{%2, %0|%0, %2}";
10835 }
10836   [(set_attr "type" "sseishft")
10837    (set_attr "prefix_data16" "1")
10838    (set_attr "mode" "TI")])
10839
10840 (define_insn "*ashlti3_2"
10841   [(set (match_operand:TI 0 "register_operand" "=r")
10842         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10843                    (match_operand:QI 2 "immediate_operand" "O")))
10844    (clobber (reg:CC FLAGS_REG))]
10845   "TARGET_64BIT"
10846   "#"
10847   [(set_attr "type" "multi")])
10848
10849 (define_split
10850   [(set (match_operand:TI 0 "register_operand" "")
10851         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10852                    (match_operand:QI 2 "register_operand" "")))
10853    (clobber (match_scratch:DI 3 ""))
10854    (clobber (reg:CC FLAGS_REG))]
10855   "TARGET_64BIT && reload_completed"
10856   [(const_int 0)]
10857   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10858
10859 (define_split
10860   [(set (match_operand:TI 0 "register_operand" "")
10861         (ashift:TI (match_operand:TI 1 "register_operand" "")
10862                    (match_operand:QI 2 "immediate_operand" "")))
10863    (clobber (reg:CC FLAGS_REG))]
10864   "TARGET_64BIT && reload_completed"
10865   [(const_int 0)]
10866   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10867
10868 (define_insn "x86_64_shld"
10869   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10870         (ior:DI (ashift:DI (match_dup 0)
10871                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10872                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10873                   (minus:QI (const_int 64) (match_dup 2)))))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "TARGET_64BIT"
10876   "@
10877    shld{q}\t{%2, %1, %0|%0, %1, %2}
10878    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10879   [(set_attr "type" "ishift")
10880    (set_attr "prefix_0f" "1")
10881    (set_attr "mode" "DI")
10882    (set_attr "athlon_decode" "vector")
10883    (set_attr "amdfam10_decode" "vector")])
10884
10885 (define_expand "x86_64_shift_adj"
10886   [(set (reg:CCZ FLAGS_REG)
10887         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10888                              (const_int 64))
10889                      (const_int 0)))
10890    (set (match_operand:DI 0 "register_operand" "")
10891         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10892                          (match_operand:DI 1 "register_operand" "")
10893                          (match_dup 0)))
10894    (set (match_dup 1)
10895         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10896                          (match_operand:DI 3 "register_operand" "r")
10897                          (match_dup 1)))]
10898   "TARGET_64BIT"
10899   "")
10900
10901 (define_expand "ashldi3"
10902   [(set (match_operand:DI 0 "shiftdi_operand" "")
10903         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10904                    (match_operand:QI 2 "nonmemory_operand" "")))]
10905   ""
10906   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10907
10908 (define_insn "*ashldi3_1_rex64"
10909   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10910         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10911                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10912    (clobber (reg:CC FLAGS_REG))]
10913   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10914 {
10915   switch (get_attr_type (insn))
10916     {
10917     case TYPE_ALU:
10918       gcc_assert (operands[2] == const1_rtx);
10919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10920       return "add{q}\t%0, %0";
10921
10922     case TYPE_LEA:
10923       gcc_assert (CONST_INT_P (operands[2]));
10924       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10925       operands[1] = gen_rtx_MULT (DImode, operands[1],
10926                                   GEN_INT (1 << INTVAL (operands[2])));
10927       return "lea{q}\t{%a1, %0|%0, %a1}";
10928
10929     default:
10930       if (REG_P (operands[2]))
10931         return "sal{q}\t{%b2, %0|%0, %b2}";
10932       else if (operands[2] == const1_rtx
10933                && (TARGET_SHIFT1 || optimize_size))
10934         return "sal{q}\t%0";
10935       else
10936         return "sal{q}\t{%2, %0|%0, %2}";
10937     }
10938 }
10939   [(set (attr "type")
10940      (cond [(eq_attr "alternative" "1")
10941               (const_string "lea")
10942             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10943                           (const_int 0))
10944                       (match_operand 0 "register_operand" ""))
10945                  (match_operand 2 "const1_operand" ""))
10946               (const_string "alu")
10947            ]
10948            (const_string "ishift")))
10949    (set_attr "mode" "DI")])
10950
10951 ;; Convert lea to the lea pattern to avoid flags dependency.
10952 (define_split
10953   [(set (match_operand:DI 0 "register_operand" "")
10954         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10955                    (match_operand:QI 2 "immediate_operand" "")))
10956    (clobber (reg:CC FLAGS_REG))]
10957   "TARGET_64BIT && reload_completed
10958    && true_regnum (operands[0]) != true_regnum (operands[1])"
10959   [(set (match_dup 0)
10960         (mult:DI (match_dup 1)
10961                  (match_dup 2)))]
10962   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10963
10964 ;; This pattern can't accept a variable shift count, since shifts by
10965 ;; zero don't affect the flags.  We assume that shifts by constant
10966 ;; zero are optimized away.
10967 (define_insn "*ashldi3_cmp_rex64"
10968   [(set (reg FLAGS_REG)
10969         (compare
10970           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10971                      (match_operand:QI 2 "immediate_operand" "e"))
10972           (const_int 0)))
10973    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10974         (ashift:DI (match_dup 1) (match_dup 2)))]
10975   "TARGET_64BIT
10976    && (optimize_size
10977        || !TARGET_PARTIAL_FLAG_REG_STALL
10978        || (operands[2] == const1_rtx
10979            && (TARGET_SHIFT1
10980                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10981    && ix86_match_ccmode (insn, CCGOCmode)
10982    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10983 {
10984   switch (get_attr_type (insn))
10985     {
10986     case TYPE_ALU:
10987       gcc_assert (operands[2] == const1_rtx);
10988       return "add{q}\t%0, %0";
10989
10990     default:
10991       if (REG_P (operands[2]))
10992         return "sal{q}\t{%b2, %0|%0, %b2}";
10993       else if (operands[2] == const1_rtx
10994                && (TARGET_SHIFT1 || optimize_size))
10995         return "sal{q}\t%0";
10996       else
10997         return "sal{q}\t{%2, %0|%0, %2}";
10998     }
10999 }
11000   [(set (attr "type")
11001      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11002                           (const_int 0))
11003                       (match_operand 0 "register_operand" ""))
11004                  (match_operand 2 "const1_operand" ""))
11005               (const_string "alu")
11006            ]
11007            (const_string "ishift")))
11008    (set_attr "mode" "DI")])
11009
11010 (define_insn "*ashldi3_cconly_rex64"
11011   [(set (reg FLAGS_REG)
11012         (compare
11013           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11014                      (match_operand:QI 2 "immediate_operand" "e"))
11015           (const_int 0)))
11016    (clobber (match_scratch:DI 0 "=r"))]
11017   "TARGET_64BIT
11018    && (optimize_size
11019        || !TARGET_PARTIAL_FLAG_REG_STALL
11020        || (operands[2] == const1_rtx
11021            && (TARGET_SHIFT1
11022                || TARGET_DOUBLE_WITH_ADD)))
11023    && ix86_match_ccmode (insn, CCGOCmode)
11024    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11025 {
11026   switch (get_attr_type (insn))
11027     {
11028     case TYPE_ALU:
11029       gcc_assert (operands[2] == const1_rtx);
11030       return "add{q}\t%0, %0";
11031
11032     default:
11033       if (REG_P (operands[2]))
11034         return "sal{q}\t{%b2, %0|%0, %b2}";
11035       else if (operands[2] == const1_rtx
11036                && (TARGET_SHIFT1 || optimize_size))
11037         return "sal{q}\t%0";
11038       else
11039         return "sal{q}\t{%2, %0|%0, %2}";
11040     }
11041 }
11042   [(set (attr "type")
11043      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11044                           (const_int 0))
11045                       (match_operand 0 "register_operand" ""))
11046                  (match_operand 2 "const1_operand" ""))
11047               (const_string "alu")
11048            ]
11049            (const_string "ishift")))
11050    (set_attr "mode" "DI")])
11051
11052 (define_insn "*ashldi3_1"
11053   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11054         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11055                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11056    (clobber (reg:CC FLAGS_REG))]
11057   "!TARGET_64BIT"
11058   "#"
11059   [(set_attr "type" "multi")])
11060
11061 ;; By default we don't ask for a scratch register, because when DImode
11062 ;; values are manipulated, registers are already at a premium.  But if
11063 ;; we have one handy, we won't turn it away.
11064 (define_peephole2
11065   [(match_scratch:SI 3 "r")
11066    (parallel [(set (match_operand:DI 0 "register_operand" "")
11067                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11068                               (match_operand:QI 2 "nonmemory_operand" "")))
11069               (clobber (reg:CC FLAGS_REG))])
11070    (match_dup 3)]
11071   "!TARGET_64BIT && TARGET_CMOVE"
11072   [(const_int 0)]
11073   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11074
11075 (define_split
11076   [(set (match_operand:DI 0 "register_operand" "")
11077         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11078                    (match_operand:QI 2 "nonmemory_operand" "")))
11079    (clobber (reg:CC FLAGS_REG))]
11080   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11081                      ? epilogue_completed : reload_completed)"
11082   [(const_int 0)]
11083   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11084
11085 (define_insn "x86_shld_1"
11086   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11087         (ior:SI (ashift:SI (match_dup 0)
11088                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11089                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11090                   (minus:QI (const_int 32) (match_dup 2)))))
11091    (clobber (reg:CC FLAGS_REG))]
11092   ""
11093   "@
11094    shld{l}\t{%2, %1, %0|%0, %1, %2}
11095    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11096   [(set_attr "type" "ishift")
11097    (set_attr "prefix_0f" "1")
11098    (set_attr "mode" "SI")
11099    (set_attr "pent_pair" "np")
11100    (set_attr "athlon_decode" "vector")
11101    (set_attr "amdfam10_decode" "vector")])
11102
11103 (define_expand "x86_shift_adj_1"
11104   [(set (reg:CCZ FLAGS_REG)
11105         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11106                              (const_int 32))
11107                      (const_int 0)))
11108    (set (match_operand:SI 0 "register_operand" "")
11109         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11110                          (match_operand:SI 1 "register_operand" "")
11111                          (match_dup 0)))
11112    (set (match_dup 1)
11113         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11114                          (match_operand:SI 3 "register_operand" "r")
11115                          (match_dup 1)))]
11116   "TARGET_CMOVE"
11117   "")
11118
11119 (define_expand "x86_shift_adj_2"
11120   [(use (match_operand:SI 0 "register_operand" ""))
11121    (use (match_operand:SI 1 "register_operand" ""))
11122    (use (match_operand:QI 2 "register_operand" ""))]
11123   ""
11124 {
11125   rtx label = gen_label_rtx ();
11126   rtx tmp;
11127
11128   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11129
11130   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11131   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11132   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11133                               gen_rtx_LABEL_REF (VOIDmode, label),
11134                               pc_rtx);
11135   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11136   JUMP_LABEL (tmp) = label;
11137
11138   emit_move_insn (operands[0], operands[1]);
11139   ix86_expand_clear (operands[1]);
11140
11141   emit_label (label);
11142   LABEL_NUSES (label) = 1;
11143
11144   DONE;
11145 })
11146
11147 (define_expand "ashlsi3"
11148   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11149         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11150                    (match_operand:QI 2 "nonmemory_operand" "")))
11151    (clobber (reg:CC FLAGS_REG))]
11152   ""
11153   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11154
11155 (define_insn "*ashlsi3_1"
11156   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11157         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11158                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11159    (clobber (reg:CC FLAGS_REG))]
11160   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11161 {
11162   switch (get_attr_type (insn))
11163     {
11164     case TYPE_ALU:
11165       gcc_assert (operands[2] == const1_rtx);
11166       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11167       return "add{l}\t%0, %0";
11168
11169     case TYPE_LEA:
11170       return "#";
11171
11172     default:
11173       if (REG_P (operands[2]))
11174         return "sal{l}\t{%b2, %0|%0, %b2}";
11175       else if (operands[2] == const1_rtx
11176                && (TARGET_SHIFT1 || optimize_size))
11177         return "sal{l}\t%0";
11178       else
11179         return "sal{l}\t{%2, %0|%0, %2}";
11180     }
11181 }
11182   [(set (attr "type")
11183      (cond [(eq_attr "alternative" "1")
11184               (const_string "lea")
11185             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11186                           (const_int 0))
11187                       (match_operand 0 "register_operand" ""))
11188                  (match_operand 2 "const1_operand" ""))
11189               (const_string "alu")
11190            ]
11191            (const_string "ishift")))
11192    (set_attr "mode" "SI")])
11193
11194 ;; Convert lea to the lea pattern to avoid flags dependency.
11195 (define_split
11196   [(set (match_operand 0 "register_operand" "")
11197         (ashift (match_operand 1 "index_register_operand" "")
11198                 (match_operand:QI 2 "const_int_operand" "")))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "reload_completed
11201    && true_regnum (operands[0]) != true_regnum (operands[1])
11202    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11203   [(const_int 0)]
11204 {
11205   rtx pat;
11206   enum machine_mode mode = GET_MODE (operands[0]);
11207
11208   if (GET_MODE_SIZE (mode) < 4)
11209     operands[0] = gen_lowpart (SImode, operands[0]);
11210   if (mode != Pmode)
11211     operands[1] = gen_lowpart (Pmode, operands[1]);
11212   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11213
11214   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11215   if (Pmode != SImode)
11216     pat = gen_rtx_SUBREG (SImode, pat, 0);
11217   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11218   DONE;
11219 })
11220
11221 ;; Rare case of shifting RSP is handled by generating move and shift
11222 (define_split
11223   [(set (match_operand 0 "register_operand" "")
11224         (ashift (match_operand 1 "register_operand" "")
11225                 (match_operand:QI 2 "const_int_operand" "")))
11226    (clobber (reg:CC FLAGS_REG))]
11227   "reload_completed
11228    && true_regnum (operands[0]) != true_regnum (operands[1])"
11229   [(const_int 0)]
11230 {
11231   rtx pat, clob;
11232   emit_move_insn (operands[0], operands[1]);
11233   pat = gen_rtx_SET (VOIDmode, operands[0],
11234                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11235                                      operands[0], operands[2]));
11236   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11237   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11238   DONE;
11239 })
11240
11241 (define_insn "*ashlsi3_1_zext"
11242   [(set (match_operand:DI 0 "register_operand" "=r,r")
11243         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11244                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11245    (clobber (reg:CC FLAGS_REG))]
11246   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11247 {
11248   switch (get_attr_type (insn))
11249     {
11250     case TYPE_ALU:
11251       gcc_assert (operands[2] == const1_rtx);
11252       return "add{l}\t%k0, %k0";
11253
11254     case TYPE_LEA:
11255       return "#";
11256
11257     default:
11258       if (REG_P (operands[2]))
11259         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11260       else if (operands[2] == const1_rtx
11261                && (TARGET_SHIFT1 || optimize_size))
11262         return "sal{l}\t%k0";
11263       else
11264         return "sal{l}\t{%2, %k0|%k0, %2}";
11265     }
11266 }
11267   [(set (attr "type")
11268      (cond [(eq_attr "alternative" "1")
11269               (const_string "lea")
11270             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11271                      (const_int 0))
11272                  (match_operand 2 "const1_operand" ""))
11273               (const_string "alu")
11274            ]
11275            (const_string "ishift")))
11276    (set_attr "mode" "SI")])
11277
11278 ;; Convert lea to the lea pattern to avoid flags dependency.
11279 (define_split
11280   [(set (match_operand:DI 0 "register_operand" "")
11281         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11282                                 (match_operand:QI 2 "const_int_operand" ""))))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && reload_completed
11285    && true_regnum (operands[0]) != true_regnum (operands[1])"
11286   [(set (match_dup 0) (zero_extend:DI
11287                         (subreg:SI (mult:SI (match_dup 1)
11288                                             (match_dup 2)) 0)))]
11289 {
11290   operands[1] = gen_lowpart (Pmode, operands[1]);
11291   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11292 })
11293
11294 ;; This pattern can't accept a variable shift count, since shifts by
11295 ;; zero don't affect the flags.  We assume that shifts by constant
11296 ;; zero are optimized away.
11297 (define_insn "*ashlsi3_cmp"
11298   [(set (reg FLAGS_REG)
11299         (compare
11300           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11302           (const_int 0)))
11303    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11304         (ashift:SI (match_dup 1) (match_dup 2)))]
11305    "(optimize_size
11306      || !TARGET_PARTIAL_FLAG_REG_STALL
11307      || (operands[2] == const1_rtx
11308          && (TARGET_SHIFT1
11309              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11310    && ix86_match_ccmode (insn, CCGOCmode)
11311    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11312 {
11313   switch (get_attr_type (insn))
11314     {
11315     case TYPE_ALU:
11316       gcc_assert (operands[2] == const1_rtx);
11317       return "add{l}\t%0, %0";
11318
11319     default:
11320       if (REG_P (operands[2]))
11321         return "sal{l}\t{%b2, %0|%0, %b2}";
11322       else if (operands[2] == const1_rtx
11323                && (TARGET_SHIFT1 || optimize_size))
11324         return "sal{l}\t%0";
11325       else
11326         return "sal{l}\t{%2, %0|%0, %2}";
11327     }
11328 }
11329   [(set (attr "type")
11330      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11331                           (const_int 0))
11332                       (match_operand 0 "register_operand" ""))
11333                  (match_operand 2 "const1_operand" ""))
11334               (const_string "alu")
11335            ]
11336            (const_string "ishift")))
11337    (set_attr "mode" "SI")])
11338
11339 (define_insn "*ashlsi3_cconly"
11340   [(set (reg FLAGS_REG)
11341         (compare
11342           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11343                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11344           (const_int 0)))
11345    (clobber (match_scratch:SI 0 "=r"))]
11346   "(optimize_size
11347     || !TARGET_PARTIAL_FLAG_REG_STALL
11348     || (operands[2] == const1_rtx
11349         && (TARGET_SHIFT1
11350             || TARGET_DOUBLE_WITH_ADD)))
11351    && ix86_match_ccmode (insn, CCGOCmode)
11352    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11353 {
11354   switch (get_attr_type (insn))
11355     {
11356     case TYPE_ALU:
11357       gcc_assert (operands[2] == const1_rtx);
11358       return "add{l}\t%0, %0";
11359
11360     default:
11361       if (REG_P (operands[2]))
11362         return "sal{l}\t{%b2, %0|%0, %b2}";
11363       else if (operands[2] == const1_rtx
11364                && (TARGET_SHIFT1 || optimize_size))
11365         return "sal{l}\t%0";
11366       else
11367         return "sal{l}\t{%2, %0|%0, %2}";
11368     }
11369 }
11370   [(set (attr "type")
11371      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11372                           (const_int 0))
11373                       (match_operand 0 "register_operand" ""))
11374                  (match_operand 2 "const1_operand" ""))
11375               (const_string "alu")
11376            ]
11377            (const_string "ishift")))
11378    (set_attr "mode" "SI")])
11379
11380 (define_insn "*ashlsi3_cmp_zext"
11381   [(set (reg FLAGS_REG)
11382         (compare
11383           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11384                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11385           (const_int 0)))
11386    (set (match_operand:DI 0 "register_operand" "=r")
11387         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11388   "TARGET_64BIT
11389    && (optimize_size
11390        || !TARGET_PARTIAL_FLAG_REG_STALL
11391        || (operands[2] == const1_rtx
11392            && (TARGET_SHIFT1
11393                || TARGET_DOUBLE_WITH_ADD)))
11394    && ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11396 {
11397   switch (get_attr_type (insn))
11398     {
11399     case TYPE_ALU:
11400       gcc_assert (operands[2] == const1_rtx);
11401       return "add{l}\t%k0, %k0";
11402
11403     default:
11404       if (REG_P (operands[2]))
11405         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11406       else if (operands[2] == const1_rtx
11407                && (TARGET_SHIFT1 || optimize_size))
11408         return "sal{l}\t%k0";
11409       else
11410         return "sal{l}\t{%2, %k0|%k0, %2}";
11411     }
11412 }
11413   [(set (attr "type")
11414      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11415                      (const_int 0))
11416                  (match_operand 2 "const1_operand" ""))
11417               (const_string "alu")
11418            ]
11419            (const_string "ishift")))
11420    (set_attr "mode" "SI")])
11421
11422 (define_expand "ashlhi3"
11423   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11424         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11425                    (match_operand:QI 2 "nonmemory_operand" "")))
11426    (clobber (reg:CC FLAGS_REG))]
11427   "TARGET_HIMODE_MATH"
11428   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11429
11430 (define_insn "*ashlhi3_1_lea"
11431   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11432         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11433                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11434    (clobber (reg:CC FLAGS_REG))]
11435   "!TARGET_PARTIAL_REG_STALL
11436    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11437 {
11438   switch (get_attr_type (insn))
11439     {
11440     case TYPE_LEA:
11441       return "#";
11442     case TYPE_ALU:
11443       gcc_assert (operands[2] == const1_rtx);
11444       return "add{w}\t%0, %0";
11445
11446     default:
11447       if (REG_P (operands[2]))
11448         return "sal{w}\t{%b2, %0|%0, %b2}";
11449       else if (operands[2] == const1_rtx
11450                && (TARGET_SHIFT1 || optimize_size))
11451         return "sal{w}\t%0";
11452       else
11453         return "sal{w}\t{%2, %0|%0, %2}";
11454     }
11455 }
11456   [(set (attr "type")
11457      (cond [(eq_attr "alternative" "1")
11458               (const_string "lea")
11459             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11460                           (const_int 0))
11461                       (match_operand 0 "register_operand" ""))
11462                  (match_operand 2 "const1_operand" ""))
11463               (const_string "alu")
11464            ]
11465            (const_string "ishift")))
11466    (set_attr "mode" "HI,SI")])
11467
11468 (define_insn "*ashlhi3_1"
11469   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11470         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11471                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11472    (clobber (reg:CC FLAGS_REG))]
11473   "TARGET_PARTIAL_REG_STALL
11474    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11475 {
11476   switch (get_attr_type (insn))
11477     {
11478     case TYPE_ALU:
11479       gcc_assert (operands[2] == const1_rtx);
11480       return "add{w}\t%0, %0";
11481
11482     default:
11483       if (REG_P (operands[2]))
11484         return "sal{w}\t{%b2, %0|%0, %b2}";
11485       else if (operands[2] == const1_rtx
11486                && (TARGET_SHIFT1 || optimize_size))
11487         return "sal{w}\t%0";
11488       else
11489         return "sal{w}\t{%2, %0|%0, %2}";
11490     }
11491 }
11492   [(set (attr "type")
11493      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11494                           (const_int 0))
11495                       (match_operand 0 "register_operand" ""))
11496                  (match_operand 2 "const1_operand" ""))
11497               (const_string "alu")
11498            ]
11499            (const_string "ishift")))
11500    (set_attr "mode" "HI")])
11501
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags.  We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*ashlhi3_cmp"
11506   [(set (reg FLAGS_REG)
11507         (compare
11508           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11509                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11510           (const_int 0)))
11511    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11512         (ashift:HI (match_dup 1) (match_dup 2)))]
11513   "(optimize_size
11514     || !TARGET_PARTIAL_FLAG_REG_STALL
11515     || (operands[2] == const1_rtx
11516         && (TARGET_SHIFT1
11517             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11518    && ix86_match_ccmode (insn, CCGOCmode)
11519    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11520 {
11521   switch (get_attr_type (insn))
11522     {
11523     case TYPE_ALU:
11524       gcc_assert (operands[2] == const1_rtx);
11525       return "add{w}\t%0, %0";
11526
11527     default:
11528       if (REG_P (operands[2]))
11529         return "sal{w}\t{%b2, %0|%0, %b2}";
11530       else if (operands[2] == const1_rtx
11531                && (TARGET_SHIFT1 || optimize_size))
11532         return "sal{w}\t%0";
11533       else
11534         return "sal{w}\t{%2, %0|%0, %2}";
11535     }
11536 }
11537   [(set (attr "type")
11538      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11539                           (const_int 0))
11540                       (match_operand 0 "register_operand" ""))
11541                  (match_operand 2 "const1_operand" ""))
11542               (const_string "alu")
11543            ]
11544            (const_string "ishift")))
11545    (set_attr "mode" "HI")])
11546
11547 (define_insn "*ashlhi3_cconly"
11548   [(set (reg FLAGS_REG)
11549         (compare
11550           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11551                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11552           (const_int 0)))
11553    (clobber (match_scratch:HI 0 "=r"))]
11554   "(optimize_size
11555     || !TARGET_PARTIAL_FLAG_REG_STALL
11556     || (operands[2] == const1_rtx
11557         && (TARGET_SHIFT1
11558             || TARGET_DOUBLE_WITH_ADD)))
11559    && ix86_match_ccmode (insn, CCGOCmode)
11560    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11561 {
11562   switch (get_attr_type (insn))
11563     {
11564     case TYPE_ALU:
11565       gcc_assert (operands[2] == const1_rtx);
11566       return "add{w}\t%0, %0";
11567
11568     default:
11569       if (REG_P (operands[2]))
11570         return "sal{w}\t{%b2, %0|%0, %b2}";
11571       else if (operands[2] == const1_rtx
11572                && (TARGET_SHIFT1 || optimize_size))
11573         return "sal{w}\t%0";
11574       else
11575         return "sal{w}\t{%2, %0|%0, %2}";
11576     }
11577 }
11578   [(set (attr "type")
11579      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11580                           (const_int 0))
11581                       (match_operand 0 "register_operand" ""))
11582                  (match_operand 2 "const1_operand" ""))
11583               (const_string "alu")
11584            ]
11585            (const_string "ishift")))
11586    (set_attr "mode" "HI")])
11587
11588 (define_expand "ashlqi3"
11589   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11590         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11591                    (match_operand:QI 2 "nonmemory_operand" "")))
11592    (clobber (reg:CC FLAGS_REG))]
11593   "TARGET_QIMODE_MATH"
11594   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11595
11596 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11597
11598 (define_insn "*ashlqi3_1_lea"
11599   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11600         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11601                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11602    (clobber (reg:CC FLAGS_REG))]
11603   "!TARGET_PARTIAL_REG_STALL
11604    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11605 {
11606   switch (get_attr_type (insn))
11607     {
11608     case TYPE_LEA:
11609       return "#";
11610     case TYPE_ALU:
11611       gcc_assert (operands[2] == const1_rtx);
11612       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11613         return "add{l}\t%k0, %k0";
11614       else
11615         return "add{b}\t%0, %0";
11616
11617     default:
11618       if (REG_P (operands[2]))
11619         {
11620           if (get_attr_mode (insn) == MODE_SI)
11621             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11622           else
11623             return "sal{b}\t{%b2, %0|%0, %b2}";
11624         }
11625       else if (operands[2] == const1_rtx
11626                && (TARGET_SHIFT1 || optimize_size))
11627         {
11628           if (get_attr_mode (insn) == MODE_SI)
11629             return "sal{l}\t%0";
11630           else
11631             return "sal{b}\t%0";
11632         }
11633       else
11634         {
11635           if (get_attr_mode (insn) == MODE_SI)
11636             return "sal{l}\t{%2, %k0|%k0, %2}";
11637           else
11638             return "sal{b}\t{%2, %0|%0, %2}";
11639         }
11640     }
11641 }
11642   [(set (attr "type")
11643      (cond [(eq_attr "alternative" "2")
11644               (const_string "lea")
11645             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11646                           (const_int 0))
11647                       (match_operand 0 "register_operand" ""))
11648                  (match_operand 2 "const1_operand" ""))
11649               (const_string "alu")
11650            ]
11651            (const_string "ishift")))
11652    (set_attr "mode" "QI,SI,SI")])
11653
11654 (define_insn "*ashlqi3_1"
11655   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11656         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11657                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11658    (clobber (reg:CC FLAGS_REG))]
11659   "TARGET_PARTIAL_REG_STALL
11660    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11661 {
11662   switch (get_attr_type (insn))
11663     {
11664     case TYPE_ALU:
11665       gcc_assert (operands[2] == const1_rtx);
11666       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11667         return "add{l}\t%k0, %k0";
11668       else
11669         return "add{b}\t%0, %0";
11670
11671     default:
11672       if (REG_P (operands[2]))
11673         {
11674           if (get_attr_mode (insn) == MODE_SI)
11675             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11676           else
11677             return "sal{b}\t{%b2, %0|%0, %b2}";
11678         }
11679       else if (operands[2] == const1_rtx
11680                && (TARGET_SHIFT1 || optimize_size))
11681         {
11682           if (get_attr_mode (insn) == MODE_SI)
11683             return "sal{l}\t%0";
11684           else
11685             return "sal{b}\t%0";
11686         }
11687       else
11688         {
11689           if (get_attr_mode (insn) == MODE_SI)
11690             return "sal{l}\t{%2, %k0|%k0, %2}";
11691           else
11692             return "sal{b}\t{%2, %0|%0, %2}";
11693         }
11694     }
11695 }
11696   [(set (attr "type")
11697      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11698                           (const_int 0))
11699                       (match_operand 0 "register_operand" ""))
11700                  (match_operand 2 "const1_operand" ""))
11701               (const_string "alu")
11702            ]
11703            (const_string "ishift")))
11704    (set_attr "mode" "QI,SI")])
11705
11706 ;; This pattern can't accept a variable shift count, since shifts by
11707 ;; zero don't affect the flags.  We assume that shifts by constant
11708 ;; zero are optimized away.
11709 (define_insn "*ashlqi3_cmp"
11710   [(set (reg FLAGS_REG)
11711         (compare
11712           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11713                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11714           (const_int 0)))
11715    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11716         (ashift:QI (match_dup 1) (match_dup 2)))]
11717   "(optimize_size
11718     || !TARGET_PARTIAL_FLAG_REG_STALL
11719     || (operands[2] == const1_rtx
11720         && (TARGET_SHIFT1
11721             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11722    && ix86_match_ccmode (insn, CCGOCmode)
11723    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11724 {
11725   switch (get_attr_type (insn))
11726     {
11727     case TYPE_ALU:
11728       gcc_assert (operands[2] == const1_rtx);
11729       return "add{b}\t%0, %0";
11730
11731     default:
11732       if (REG_P (operands[2]))
11733         return "sal{b}\t{%b2, %0|%0, %b2}";
11734       else if (operands[2] == const1_rtx
11735                && (TARGET_SHIFT1 || optimize_size))
11736         return "sal{b}\t%0";
11737       else
11738         return "sal{b}\t{%2, %0|%0, %2}";
11739     }
11740 }
11741   [(set (attr "type")
11742      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11743                           (const_int 0))
11744                       (match_operand 0 "register_operand" ""))
11745                  (match_operand 2 "const1_operand" ""))
11746               (const_string "alu")
11747            ]
11748            (const_string "ishift")))
11749    (set_attr "mode" "QI")])
11750
11751 (define_insn "*ashlqi3_cconly"
11752   [(set (reg FLAGS_REG)
11753         (compare
11754           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11755                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11756           (const_int 0)))
11757    (clobber (match_scratch:QI 0 "=q"))]
11758   "(optimize_size
11759     || !TARGET_PARTIAL_FLAG_REG_STALL
11760     || (operands[2] == const1_rtx
11761         && (TARGET_SHIFT1
11762             || TARGET_DOUBLE_WITH_ADD)))
11763    && ix86_match_ccmode (insn, CCGOCmode)
11764    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11765 {
11766   switch (get_attr_type (insn))
11767     {
11768     case TYPE_ALU:
11769       gcc_assert (operands[2] == const1_rtx);
11770       return "add{b}\t%0, %0";
11771
11772     default:
11773       if (REG_P (operands[2]))
11774         return "sal{b}\t{%b2, %0|%0, %b2}";
11775       else if (operands[2] == const1_rtx
11776                && (TARGET_SHIFT1 || optimize_size))
11777         return "sal{b}\t%0";
11778       else
11779         return "sal{b}\t{%2, %0|%0, %2}";
11780     }
11781 }
11782   [(set (attr "type")
11783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11784                           (const_int 0))
11785                       (match_operand 0 "register_operand" ""))
11786                  (match_operand 2 "const1_operand" ""))
11787               (const_string "alu")
11788            ]
11789            (const_string "ishift")))
11790    (set_attr "mode" "QI")])
11791
11792 ;; See comment above `ashldi3' about how this works.
11793
11794 (define_expand "ashrti3"
11795   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11796                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11797                                 (match_operand:QI 2 "nonmemory_operand" "")))
11798               (clobber (reg:CC FLAGS_REG))])]
11799   "TARGET_64BIT"
11800 {
11801   if (! immediate_operand (operands[2], QImode))
11802     {
11803       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11804       DONE;
11805     }
11806   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11807   DONE;
11808 })
11809
11810 (define_insn "ashrti3_1"
11811   [(set (match_operand:TI 0 "register_operand" "=r")
11812         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11813                      (match_operand:QI 2 "register_operand" "c")))
11814    (clobber (match_scratch:DI 3 "=&r"))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "TARGET_64BIT"
11817   "#"
11818   [(set_attr "type" "multi")])
11819
11820 (define_insn "*ashrti3_2"
11821   [(set (match_operand:TI 0 "register_operand" "=r")
11822         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11823                      (match_operand:QI 2 "immediate_operand" "O")))
11824    (clobber (reg:CC FLAGS_REG))]
11825   "TARGET_64BIT"
11826   "#"
11827   [(set_attr "type" "multi")])
11828
11829 (define_split
11830   [(set (match_operand:TI 0 "register_operand" "")
11831         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11832                      (match_operand:QI 2 "register_operand" "")))
11833    (clobber (match_scratch:DI 3 ""))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "TARGET_64BIT && reload_completed"
11836   [(const_int 0)]
11837   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11838
11839 (define_split
11840   [(set (match_operand:TI 0 "register_operand" "")
11841         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11842                      (match_operand:QI 2 "immediate_operand" "")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "TARGET_64BIT && reload_completed"
11845   [(const_int 0)]
11846   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11847
11848 (define_insn "x86_64_shrd"
11849   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11850         (ior:DI (ashiftrt:DI (match_dup 0)
11851                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11852                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11853                   (minus:QI (const_int 64) (match_dup 2)))))
11854    (clobber (reg:CC FLAGS_REG))]
11855   "TARGET_64BIT"
11856   "@
11857    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11858    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11859   [(set_attr "type" "ishift")
11860    (set_attr "prefix_0f" "1")
11861    (set_attr "mode" "DI")
11862    (set_attr "athlon_decode" "vector")
11863    (set_attr "amdfam10_decode" "vector")])
11864
11865 (define_expand "ashrdi3"
11866   [(set (match_operand:DI 0 "shiftdi_operand" "")
11867         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11868                      (match_operand:QI 2 "nonmemory_operand" "")))]
11869   ""
11870   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11871
11872 (define_insn "*ashrdi3_63_rex64"
11873   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11874         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11875                      (match_operand:DI 2 "const_int_operand" "i,i")))
11876    (clobber (reg:CC FLAGS_REG))]
11877   "TARGET_64BIT && INTVAL (operands[2]) == 63
11878    && (TARGET_USE_CLTD || optimize_size)
11879    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11880   "@
11881    {cqto|cqo}
11882    sar{q}\t{%2, %0|%0, %2}"
11883   [(set_attr "type" "imovx,ishift")
11884    (set_attr "prefix_0f" "0,*")
11885    (set_attr "length_immediate" "0,*")
11886    (set_attr "modrm" "0,1")
11887    (set_attr "mode" "DI")])
11888
11889 (define_insn "*ashrdi3_1_one_bit_rex64"
11890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11891         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11892                      (match_operand:QI 2 "const1_operand" "")))
11893    (clobber (reg:CC FLAGS_REG))]
11894   "TARGET_64BIT
11895    && (TARGET_SHIFT1 || optimize_size)
11896    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11897   "sar{q}\t%0"
11898   [(set_attr "type" "ishift")
11899    (set (attr "length")
11900      (if_then_else (match_operand:DI 0 "register_operand" "")
11901         (const_string "2")
11902         (const_string "*")))])
11903
11904 (define_insn "*ashrdi3_1_rex64"
11905   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11906         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11907                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11910   "@
11911    sar{q}\t{%2, %0|%0, %2}
11912    sar{q}\t{%b2, %0|%0, %b2}"
11913   [(set_attr "type" "ishift")
11914    (set_attr "mode" "DI")])
11915
11916 ;; This pattern can't accept a variable shift count, since shifts by
11917 ;; zero don't affect the flags.  We assume that shifts by constant
11918 ;; zero are optimized away.
11919 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11920   [(set (reg FLAGS_REG)
11921         (compare
11922           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11923                        (match_operand:QI 2 "const1_operand" ""))
11924           (const_int 0)))
11925    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11926         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11927   "TARGET_64BIT
11928    && (TARGET_SHIFT1 || optimize_size)
11929    && ix86_match_ccmode (insn, CCGOCmode)
11930    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11931   "sar{q}\t%0"
11932   [(set_attr "type" "ishift")
11933    (set (attr "length")
11934      (if_then_else (match_operand:DI 0 "register_operand" "")
11935         (const_string "2")
11936         (const_string "*")))])
11937
11938 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11939   [(set (reg FLAGS_REG)
11940         (compare
11941           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11942                        (match_operand:QI 2 "const1_operand" ""))
11943           (const_int 0)))
11944    (clobber (match_scratch:DI 0 "=r"))]
11945   "TARGET_64BIT
11946    && (TARGET_SHIFT1 || optimize_size)
11947    && ix86_match_ccmode (insn, CCGOCmode)
11948    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11949   "sar{q}\t%0"
11950   [(set_attr "type" "ishift")
11951    (set_attr "length" "2")])
11952
11953 ;; This pattern can't accept a variable shift count, since shifts by
11954 ;; zero don't affect the flags.  We assume that shifts by constant
11955 ;; zero are optimized away.
11956 (define_insn "*ashrdi3_cmp_rex64"
11957   [(set (reg FLAGS_REG)
11958         (compare
11959           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11960                        (match_operand:QI 2 "const_int_operand" "n"))
11961           (const_int 0)))
11962    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11963         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11964   "TARGET_64BIT
11965    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11966    && ix86_match_ccmode (insn, CCGOCmode)
11967    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11968   "sar{q}\t{%2, %0|%0, %2}"
11969   [(set_attr "type" "ishift")
11970    (set_attr "mode" "DI")])
11971
11972 (define_insn "*ashrdi3_cconly_rex64"
11973   [(set (reg FLAGS_REG)
11974         (compare
11975           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976                        (match_operand:QI 2 "const_int_operand" "n"))
11977           (const_int 0)))
11978    (clobber (match_scratch:DI 0 "=r"))]
11979   "TARGET_64BIT
11980    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11981    && ix86_match_ccmode (insn, CCGOCmode)
11982    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11983   "sar{q}\t{%2, %0|%0, %2}"
11984   [(set_attr "type" "ishift")
11985    (set_attr "mode" "DI")])
11986
11987 (define_insn "*ashrdi3_1"
11988   [(set (match_operand:DI 0 "register_operand" "=r")
11989         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11990                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11991    (clobber (reg:CC FLAGS_REG))]
11992   "!TARGET_64BIT"
11993   "#"
11994   [(set_attr "type" "multi")])
11995
11996 ;; By default we don't ask for a scratch register, because when DImode
11997 ;; values are manipulated, registers are already at a premium.  But if
11998 ;; we have one handy, we won't turn it away.
11999 (define_peephole2
12000   [(match_scratch:SI 3 "r")
12001    (parallel [(set (match_operand:DI 0 "register_operand" "")
12002                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12003                                 (match_operand:QI 2 "nonmemory_operand" "")))
12004               (clobber (reg:CC FLAGS_REG))])
12005    (match_dup 3)]
12006   "!TARGET_64BIT && TARGET_CMOVE"
12007   [(const_int 0)]
12008   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12009
12010 (define_split
12011   [(set (match_operand:DI 0 "register_operand" "")
12012         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12013                      (match_operand:QI 2 "nonmemory_operand" "")))
12014    (clobber (reg:CC FLAGS_REG))]
12015   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12016                      ? epilogue_completed : reload_completed)"
12017   [(const_int 0)]
12018   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12019
12020 (define_insn "x86_shrd_1"
12021   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12022         (ior:SI (ashiftrt:SI (match_dup 0)
12023                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12024                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12025                   (minus:QI (const_int 32) (match_dup 2)))))
12026    (clobber (reg:CC FLAGS_REG))]
12027   ""
12028   "@
12029    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12030    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12031   [(set_attr "type" "ishift")
12032    (set_attr "prefix_0f" "1")
12033    (set_attr "pent_pair" "np")
12034    (set_attr "mode" "SI")])
12035
12036 (define_expand "x86_shift_adj_3"
12037   [(use (match_operand:SI 0 "register_operand" ""))
12038    (use (match_operand:SI 1 "register_operand" ""))
12039    (use (match_operand:QI 2 "register_operand" ""))]
12040   ""
12041 {
12042   rtx label = gen_label_rtx ();
12043   rtx tmp;
12044
12045   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12046
12047   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12048   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12049   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12050                               gen_rtx_LABEL_REF (VOIDmode, label),
12051                               pc_rtx);
12052   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12053   JUMP_LABEL (tmp) = label;
12054
12055   emit_move_insn (operands[0], operands[1]);
12056   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12057
12058   emit_label (label);
12059   LABEL_NUSES (label) = 1;
12060
12061   DONE;
12062 })
12063
12064 (define_insn "ashrsi3_31"
12065   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12066         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12067                      (match_operand:SI 2 "const_int_operand" "i,i")))
12068    (clobber (reg:CC FLAGS_REG))]
12069   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12070    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12071   "@
12072    {cltd|cdq}
12073    sar{l}\t{%2, %0|%0, %2}"
12074   [(set_attr "type" "imovx,ishift")
12075    (set_attr "prefix_0f" "0,*")
12076    (set_attr "length_immediate" "0,*")
12077    (set_attr "modrm" "0,1")
12078    (set_attr "mode" "SI")])
12079
12080 (define_insn "*ashrsi3_31_zext"
12081   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12082         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12083                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12084    (clobber (reg:CC FLAGS_REG))]
12085   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12086    && INTVAL (operands[2]) == 31
12087    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12088   "@
12089    {cltd|cdq}
12090    sar{l}\t{%2, %k0|%k0, %2}"
12091   [(set_attr "type" "imovx,ishift")
12092    (set_attr "prefix_0f" "0,*")
12093    (set_attr "length_immediate" "0,*")
12094    (set_attr "modrm" "0,1")
12095    (set_attr "mode" "SI")])
12096
12097 (define_expand "ashrsi3"
12098   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12099         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12100                      (match_operand:QI 2 "nonmemory_operand" "")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   ""
12103   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12104
12105 (define_insn "*ashrsi3_1_one_bit"
12106   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12107         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12108                      (match_operand:QI 2 "const1_operand" "")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "(TARGET_SHIFT1 || optimize_size)
12111    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12112   "sar{l}\t%0"
12113   [(set_attr "type" "ishift")
12114    (set (attr "length")
12115      (if_then_else (match_operand:SI 0 "register_operand" "")
12116         (const_string "2")
12117         (const_string "*")))])
12118
12119 (define_insn "*ashrsi3_1_one_bit_zext"
12120   [(set (match_operand:DI 0 "register_operand" "=r")
12121         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12122                                      (match_operand:QI 2 "const1_operand" ""))))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "TARGET_64BIT
12125    && (TARGET_SHIFT1 || optimize_size)
12126    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12127   "sar{l}\t%k0"
12128   [(set_attr "type" "ishift")
12129    (set_attr "length" "2")])
12130
12131 (define_insn "*ashrsi3_1"
12132   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12133         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12134                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12135    (clobber (reg:CC FLAGS_REG))]
12136   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12137   "@
12138    sar{l}\t{%2, %0|%0, %2}
12139    sar{l}\t{%b2, %0|%0, %b2}"
12140   [(set_attr "type" "ishift")
12141    (set_attr "mode" "SI")])
12142
12143 (define_insn "*ashrsi3_1_zext"
12144   [(set (match_operand:DI 0 "register_operand" "=r,r")
12145         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12146                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12147    (clobber (reg:CC FLAGS_REG))]
12148   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12149   "@
12150    sar{l}\t{%2, %k0|%k0, %2}
12151    sar{l}\t{%b2, %k0|%k0, %b2}"
12152   [(set_attr "type" "ishift")
12153    (set_attr "mode" "SI")])
12154
12155 ;; This pattern can't accept a variable shift count, since shifts by
12156 ;; zero don't affect the flags.  We assume that shifts by constant
12157 ;; zero are optimized away.
12158 (define_insn "*ashrsi3_one_bit_cmp"
12159   [(set (reg FLAGS_REG)
12160         (compare
12161           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162                        (match_operand:QI 2 "const1_operand" ""))
12163           (const_int 0)))
12164    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12165         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12166   "(TARGET_SHIFT1 || optimize_size)
12167    && ix86_match_ccmode (insn, CCGOCmode)
12168    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12169   "sar{l}\t%0"
12170   [(set_attr "type" "ishift")
12171    (set (attr "length")
12172      (if_then_else (match_operand:SI 0 "register_operand" "")
12173         (const_string "2")
12174         (const_string "*")))])
12175
12176 (define_insn "*ashrsi3_one_bit_cconly"
12177   [(set (reg FLAGS_REG)
12178         (compare
12179           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180                        (match_operand:QI 2 "const1_operand" ""))
12181           (const_int 0)))
12182    (clobber (match_scratch:SI 0 "=r"))]
12183   "(TARGET_SHIFT1 || optimize_size)
12184    && ix86_match_ccmode (insn, CCGOCmode)
12185    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12186   "sar{l}\t%0"
12187   [(set_attr "type" "ishift")
12188    (set_attr "length" "2")])
12189
12190 (define_insn "*ashrsi3_one_bit_cmp_zext"
12191   [(set (reg FLAGS_REG)
12192         (compare
12193           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12194                        (match_operand:QI 2 "const1_operand" ""))
12195           (const_int 0)))
12196    (set (match_operand:DI 0 "register_operand" "=r")
12197         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12198   "TARGET_64BIT
12199    && (TARGET_SHIFT1 || optimize_size)
12200    && ix86_match_ccmode (insn, CCmode)
12201    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12202   "sar{l}\t%k0"
12203   [(set_attr "type" "ishift")
12204    (set_attr "length" "2")])
12205
12206 ;; This pattern can't accept a variable shift count, since shifts by
12207 ;; zero don't affect the flags.  We assume that shifts by constant
12208 ;; zero are optimized away.
12209 (define_insn "*ashrsi3_cmp"
12210   [(set (reg FLAGS_REG)
12211         (compare
12212           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12213                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12214           (const_int 0)))
12215    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12216         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12217   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12218    && ix86_match_ccmode (insn, CCGOCmode)
12219    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12220   "sar{l}\t{%2, %0|%0, %2}"
12221   [(set_attr "type" "ishift")
12222    (set_attr "mode" "SI")])
12223
12224 (define_insn "*ashrsi3_cconly"
12225   [(set (reg FLAGS_REG)
12226         (compare
12227           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12229           (const_int 0)))
12230    (clobber (match_scratch:SI 0 "=r"))]
12231   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12232    && ix86_match_ccmode (insn, CCGOCmode)
12233    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12234   "sar{l}\t{%2, %0|%0, %2}"
12235   [(set_attr "type" "ishift")
12236    (set_attr "mode" "SI")])
12237
12238 (define_insn "*ashrsi3_cmp_zext"
12239   [(set (reg FLAGS_REG)
12240         (compare
12241           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12242                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12243           (const_int 0)))
12244    (set (match_operand:DI 0 "register_operand" "=r")
12245         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12246   "TARGET_64BIT
12247    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12248    && ix86_match_ccmode (insn, CCGOCmode)
12249    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12250   "sar{l}\t{%2, %k0|%k0, %2}"
12251   [(set_attr "type" "ishift")
12252    (set_attr "mode" "SI")])
12253
12254 (define_expand "ashrhi3"
12255   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12256         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12257                      (match_operand:QI 2 "nonmemory_operand" "")))
12258    (clobber (reg:CC FLAGS_REG))]
12259   "TARGET_HIMODE_MATH"
12260   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12261
12262 (define_insn "*ashrhi3_1_one_bit"
12263   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12264         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12265                      (match_operand:QI 2 "const1_operand" "")))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "(TARGET_SHIFT1 || optimize_size)
12268    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12269   "sar{w}\t%0"
12270   [(set_attr "type" "ishift")
12271    (set (attr "length")
12272      (if_then_else (match_operand 0 "register_operand" "")
12273         (const_string "2")
12274         (const_string "*")))])
12275
12276 (define_insn "*ashrhi3_1"
12277   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12278         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12279                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12280    (clobber (reg:CC FLAGS_REG))]
12281   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12282   "@
12283    sar{w}\t{%2, %0|%0, %2}
12284    sar{w}\t{%b2, %0|%0, %b2}"
12285   [(set_attr "type" "ishift")
12286    (set_attr "mode" "HI")])
12287
12288 ;; This pattern can't accept a variable shift count, since shifts by
12289 ;; zero don't affect the flags.  We assume that shifts by constant
12290 ;; zero are optimized away.
12291 (define_insn "*ashrhi3_one_bit_cmp"
12292   [(set (reg FLAGS_REG)
12293         (compare
12294           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12295                        (match_operand:QI 2 "const1_operand" ""))
12296           (const_int 0)))
12297    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12298         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12299   "(TARGET_SHIFT1 || optimize_size)
12300    && ix86_match_ccmode (insn, CCGOCmode)
12301    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12302   "sar{w}\t%0"
12303   [(set_attr "type" "ishift")
12304    (set (attr "length")
12305      (if_then_else (match_operand 0 "register_operand" "")
12306         (const_string "2")
12307         (const_string "*")))])
12308
12309 (define_insn "*ashrhi3_one_bit_cconly"
12310   [(set (reg FLAGS_REG)
12311         (compare
12312           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12313                        (match_operand:QI 2 "const1_operand" ""))
12314           (const_int 0)))
12315    (clobber (match_scratch:HI 0 "=r"))]
12316   "(TARGET_SHIFT1 || optimize_size)
12317    && ix86_match_ccmode (insn, CCGOCmode)
12318    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12319   "sar{w}\t%0"
12320   [(set_attr "type" "ishift")
12321    (set_attr "length" "2")])
12322
12323 ;; This pattern can't accept a variable shift count, since shifts by
12324 ;; zero don't affect the flags.  We assume that shifts by constant
12325 ;; zero are optimized away.
12326 (define_insn "*ashrhi3_cmp"
12327   [(set (reg FLAGS_REG)
12328         (compare
12329           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12330                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331           (const_int 0)))
12332    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12333         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12334   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12335    && ix86_match_ccmode (insn, CCGOCmode)
12336    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12337   "sar{w}\t{%2, %0|%0, %2}"
12338   [(set_attr "type" "ishift")
12339    (set_attr "mode" "HI")])
12340
12341 (define_insn "*ashrhi3_cconly"
12342   [(set (reg FLAGS_REG)
12343         (compare
12344           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12345                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346           (const_int 0)))
12347    (clobber (match_scratch:HI 0 "=r"))]
12348   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12349    && ix86_match_ccmode (insn, CCGOCmode)
12350    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12351   "sar{w}\t{%2, %0|%0, %2}"
12352   [(set_attr "type" "ishift")
12353    (set_attr "mode" "HI")])
12354
12355 (define_expand "ashrqi3"
12356   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12357         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12358                      (match_operand:QI 2 "nonmemory_operand" "")))
12359    (clobber (reg:CC FLAGS_REG))]
12360   "TARGET_QIMODE_MATH"
12361   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12362
12363 (define_insn "*ashrqi3_1_one_bit"
12364   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12365         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12366                      (match_operand:QI 2 "const1_operand" "")))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "(TARGET_SHIFT1 || optimize_size)
12369    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12370   "sar{b}\t%0"
12371   [(set_attr "type" "ishift")
12372    (set (attr "length")
12373      (if_then_else (match_operand 0 "register_operand" "")
12374         (const_string "2")
12375         (const_string "*")))])
12376
12377 (define_insn "*ashrqi3_1_one_bit_slp"
12378   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12379         (ashiftrt:QI (match_dup 0)
12380                      (match_operand:QI 1 "const1_operand" "")))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12383    && (TARGET_SHIFT1 || optimize_size)
12384    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12385   "sar{b}\t%0"
12386   [(set_attr "type" "ishift1")
12387    (set (attr "length")
12388      (if_then_else (match_operand 0 "register_operand" "")
12389         (const_string "2")
12390         (const_string "*")))])
12391
12392 (define_insn "*ashrqi3_1"
12393   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12394         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12395                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12398   "@
12399    sar{b}\t{%2, %0|%0, %2}
12400    sar{b}\t{%b2, %0|%0, %b2}"
12401   [(set_attr "type" "ishift")
12402    (set_attr "mode" "QI")])
12403
12404 (define_insn "*ashrqi3_1_slp"
12405   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12406         (ashiftrt:QI (match_dup 0)
12407                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12410    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12411   "@
12412    sar{b}\t{%1, %0|%0, %1}
12413    sar{b}\t{%b1, %0|%0, %b1}"
12414   [(set_attr "type" "ishift1")
12415    (set_attr "mode" "QI")])
12416
12417 ;; This pattern can't accept a variable shift count, since shifts by
12418 ;; zero don't affect the flags.  We assume that shifts by constant
12419 ;; zero are optimized away.
12420 (define_insn "*ashrqi3_one_bit_cmp"
12421   [(set (reg FLAGS_REG)
12422         (compare
12423           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424                        (match_operand:QI 2 "const1_operand" "I"))
12425           (const_int 0)))
12426    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12428   "(TARGET_SHIFT1 || optimize_size)
12429    && ix86_match_ccmode (insn, CCGOCmode)
12430    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12431   "sar{b}\t%0"
12432   [(set_attr "type" "ishift")
12433    (set (attr "length")
12434      (if_then_else (match_operand 0 "register_operand" "")
12435         (const_string "2")
12436         (const_string "*")))])
12437
12438 (define_insn "*ashrqi3_one_bit_cconly"
12439   [(set (reg FLAGS_REG)
12440         (compare
12441           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12442                        (match_operand:QI 2 "const1_operand" "I"))
12443           (const_int 0)))
12444    (clobber (match_scratch:QI 0 "=q"))]
12445   "(TARGET_SHIFT1 || optimize_size)
12446    && ix86_match_ccmode (insn, CCGOCmode)
12447    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12448   "sar{b}\t%0"
12449   [(set_attr "type" "ishift")
12450    (set_attr "length" "2")])
12451
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags.  We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrqi3_cmp"
12456   [(set (reg FLAGS_REG)
12457         (compare
12458           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12460           (const_int 0)))
12461    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12462         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12463   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12464    && ix86_match_ccmode (insn, CCGOCmode)
12465    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12466   "sar{b}\t{%2, %0|%0, %2}"
12467   [(set_attr "type" "ishift")
12468    (set_attr "mode" "QI")])
12469
12470 (define_insn "*ashrqi3_cconly"
12471   [(set (reg FLAGS_REG)
12472         (compare
12473           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12474                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12475           (const_int 0)))
12476    (clobber (match_scratch:QI 0 "=q"))]
12477   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12478    && ix86_match_ccmode (insn, CCGOCmode)
12479    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12480   "sar{b}\t{%2, %0|%0, %2}"
12481   [(set_attr "type" "ishift")
12482    (set_attr "mode" "QI")])
12483
12484 \f
12485 ;; Logical shift instructions
12486
12487 ;; See comment above `ashldi3' about how this works.
12488
12489 (define_expand "lshrti3"
12490   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12491                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12492                                 (match_operand:QI 2 "nonmemory_operand" "")))
12493               (clobber (reg:CC FLAGS_REG))])]
12494   "TARGET_64BIT"
12495 {
12496   if (! immediate_operand (operands[2], QImode))
12497     {
12498       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12499       DONE;
12500     }
12501   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12502   DONE;
12503 })
12504
12505 (define_insn "lshrti3_1"
12506   [(set (match_operand:TI 0 "register_operand" "=r")
12507         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12508                      (match_operand:QI 2 "register_operand" "c")))
12509    (clobber (match_scratch:DI 3 "=&r"))
12510    (clobber (reg:CC FLAGS_REG))]
12511   "TARGET_64BIT"
12512   "#"
12513   [(set_attr "type" "multi")])
12514
12515 ;; This pattern must be defined before *lshrti3_2 to prevent
12516 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12517
12518 (define_insn "sse2_lshrti3"
12519   [(set (match_operand:TI 0 "register_operand" "=x")
12520         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12521                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12522   "TARGET_SSE2"
12523 {
12524   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12525   return "psrldq\t{%2, %0|%0, %2}";
12526 }
12527   [(set_attr "type" "sseishft")
12528    (set_attr "prefix_data16" "1")
12529    (set_attr "mode" "TI")])
12530
12531 (define_insn "*lshrti3_2"
12532   [(set (match_operand:TI 0 "register_operand" "=r")
12533         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12534                      (match_operand:QI 2 "immediate_operand" "O")))
12535    (clobber (reg:CC FLAGS_REG))]
12536   "TARGET_64BIT"
12537   "#"
12538   [(set_attr "type" "multi")])
12539
12540 (define_split
12541   [(set (match_operand:TI 0 "register_operand" "")
12542         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12543                      (match_operand:QI 2 "register_operand" "")))
12544    (clobber (match_scratch:DI 3 ""))
12545    (clobber (reg:CC FLAGS_REG))]
12546   "TARGET_64BIT && reload_completed"
12547   [(const_int 0)]
12548   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12549
12550 (define_split
12551   [(set (match_operand:TI 0 "register_operand" "")
12552         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12553                      (match_operand:QI 2 "immediate_operand" "")))
12554    (clobber (reg:CC FLAGS_REG))]
12555   "TARGET_64BIT && reload_completed"
12556   [(const_int 0)]
12557   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12558
12559 (define_expand "lshrdi3"
12560   [(set (match_operand:DI 0 "shiftdi_operand" "")
12561         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12562                      (match_operand:QI 2 "nonmemory_operand" "")))]
12563   ""
12564   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12565
12566 (define_insn "*lshrdi3_1_one_bit_rex64"
12567   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12568         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12569                      (match_operand:QI 2 "const1_operand" "")))
12570    (clobber (reg:CC FLAGS_REG))]
12571   "TARGET_64BIT
12572    && (TARGET_SHIFT1 || optimize_size)
12573    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12574   "shr{q}\t%0"
12575   [(set_attr "type" "ishift")
12576    (set (attr "length")
12577      (if_then_else (match_operand:DI 0 "register_operand" "")
12578         (const_string "2")
12579         (const_string "*")))])
12580
12581 (define_insn "*lshrdi3_1_rex64"
12582   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12583         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12584                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12585    (clobber (reg:CC FLAGS_REG))]
12586   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12587   "@
12588    shr{q}\t{%2, %0|%0, %2}
12589    shr{q}\t{%b2, %0|%0, %b2}"
12590   [(set_attr "type" "ishift")
12591    (set_attr "mode" "DI")])
12592
12593 ;; This pattern can't accept a variable shift count, since shifts by
12594 ;; zero don't affect the flags.  We assume that shifts by constant
12595 ;; zero are optimized away.
12596 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12597   [(set (reg FLAGS_REG)
12598         (compare
12599           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12600                        (match_operand:QI 2 "const1_operand" ""))
12601           (const_int 0)))
12602    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12603         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12604   "TARGET_64BIT
12605    && (TARGET_SHIFT1 || optimize_size)
12606    && ix86_match_ccmode (insn, CCGOCmode)
12607    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12608   "shr{q}\t%0"
12609   [(set_attr "type" "ishift")
12610    (set (attr "length")
12611      (if_then_else (match_operand:DI 0 "register_operand" "")
12612         (const_string "2")
12613         (const_string "*")))])
12614
12615 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12616   [(set (reg FLAGS_REG)
12617         (compare
12618           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12619                        (match_operand:QI 2 "const1_operand" ""))
12620           (const_int 0)))
12621    (clobber (match_scratch:DI 0 "=r"))]
12622   "TARGET_64BIT
12623    && (TARGET_SHIFT1 || optimize_size)
12624    && ix86_match_ccmode (insn, CCGOCmode)
12625    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12626   "shr{q}\t%0"
12627   [(set_attr "type" "ishift")
12628    (set_attr "length" "2")])
12629
12630 ;; This pattern can't accept a variable shift count, since shifts by
12631 ;; zero don't affect the flags.  We assume that shifts by constant
12632 ;; zero are optimized away.
12633 (define_insn "*lshrdi3_cmp_rex64"
12634   [(set (reg FLAGS_REG)
12635         (compare
12636           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12637                        (match_operand:QI 2 "const_int_operand" "e"))
12638           (const_int 0)))
12639    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12640         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12641   "TARGET_64BIT
12642    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12643    && ix86_match_ccmode (insn, CCGOCmode)
12644    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12645   "shr{q}\t{%2, %0|%0, %2}"
12646   [(set_attr "type" "ishift")
12647    (set_attr "mode" "DI")])
12648
12649 (define_insn "*lshrdi3_cconly_rex64"
12650   [(set (reg FLAGS_REG)
12651         (compare
12652           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653                        (match_operand:QI 2 "const_int_operand" "e"))
12654           (const_int 0)))
12655    (clobber (match_scratch:DI 0 "=r"))]
12656   "TARGET_64BIT
12657    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12658    && ix86_match_ccmode (insn, CCGOCmode)
12659    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12660   "shr{q}\t{%2, %0|%0, %2}"
12661   [(set_attr "type" "ishift")
12662    (set_attr "mode" "DI")])
12663
12664 (define_insn "*lshrdi3_1"
12665   [(set (match_operand:DI 0 "register_operand" "=r")
12666         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12667                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12668    (clobber (reg:CC FLAGS_REG))]
12669   "!TARGET_64BIT"
12670   "#"
12671   [(set_attr "type" "multi")])
12672
12673 ;; By default we don't ask for a scratch register, because when DImode
12674 ;; values are manipulated, registers are already at a premium.  But if
12675 ;; we have one handy, we won't turn it away.
12676 (define_peephole2
12677   [(match_scratch:SI 3 "r")
12678    (parallel [(set (match_operand:DI 0 "register_operand" "")
12679                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12680                                 (match_operand:QI 2 "nonmemory_operand" "")))
12681               (clobber (reg:CC FLAGS_REG))])
12682    (match_dup 3)]
12683   "!TARGET_64BIT && TARGET_CMOVE"
12684   [(const_int 0)]
12685   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12686
12687 (define_split
12688   [(set (match_operand:DI 0 "register_operand" "")
12689         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12690                      (match_operand:QI 2 "nonmemory_operand" "")))
12691    (clobber (reg:CC FLAGS_REG))]
12692   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12693                      ? epilogue_completed : reload_completed)"
12694   [(const_int 0)]
12695   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12696
12697 (define_expand "lshrsi3"
12698   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12699         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12700                      (match_operand:QI 2 "nonmemory_operand" "")))
12701    (clobber (reg:CC FLAGS_REG))]
12702   ""
12703   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12704
12705 (define_insn "*lshrsi3_1_one_bit"
12706   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12707         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12708                      (match_operand:QI 2 "const1_operand" "")))
12709    (clobber (reg:CC FLAGS_REG))]
12710   "(TARGET_SHIFT1 || optimize_size)
12711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12712   "shr{l}\t%0"
12713   [(set_attr "type" "ishift")
12714    (set (attr "length")
12715      (if_then_else (match_operand:SI 0 "register_operand" "")
12716         (const_string "2")
12717         (const_string "*")))])
12718
12719 (define_insn "*lshrsi3_1_one_bit_zext"
12720   [(set (match_operand:DI 0 "register_operand" "=r")
12721         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12722                      (match_operand:QI 2 "const1_operand" "")))
12723    (clobber (reg:CC FLAGS_REG))]
12724   "TARGET_64BIT
12725    && (TARGET_SHIFT1 || optimize_size)
12726    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12727   "shr{l}\t%k0"
12728   [(set_attr "type" "ishift")
12729    (set_attr "length" "2")])
12730
12731 (define_insn "*lshrsi3_1"
12732   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12733         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12734                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12735    (clobber (reg:CC FLAGS_REG))]
12736   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12737   "@
12738    shr{l}\t{%2, %0|%0, %2}
12739    shr{l}\t{%b2, %0|%0, %b2}"
12740   [(set_attr "type" "ishift")
12741    (set_attr "mode" "SI")])
12742
12743 (define_insn "*lshrsi3_1_zext"
12744   [(set (match_operand:DI 0 "register_operand" "=r,r")
12745         (zero_extend:DI
12746           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12747                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12750   "@
12751    shr{l}\t{%2, %k0|%k0, %2}
12752    shr{l}\t{%b2, %k0|%k0, %b2}"
12753   [(set_attr "type" "ishift")
12754    (set_attr "mode" "SI")])
12755
12756 ;; This pattern can't accept a variable shift count, since shifts by
12757 ;; zero don't affect the flags.  We assume that shifts by constant
12758 ;; zero are optimized away.
12759 (define_insn "*lshrsi3_one_bit_cmp"
12760   [(set (reg FLAGS_REG)
12761         (compare
12762           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12763                        (match_operand:QI 2 "const1_operand" ""))
12764           (const_int 0)))
12765    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12766         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12767   "(TARGET_SHIFT1 || optimize_size)
12768    && ix86_match_ccmode (insn, CCGOCmode)
12769    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12770   "shr{l}\t%0"
12771   [(set_attr "type" "ishift")
12772    (set (attr "length")
12773      (if_then_else (match_operand:SI 0 "register_operand" "")
12774         (const_string "2")
12775         (const_string "*")))])
12776
12777 (define_insn "*lshrsi3_one_bit_cconly"
12778   [(set (reg FLAGS_REG)
12779         (compare
12780           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12781                        (match_operand:QI 2 "const1_operand" ""))
12782           (const_int 0)))
12783    (clobber (match_scratch:SI 0 "=r"))]
12784   "(TARGET_SHIFT1 || optimize_size)
12785    && ix86_match_ccmode (insn, CCGOCmode)
12786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12787   "shr{l}\t%0"
12788   [(set_attr "type" "ishift")
12789    (set_attr "length" "2")])
12790
12791 (define_insn "*lshrsi3_cmp_one_bit_zext"
12792   [(set (reg FLAGS_REG)
12793         (compare
12794           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12795                        (match_operand:QI 2 "const1_operand" ""))
12796           (const_int 0)))
12797    (set (match_operand:DI 0 "register_operand" "=r")
12798         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12799   "TARGET_64BIT
12800    && (TARGET_SHIFT1 || optimize_size)
12801    && ix86_match_ccmode (insn, CCGOCmode)
12802    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12803   "shr{l}\t%k0"
12804   [(set_attr "type" "ishift")
12805    (set_attr "length" "2")])
12806
12807 ;; This pattern can't accept a variable shift count, since shifts by
12808 ;; zero don't affect the flags.  We assume that shifts by constant
12809 ;; zero are optimized away.
12810 (define_insn "*lshrsi3_cmp"
12811   [(set (reg FLAGS_REG)
12812         (compare
12813           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12814                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12815           (const_int 0)))
12816    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12817         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12818   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12819    && ix86_match_ccmode (insn, CCGOCmode)
12820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12821   "shr{l}\t{%2, %0|%0, %2}"
12822   [(set_attr "type" "ishift")
12823    (set_attr "mode" "SI")])
12824
12825 (define_insn "*lshrsi3_cconly"
12826   [(set (reg FLAGS_REG)
12827       (compare
12828         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12829                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12830         (const_int 0)))
12831    (clobber (match_scratch:SI 0 "=r"))]
12832   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12833    && ix86_match_ccmode (insn, CCGOCmode)
12834    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12835   "shr{l}\t{%2, %0|%0, %2}"
12836   [(set_attr "type" "ishift")
12837    (set_attr "mode" "SI")])
12838
12839 (define_insn "*lshrsi3_cmp_zext"
12840   [(set (reg FLAGS_REG)
12841         (compare
12842           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12843                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12844           (const_int 0)))
12845    (set (match_operand:DI 0 "register_operand" "=r")
12846         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12847   "TARGET_64BIT
12848    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12849    && ix86_match_ccmode (insn, CCGOCmode)
12850    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12851   "shr{l}\t{%2, %k0|%k0, %2}"
12852   [(set_attr "type" "ishift")
12853    (set_attr "mode" "SI")])
12854
12855 (define_expand "lshrhi3"
12856   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12857         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12858                      (match_operand:QI 2 "nonmemory_operand" "")))
12859    (clobber (reg:CC FLAGS_REG))]
12860   "TARGET_HIMODE_MATH"
12861   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12862
12863 (define_insn "*lshrhi3_1_one_bit"
12864   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12865         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12866                      (match_operand:QI 2 "const1_operand" "")))
12867    (clobber (reg:CC FLAGS_REG))]
12868   "(TARGET_SHIFT1 || optimize_size)
12869    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12870   "shr{w}\t%0"
12871   [(set_attr "type" "ishift")
12872    (set (attr "length")
12873      (if_then_else (match_operand 0 "register_operand" "")
12874         (const_string "2")
12875         (const_string "*")))])
12876
12877 (define_insn "*lshrhi3_1"
12878   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12879         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12880                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12881    (clobber (reg:CC FLAGS_REG))]
12882   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12883   "@
12884    shr{w}\t{%2, %0|%0, %2}
12885    shr{w}\t{%b2, %0|%0, %b2}"
12886   [(set_attr "type" "ishift")
12887    (set_attr "mode" "HI")])
12888
12889 ;; This pattern can't accept a variable shift count, since shifts by
12890 ;; zero don't affect the flags.  We assume that shifts by constant
12891 ;; zero are optimized away.
12892 (define_insn "*lshrhi3_one_bit_cmp"
12893   [(set (reg FLAGS_REG)
12894         (compare
12895           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12896                        (match_operand:QI 2 "const1_operand" ""))
12897           (const_int 0)))
12898    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12899         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12900   "(TARGET_SHIFT1 || optimize_size)
12901    && ix86_match_ccmode (insn, CCGOCmode)
12902    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12903   "shr{w}\t%0"
12904   [(set_attr "type" "ishift")
12905    (set (attr "length")
12906      (if_then_else (match_operand:SI 0 "register_operand" "")
12907         (const_string "2")
12908         (const_string "*")))])
12909
12910 (define_insn "*lshrhi3_one_bit_cconly"
12911   [(set (reg FLAGS_REG)
12912         (compare
12913           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12914                        (match_operand:QI 2 "const1_operand" ""))
12915           (const_int 0)))
12916    (clobber (match_scratch:HI 0 "=r"))]
12917   "(TARGET_SHIFT1 || optimize_size)
12918    && ix86_match_ccmode (insn, CCGOCmode)
12919    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12920   "shr{w}\t%0"
12921   [(set_attr "type" "ishift")
12922    (set_attr "length" "2")])
12923
12924 ;; This pattern can't accept a variable shift count, since shifts by
12925 ;; zero don't affect the flags.  We assume that shifts by constant
12926 ;; zero are optimized away.
12927 (define_insn "*lshrhi3_cmp"
12928   [(set (reg FLAGS_REG)
12929         (compare
12930           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12931                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12932           (const_int 0)))
12933    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12934         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12935   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12936    && ix86_match_ccmode (insn, CCGOCmode)
12937    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12938   "shr{w}\t{%2, %0|%0, %2}"
12939   [(set_attr "type" "ishift")
12940    (set_attr "mode" "HI")])
12941
12942 (define_insn "*lshrhi3_cconly"
12943   [(set (reg FLAGS_REG)
12944         (compare
12945           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12946                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12947           (const_int 0)))
12948    (clobber (match_scratch:HI 0 "=r"))]
12949   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12950    && ix86_match_ccmode (insn, CCGOCmode)
12951    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12952   "shr{w}\t{%2, %0|%0, %2}"
12953   [(set_attr "type" "ishift")
12954    (set_attr "mode" "HI")])
12955
12956 (define_expand "lshrqi3"
12957   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12958         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12959                      (match_operand:QI 2 "nonmemory_operand" "")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "TARGET_QIMODE_MATH"
12962   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12963
12964 (define_insn "*lshrqi3_1_one_bit"
12965   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12966         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12967                      (match_operand:QI 2 "const1_operand" "")))
12968    (clobber (reg:CC FLAGS_REG))]
12969   "(TARGET_SHIFT1 || optimize_size)
12970    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12971   "shr{b}\t%0"
12972   [(set_attr "type" "ishift")
12973    (set (attr "length")
12974      (if_then_else (match_operand 0 "register_operand" "")
12975         (const_string "2")
12976         (const_string "*")))])
12977
12978 (define_insn "*lshrqi3_1_one_bit_slp"
12979   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12980         (lshiftrt:QI (match_dup 0)
12981                      (match_operand:QI 1 "const1_operand" "")))
12982    (clobber (reg:CC FLAGS_REG))]
12983   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12984    && (TARGET_SHIFT1 || optimize_size)"
12985   "shr{b}\t%0"
12986   [(set_attr "type" "ishift1")
12987    (set (attr "length")
12988      (if_then_else (match_operand 0 "register_operand" "")
12989         (const_string "2")
12990         (const_string "*")))])
12991
12992 (define_insn "*lshrqi3_1"
12993   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12994         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12995                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12996    (clobber (reg:CC FLAGS_REG))]
12997   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12998   "@
12999    shr{b}\t{%2, %0|%0, %2}
13000    shr{b}\t{%b2, %0|%0, %b2}"
13001   [(set_attr "type" "ishift")
13002    (set_attr "mode" "QI")])
13003
13004 (define_insn "*lshrqi3_1_slp"
13005   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13006         (lshiftrt:QI (match_dup 0)
13007                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13008    (clobber (reg:CC FLAGS_REG))]
13009   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13011   "@
13012    shr{b}\t{%1, %0|%0, %1}
13013    shr{b}\t{%b1, %0|%0, %b1}"
13014   [(set_attr "type" "ishift1")
13015    (set_attr "mode" "QI")])
13016
13017 ;; This pattern can't accept a variable shift count, since shifts by
13018 ;; zero don't affect the flags.  We assume that shifts by constant
13019 ;; zero are optimized away.
13020 (define_insn "*lshrqi2_one_bit_cmp"
13021   [(set (reg FLAGS_REG)
13022         (compare
13023           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13024                        (match_operand:QI 2 "const1_operand" ""))
13025           (const_int 0)))
13026    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13027         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13028   "(TARGET_SHIFT1 || optimize_size)
13029    && ix86_match_ccmode (insn, CCGOCmode)
13030    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13031   "shr{b}\t%0"
13032   [(set_attr "type" "ishift")
13033    (set (attr "length")
13034      (if_then_else (match_operand:SI 0 "register_operand" "")
13035         (const_string "2")
13036         (const_string "*")))])
13037
13038 (define_insn "*lshrqi2_one_bit_cconly"
13039   [(set (reg FLAGS_REG)
13040         (compare
13041           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13042                        (match_operand:QI 2 "const1_operand" ""))
13043           (const_int 0)))
13044    (clobber (match_scratch:QI 0 "=q"))]
13045   "(TARGET_SHIFT1 || optimize_size)
13046    && ix86_match_ccmode (insn, CCGOCmode)
13047    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13048   "shr{b}\t%0"
13049   [(set_attr "type" "ishift")
13050    (set_attr "length" "2")])
13051
13052 ;; This pattern can't accept a variable shift count, since shifts by
13053 ;; zero don't affect the flags.  We assume that shifts by constant
13054 ;; zero are optimized away.
13055 (define_insn "*lshrqi2_cmp"
13056   [(set (reg FLAGS_REG)
13057         (compare
13058           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13059                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13060           (const_int 0)))
13061    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13063   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13064    && ix86_match_ccmode (insn, CCGOCmode)
13065    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13066   "shr{b}\t{%2, %0|%0, %2}"
13067   [(set_attr "type" "ishift")
13068    (set_attr "mode" "QI")])
13069
13070 (define_insn "*lshrqi2_cconly"
13071   [(set (reg FLAGS_REG)
13072         (compare
13073           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13074                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13075           (const_int 0)))
13076    (clobber (match_scratch:QI 0 "=q"))]
13077   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13078    && ix86_match_ccmode (insn, CCGOCmode)
13079    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13080   "shr{b}\t{%2, %0|%0, %2}"
13081   [(set_attr "type" "ishift")
13082    (set_attr "mode" "QI")])
13083 \f
13084 ;; Rotate instructions
13085
13086 (define_expand "rotldi3"
13087   [(set (match_operand:DI 0 "shiftdi_operand" "")
13088         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13089                    (match_operand:QI 2 "nonmemory_operand" "")))
13090    (clobber (reg:CC FLAGS_REG))]
13091  ""
13092 {
13093   if (TARGET_64BIT)
13094     {
13095       ix86_expand_binary_operator (ROTATE, DImode, operands);
13096       DONE;
13097     }
13098   if (!const_1_to_31_operand (operands[2], VOIDmode))
13099     FAIL;
13100   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13101   DONE;
13102 })
13103
13104 ;; Implement rotation using two double-precision shift instructions
13105 ;; and a scratch register.
13106 (define_insn_and_split "ix86_rotldi3"
13107  [(set (match_operand:DI 0 "register_operand" "=r")
13108        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13109                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13110   (clobber (reg:CC FLAGS_REG))
13111   (clobber (match_scratch:SI 3 "=&r"))]
13112  "!TARGET_64BIT"
13113  ""
13114  "&& reload_completed"
13115  [(set (match_dup 3) (match_dup 4))
13116   (parallel
13117    [(set (match_dup 4)
13118          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13119                  (lshiftrt:SI (match_dup 5)
13120                               (minus:QI (const_int 32) (match_dup 2)))))
13121     (clobber (reg:CC FLAGS_REG))])
13122   (parallel
13123    [(set (match_dup 5)
13124          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13125                  (lshiftrt:SI (match_dup 3)
13126                               (minus:QI (const_int 32) (match_dup 2)))))
13127     (clobber (reg:CC FLAGS_REG))])]
13128  "split_di (operands, 1, operands + 4, operands + 5);")
13129
13130 (define_insn "*rotlsi3_1_one_bit_rex64"
13131   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13132         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13133                    (match_operand:QI 2 "const1_operand" "")))
13134    (clobber (reg:CC FLAGS_REG))]
13135   "TARGET_64BIT
13136    && (TARGET_SHIFT1 || optimize_size)
13137    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13138   "rol{q}\t%0"
13139   [(set_attr "type" "rotate")
13140    (set (attr "length")
13141      (if_then_else (match_operand:DI 0 "register_operand" "")
13142         (const_string "2")
13143         (const_string "*")))])
13144
13145 (define_insn "*rotldi3_1_rex64"
13146   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13147         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13148                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13149    (clobber (reg:CC FLAGS_REG))]
13150   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13151   "@
13152    rol{q}\t{%2, %0|%0, %2}
13153    rol{q}\t{%b2, %0|%0, %b2}"
13154   [(set_attr "type" "rotate")
13155    (set_attr "mode" "DI")])
13156
13157 (define_expand "rotlsi3"
13158   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13159         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13160                    (match_operand:QI 2 "nonmemory_operand" "")))
13161    (clobber (reg:CC FLAGS_REG))]
13162   ""
13163   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13164
13165 (define_insn "*rotlsi3_1_one_bit"
13166   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13167         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13168                    (match_operand:QI 2 "const1_operand" "")))
13169    (clobber (reg:CC FLAGS_REG))]
13170   "(TARGET_SHIFT1 || optimize_size)
13171    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13172   "rol{l}\t%0"
13173   [(set_attr "type" "rotate")
13174    (set (attr "length")
13175      (if_then_else (match_operand:SI 0 "register_operand" "")
13176         (const_string "2")
13177         (const_string "*")))])
13178
13179 (define_insn "*rotlsi3_1_one_bit_zext"
13180   [(set (match_operand:DI 0 "register_operand" "=r")
13181         (zero_extend:DI
13182           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13183                      (match_operand:QI 2 "const1_operand" ""))))
13184    (clobber (reg:CC FLAGS_REG))]
13185   "TARGET_64BIT
13186    && (TARGET_SHIFT1 || optimize_size)
13187    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13188   "rol{l}\t%k0"
13189   [(set_attr "type" "rotate")
13190    (set_attr "length" "2")])
13191
13192 (define_insn "*rotlsi3_1"
13193   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13194         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13195                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13196    (clobber (reg:CC FLAGS_REG))]
13197   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13198   "@
13199    rol{l}\t{%2, %0|%0, %2}
13200    rol{l}\t{%b2, %0|%0, %b2}"
13201   [(set_attr "type" "rotate")
13202    (set_attr "mode" "SI")])
13203
13204 (define_insn "*rotlsi3_1_zext"
13205   [(set (match_operand:DI 0 "register_operand" "=r,r")
13206         (zero_extend:DI
13207           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13208                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13209    (clobber (reg:CC FLAGS_REG))]
13210   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13211   "@
13212    rol{l}\t{%2, %k0|%k0, %2}
13213    rol{l}\t{%b2, %k0|%k0, %b2}"
13214   [(set_attr "type" "rotate")
13215    (set_attr "mode" "SI")])
13216
13217 (define_expand "rotlhi3"
13218   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13219         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13220                    (match_operand:QI 2 "nonmemory_operand" "")))
13221    (clobber (reg:CC FLAGS_REG))]
13222   "TARGET_HIMODE_MATH"
13223   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13224
13225 (define_insn "*rotlhi3_1_one_bit"
13226   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13227         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13228                    (match_operand:QI 2 "const1_operand" "")))
13229    (clobber (reg:CC FLAGS_REG))]
13230   "(TARGET_SHIFT1 || optimize_size)
13231    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13232   "rol{w}\t%0"
13233   [(set_attr "type" "rotate")
13234    (set (attr "length")
13235      (if_then_else (match_operand 0 "register_operand" "")
13236         (const_string "2")
13237         (const_string "*")))])
13238
13239 (define_insn "*rotlhi3_1"
13240   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13245   "@
13246    rol{w}\t{%2, %0|%0, %2}
13247    rol{w}\t{%b2, %0|%0, %b2}"
13248   [(set_attr "type" "rotate")
13249    (set_attr "mode" "HI")])
13250
13251 (define_split
13252  [(set (match_operand:HI 0 "register_operand" "")
13253        (rotate:HI (match_dup 0) (const_int 8)))
13254   (clobber (reg:CC FLAGS_REG))]
13255  "reload_completed"
13256  [(parallel [(set (strict_low_part (match_dup 0))
13257                   (bswap:HI (match_dup 0)))
13258              (clobber (reg:CC FLAGS_REG))])]
13259  "")
13260
13261 (define_expand "rotlqi3"
13262   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13263         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13264                    (match_operand:QI 2 "nonmemory_operand" "")))
13265    (clobber (reg:CC FLAGS_REG))]
13266   "TARGET_QIMODE_MATH"
13267   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13268
13269 (define_insn "*rotlqi3_1_one_bit_slp"
13270   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13271         (rotate:QI (match_dup 0)
13272                    (match_operand:QI 1 "const1_operand" "")))
13273    (clobber (reg:CC FLAGS_REG))]
13274   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13275    && (TARGET_SHIFT1 || optimize_size)"
13276   "rol{b}\t%0"
13277   [(set_attr "type" "rotate1")
13278    (set (attr "length")
13279      (if_then_else (match_operand 0 "register_operand" "")
13280         (const_string "2")
13281         (const_string "*")))])
13282
13283 (define_insn "*rotlqi3_1_one_bit"
13284   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13285         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13286                    (match_operand:QI 2 "const1_operand" "")))
13287    (clobber (reg:CC FLAGS_REG))]
13288   "(TARGET_SHIFT1 || optimize_size)
13289    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13290   "rol{b}\t%0"
13291   [(set_attr "type" "rotate")
13292    (set (attr "length")
13293      (if_then_else (match_operand 0 "register_operand" "")
13294         (const_string "2")
13295         (const_string "*")))])
13296
13297 (define_insn "*rotlqi3_1_slp"
13298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13299         (rotate:QI (match_dup 0)
13300                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13301    (clobber (reg:CC FLAGS_REG))]
13302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13303    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13304   "@
13305    rol{b}\t{%1, %0|%0, %1}
13306    rol{b}\t{%b1, %0|%0, %b1}"
13307   [(set_attr "type" "rotate1")
13308    (set_attr "mode" "QI")])
13309
13310 (define_insn "*rotlqi3_1"
13311   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13312         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13313                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13314    (clobber (reg:CC FLAGS_REG))]
13315   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13316   "@
13317    rol{b}\t{%2, %0|%0, %2}
13318    rol{b}\t{%b2, %0|%0, %b2}"
13319   [(set_attr "type" "rotate")
13320    (set_attr "mode" "QI")])
13321
13322 (define_expand "rotrdi3"
13323   [(set (match_operand:DI 0 "shiftdi_operand" "")
13324         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13325                    (match_operand:QI 2 "nonmemory_operand" "")))
13326    (clobber (reg:CC FLAGS_REG))]
13327  ""
13328 {
13329   if (TARGET_64BIT)
13330     {
13331       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13332       DONE;
13333     }
13334   if (!const_1_to_31_operand (operands[2], VOIDmode))
13335     FAIL;
13336   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13337   DONE;
13338 })
13339
13340 ;; Implement rotation using two double-precision shift instructions
13341 ;; and a scratch register.
13342 (define_insn_and_split "ix86_rotrdi3"
13343  [(set (match_operand:DI 0 "register_operand" "=r")
13344        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13345                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13346   (clobber (reg:CC FLAGS_REG))
13347   (clobber (match_scratch:SI 3 "=&r"))]
13348  "!TARGET_64BIT"
13349  ""
13350  "&& reload_completed"
13351  [(set (match_dup 3) (match_dup 4))
13352   (parallel
13353    [(set (match_dup 4)
13354          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13355                  (ashift:SI (match_dup 5)
13356                             (minus:QI (const_int 32) (match_dup 2)))))
13357     (clobber (reg:CC FLAGS_REG))])
13358   (parallel
13359    [(set (match_dup 5)
13360          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13361                  (ashift:SI (match_dup 3)
13362                             (minus:QI (const_int 32) (match_dup 2)))))
13363     (clobber (reg:CC FLAGS_REG))])]
13364  "split_di (operands, 1, operands + 4, operands + 5);")
13365
13366 (define_insn "*rotrdi3_1_one_bit_rex64"
13367   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13368         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13369                      (match_operand:QI 2 "const1_operand" "")))
13370    (clobber (reg:CC FLAGS_REG))]
13371   "TARGET_64BIT
13372    && (TARGET_SHIFT1 || optimize_size)
13373    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13374   "ror{q}\t%0"
13375   [(set_attr "type" "rotate")
13376    (set (attr "length")
13377      (if_then_else (match_operand:DI 0 "register_operand" "")
13378         (const_string "2")
13379         (const_string "*")))])
13380
13381 (define_insn "*rotrdi3_1_rex64"
13382   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13383         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13384                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13385    (clobber (reg:CC FLAGS_REG))]
13386   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13387   "@
13388    ror{q}\t{%2, %0|%0, %2}
13389    ror{q}\t{%b2, %0|%0, %b2}"
13390   [(set_attr "type" "rotate")
13391    (set_attr "mode" "DI")])
13392
13393 (define_expand "rotrsi3"
13394   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13395         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13396                      (match_operand:QI 2 "nonmemory_operand" "")))
13397    (clobber (reg:CC FLAGS_REG))]
13398   ""
13399   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13400
13401 (define_insn "*rotrsi3_1_one_bit"
13402   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13403         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13404                      (match_operand:QI 2 "const1_operand" "")))
13405    (clobber (reg:CC FLAGS_REG))]
13406   "(TARGET_SHIFT1 || optimize_size)
13407    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13408   "ror{l}\t%0"
13409   [(set_attr "type" "rotate")
13410    (set (attr "length")
13411      (if_then_else (match_operand:SI 0 "register_operand" "")
13412         (const_string "2")
13413         (const_string "*")))])
13414
13415 (define_insn "*rotrsi3_1_one_bit_zext"
13416   [(set (match_operand:DI 0 "register_operand" "=r")
13417         (zero_extend:DI
13418           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13419                        (match_operand:QI 2 "const1_operand" ""))))
13420    (clobber (reg:CC FLAGS_REG))]
13421   "TARGET_64BIT
13422    && (TARGET_SHIFT1 || optimize_size)
13423    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13424   "ror{l}\t%k0"
13425   [(set_attr "type" "rotate")
13426    (set (attr "length")
13427      (if_then_else (match_operand:SI 0 "register_operand" "")
13428         (const_string "2")
13429         (const_string "*")))])
13430
13431 (define_insn "*rotrsi3_1"
13432   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13433         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13434                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13435    (clobber (reg:CC FLAGS_REG))]
13436   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13437   "@
13438    ror{l}\t{%2, %0|%0, %2}
13439    ror{l}\t{%b2, %0|%0, %b2}"
13440   [(set_attr "type" "rotate")
13441    (set_attr "mode" "SI")])
13442
13443 (define_insn "*rotrsi3_1_zext"
13444   [(set (match_operand:DI 0 "register_operand" "=r,r")
13445         (zero_extend:DI
13446           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13447                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13448    (clobber (reg:CC FLAGS_REG))]
13449   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13450   "@
13451    ror{l}\t{%2, %k0|%k0, %2}
13452    ror{l}\t{%b2, %k0|%k0, %b2}"
13453   [(set_attr "type" "rotate")
13454    (set_attr "mode" "SI")])
13455
13456 (define_expand "rotrhi3"
13457   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13458         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13459                      (match_operand:QI 2 "nonmemory_operand" "")))
13460    (clobber (reg:CC FLAGS_REG))]
13461   "TARGET_HIMODE_MATH"
13462   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13463
13464 (define_insn "*rotrhi3_one_bit"
13465   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13466         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13467                      (match_operand:QI 2 "const1_operand" "")))
13468    (clobber (reg:CC FLAGS_REG))]
13469   "(TARGET_SHIFT1 || optimize_size)
13470    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13471   "ror{w}\t%0"
13472   [(set_attr "type" "rotate")
13473    (set (attr "length")
13474      (if_then_else (match_operand 0 "register_operand" "")
13475         (const_string "2")
13476         (const_string "*")))])
13477
13478 (define_insn "*rotrhi3_1"
13479   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13480         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13481                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482    (clobber (reg:CC FLAGS_REG))]
13483   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13484   "@
13485    ror{w}\t{%2, %0|%0, %2}
13486    ror{w}\t{%b2, %0|%0, %b2}"
13487   [(set_attr "type" "rotate")
13488    (set_attr "mode" "HI")])
13489
13490 (define_split
13491  [(set (match_operand:HI 0 "register_operand" "")
13492        (rotatert:HI (match_dup 0) (const_int 8)))
13493   (clobber (reg:CC FLAGS_REG))]
13494  "reload_completed"
13495  [(parallel [(set (strict_low_part (match_dup 0))
13496                   (bswap:HI (match_dup 0)))
13497              (clobber (reg:CC FLAGS_REG))])]
13498  "")
13499
13500 (define_expand "rotrqi3"
13501   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13502         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13503                      (match_operand:QI 2 "nonmemory_operand" "")))
13504    (clobber (reg:CC FLAGS_REG))]
13505   "TARGET_QIMODE_MATH"
13506   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13507
13508 (define_insn "*rotrqi3_1_one_bit"
13509   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13510         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13511                      (match_operand:QI 2 "const1_operand" "")))
13512    (clobber (reg:CC FLAGS_REG))]
13513   "(TARGET_SHIFT1 || optimize_size)
13514    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13515   "ror{b}\t%0"
13516   [(set_attr "type" "rotate")
13517    (set (attr "length")
13518      (if_then_else (match_operand 0 "register_operand" "")
13519         (const_string "2")
13520         (const_string "*")))])
13521
13522 (define_insn "*rotrqi3_1_one_bit_slp"
13523   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13524         (rotatert:QI (match_dup 0)
13525                      (match_operand:QI 1 "const1_operand" "")))
13526    (clobber (reg:CC FLAGS_REG))]
13527   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13528    && (TARGET_SHIFT1 || optimize_size)"
13529   "ror{b}\t%0"
13530   [(set_attr "type" "rotate1")
13531    (set (attr "length")
13532      (if_then_else (match_operand 0 "register_operand" "")
13533         (const_string "2")
13534         (const_string "*")))])
13535
13536 (define_insn "*rotrqi3_1"
13537   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13538         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13539                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13540    (clobber (reg:CC FLAGS_REG))]
13541   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13542   "@
13543    ror{b}\t{%2, %0|%0, %2}
13544    ror{b}\t{%b2, %0|%0, %b2}"
13545   [(set_attr "type" "rotate")
13546    (set_attr "mode" "QI")])
13547
13548 (define_insn "*rotrqi3_1_slp"
13549   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13550         (rotatert:QI (match_dup 0)
13551                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13552    (clobber (reg:CC FLAGS_REG))]
13553   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13554    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13555   "@
13556    ror{b}\t{%1, %0|%0, %1}
13557    ror{b}\t{%b1, %0|%0, %b1}"
13558   [(set_attr "type" "rotate1")
13559    (set_attr "mode" "QI")])
13560 \f
13561 ;; Bit set / bit test instructions
13562
13563 (define_expand "extv"
13564   [(set (match_operand:SI 0 "register_operand" "")
13565         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13566                          (match_operand:SI 2 "const8_operand" "")
13567                          (match_operand:SI 3 "const8_operand" "")))]
13568   ""
13569 {
13570   /* Handle extractions from %ah et al.  */
13571   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13572     FAIL;
13573
13574   /* From mips.md: extract_bit_field doesn't verify that our source
13575      matches the predicate, so check it again here.  */
13576   if (! ext_register_operand (operands[1], VOIDmode))
13577     FAIL;
13578 })
13579
13580 (define_expand "extzv"
13581   [(set (match_operand:SI 0 "register_operand" "")
13582         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13583                          (match_operand:SI 2 "const8_operand" "")
13584                          (match_operand:SI 3 "const8_operand" "")))]
13585   ""
13586 {
13587   /* Handle extractions from %ah et al.  */
13588   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13589     FAIL;
13590
13591   /* From mips.md: extract_bit_field doesn't verify that our source
13592      matches the predicate, so check it again here.  */
13593   if (! ext_register_operand (operands[1], VOIDmode))
13594     FAIL;
13595 })
13596
13597 (define_expand "insv"
13598   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13599                       (match_operand 1 "const8_operand" "")
13600                       (match_operand 2 "const8_operand" ""))
13601         (match_operand 3 "register_operand" ""))]
13602   ""
13603 {
13604   /* Handle insertions to %ah et al.  */
13605   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13606     FAIL;
13607
13608   /* From mips.md: insert_bit_field doesn't verify that our source
13609      matches the predicate, so check it again here.  */
13610   if (! ext_register_operand (operands[0], VOIDmode))
13611     FAIL;
13612
13613   if (TARGET_64BIT)
13614     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13615   else
13616     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13617
13618   DONE;
13619 })
13620
13621 ;; %%% bts, btr, btc, bt.
13622 ;; In general these instructions are *slow* when applied to memory,
13623 ;; since they enforce atomic operation.  When applied to registers,
13624 ;; it depends on the cpu implementation.  They're never faster than
13625 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13626 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13627 ;; within the instruction itself, so operating on bits in the high
13628 ;; 32-bits of a register becomes easier.
13629 ;;
13630 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13631 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13632 ;; negdf respectively, so they can never be disabled entirely.
13633
13634 (define_insn "*btsq"
13635   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13636                          (const_int 1)
13637                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13638         (const_int 1))
13639    (clobber (reg:CC FLAGS_REG))]
13640   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13641   "bts{q} %1,%0"
13642   [(set_attr "type" "alu1")])
13643
13644 (define_insn "*btrq"
13645   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13646                          (const_int 1)
13647                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13648         (const_int 0))
13649    (clobber (reg:CC FLAGS_REG))]
13650   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13651   "btr{q} %1,%0"
13652   [(set_attr "type" "alu1")])
13653
13654 (define_insn "*btcq"
13655   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13656                          (const_int 1)
13657                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13658         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13659    (clobber (reg:CC FLAGS_REG))]
13660   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13661   "btc{q} %1,%0"
13662   [(set_attr "type" "alu1")])
13663
13664 ;; Allow Nocona to avoid these instructions if a register is available.
13665
13666 (define_peephole2
13667   [(match_scratch:DI 2 "r")
13668    (parallel [(set (zero_extract:DI
13669                      (match_operand:DI 0 "register_operand" "")
13670                      (const_int 1)
13671                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13672                    (const_int 1))
13673               (clobber (reg:CC FLAGS_REG))])]
13674   "TARGET_64BIT && !TARGET_USE_BT"
13675   [(const_int 0)]
13676 {
13677   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13678   rtx op1;
13679
13680   if (HOST_BITS_PER_WIDE_INT >= 64)
13681     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13682   else if (i < HOST_BITS_PER_WIDE_INT)
13683     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13684   else
13685     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13686
13687   op1 = immed_double_const (lo, hi, DImode);
13688   if (i >= 31)
13689     {
13690       emit_move_insn (operands[2], op1);
13691       op1 = operands[2];
13692     }
13693
13694   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13695   DONE;
13696 })
13697
13698 (define_peephole2
13699   [(match_scratch:DI 2 "r")
13700    (parallel [(set (zero_extract:DI
13701                      (match_operand:DI 0 "register_operand" "")
13702                      (const_int 1)
13703                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13704                    (const_int 0))
13705               (clobber (reg:CC FLAGS_REG))])]
13706   "TARGET_64BIT && !TARGET_USE_BT"
13707   [(const_int 0)]
13708 {
13709   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13710   rtx op1;
13711
13712   if (HOST_BITS_PER_WIDE_INT >= 64)
13713     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13714   else if (i < HOST_BITS_PER_WIDE_INT)
13715     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13716   else
13717     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13718
13719   op1 = immed_double_const (~lo, ~hi, DImode);
13720   if (i >= 32)
13721     {
13722       emit_move_insn (operands[2], op1);
13723       op1 = operands[2];
13724     }
13725
13726   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13727   DONE;
13728 })
13729
13730 (define_peephole2
13731   [(match_scratch:DI 2 "r")
13732    (parallel [(set (zero_extract:DI
13733                      (match_operand:DI 0 "register_operand" "")
13734                      (const_int 1)
13735                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13736               (not:DI (zero_extract:DI
13737                         (match_dup 0) (const_int 1) (match_dup 1))))
13738               (clobber (reg:CC FLAGS_REG))])]
13739   "TARGET_64BIT && !TARGET_USE_BT"
13740   [(const_int 0)]
13741 {
13742   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13743   rtx op1;
13744
13745   if (HOST_BITS_PER_WIDE_INT >= 64)
13746     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13747   else if (i < HOST_BITS_PER_WIDE_INT)
13748     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13749   else
13750     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13751
13752   op1 = immed_double_const (lo, hi, DImode);
13753   if (i >= 31)
13754     {
13755       emit_move_insn (operands[2], op1);
13756       op1 = operands[2];
13757     }
13758
13759   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13760   DONE;
13761 })
13762 \f
13763 ;; Store-flag instructions.
13764
13765 ;; For all sCOND expanders, also expand the compare or test insn that
13766 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13767
13768 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13769 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13770 ;; way, which can later delete the movzx if only QImode is needed.
13771
13772 (define_expand "s<code>"
13773   [(set (match_operand:QI 0 "register_operand" "")
13774         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13775   ""
13776   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13777
13778 (define_expand "s<code>"
13779   [(set (match_operand:QI 0 "register_operand" "")
13780         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781   "TARGET_80387 || TARGET_SSE"
13782   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13783
13784 (define_insn "*setcc_1"
13785   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13786         (match_operator:QI 1 "ix86_comparison_operator"
13787           [(reg FLAGS_REG) (const_int 0)]))]
13788   ""
13789   "set%C1\t%0"
13790   [(set_attr "type" "setcc")
13791    (set_attr "mode" "QI")])
13792
13793 (define_insn "*setcc_2"
13794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13795         (match_operator:QI 1 "ix86_comparison_operator"
13796           [(reg FLAGS_REG) (const_int 0)]))]
13797   ""
13798   "set%C1\t%0"
13799   [(set_attr "type" "setcc")
13800    (set_attr "mode" "QI")])
13801
13802 ;; In general it is not safe to assume too much about CCmode registers,
13803 ;; so simplify-rtx stops when it sees a second one.  Under certain
13804 ;; conditions this is safe on x86, so help combine not create
13805 ;;
13806 ;;      seta    %al
13807 ;;      testb   %al, %al
13808 ;;      sete    %al
13809
13810 (define_split
13811   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13812         (ne:QI (match_operator 1 "ix86_comparison_operator"
13813                  [(reg FLAGS_REG) (const_int 0)])
13814             (const_int 0)))]
13815   ""
13816   [(set (match_dup 0) (match_dup 1))]
13817 {
13818   PUT_MODE (operands[1], QImode);
13819 })
13820
13821 (define_split
13822   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13823         (ne:QI (match_operator 1 "ix86_comparison_operator"
13824                  [(reg FLAGS_REG) (const_int 0)])
13825             (const_int 0)))]
13826   ""
13827   [(set (match_dup 0) (match_dup 1))]
13828 {
13829   PUT_MODE (operands[1], QImode);
13830 })
13831
13832 (define_split
13833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13834         (eq:QI (match_operator 1 "ix86_comparison_operator"
13835                  [(reg FLAGS_REG) (const_int 0)])
13836             (const_int 0)))]
13837   ""
13838   [(set (match_dup 0) (match_dup 1))]
13839 {
13840   rtx new_op1 = copy_rtx (operands[1]);
13841   operands[1] = new_op1;
13842   PUT_MODE (new_op1, QImode);
13843   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13844                                              GET_MODE (XEXP (new_op1, 0))));
13845
13846   /* Make sure that (a) the CCmode we have for the flags is strong
13847      enough for the reversed compare or (b) we have a valid FP compare.  */
13848   if (! ix86_comparison_operator (new_op1, VOIDmode))
13849     FAIL;
13850 })
13851
13852 (define_split
13853   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13854         (eq:QI (match_operator 1 "ix86_comparison_operator"
13855                  [(reg FLAGS_REG) (const_int 0)])
13856             (const_int 0)))]
13857   ""
13858   [(set (match_dup 0) (match_dup 1))]
13859 {
13860   rtx new_op1 = copy_rtx (operands[1]);
13861   operands[1] = new_op1;
13862   PUT_MODE (new_op1, QImode);
13863   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13864                                              GET_MODE (XEXP (new_op1, 0))));
13865
13866   /* Make sure that (a) the CCmode we have for the flags is strong
13867      enough for the reversed compare or (b) we have a valid FP compare.  */
13868   if (! ix86_comparison_operator (new_op1, VOIDmode))
13869     FAIL;
13870 })
13871
13872 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13873 ;; subsequent logical operations are used to imitate conditional moves.
13874 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13875 ;; it directly.
13876
13877 (define_insn "*sse_setcc<mode>"
13878   [(set (match_operand:MODEF 0 "register_operand" "=x")
13879         (match_operator:MODEF 1 "sse_comparison_operator"
13880           [(match_operand:MODEF 2 "register_operand" "0")
13881            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13882   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13883   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13884   [(set_attr "type" "ssecmp")
13885    (set_attr "mode" "<MODE>")])
13886
13887 (define_insn "*sse5_setcc<mode>"
13888   [(set (match_operand:MODEF 0 "register_operand" "=x")
13889         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13890           [(match_operand:MODEF 2 "register_operand" "x")
13891            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13892   "TARGET_SSE5"
13893   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13894   [(set_attr "type" "sse4arg")
13895    (set_attr "mode" "<MODE>")])
13896
13897 \f
13898 ;; Basic conditional jump instructions.
13899 ;; We ignore the overflow flag for signed branch instructions.
13900
13901 ;; For all bCOND expanders, also expand the compare or test insn that
13902 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13903
13904 (define_expand "b<code>"
13905   [(set (pc)
13906         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13907                                    (const_int 0))
13908                       (label_ref (match_operand 0 ""))
13909                       (pc)))]
13910   ""
13911   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13912
13913 (define_expand "b<code>"
13914   [(set (pc)
13915         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13916                                   (const_int 0))
13917                       (label_ref (match_operand 0 ""))
13918                       (pc)))]
13919   "TARGET_80387 || TARGET_SSE_MATH"
13920   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13921
13922 (define_insn "*jcc_1"
13923   [(set (pc)
13924         (if_then_else (match_operator 1 "ix86_comparison_operator"
13925                                       [(reg FLAGS_REG) (const_int 0)])
13926                       (label_ref (match_operand 0 "" ""))
13927                       (pc)))]
13928   ""
13929   "%+j%C1\t%l0"
13930   [(set_attr "type" "ibr")
13931    (set_attr "modrm" "0")
13932    (set (attr "length")
13933            (if_then_else (and (ge (minus (match_dup 0) (pc))
13934                                   (const_int -126))
13935                               (lt (minus (match_dup 0) (pc))
13936                                   (const_int 128)))
13937              (const_int 2)
13938              (const_int 6)))])
13939
13940 (define_insn "*jcc_2"
13941   [(set (pc)
13942         (if_then_else (match_operator 1 "ix86_comparison_operator"
13943                                       [(reg FLAGS_REG) (const_int 0)])
13944                       (pc)
13945                       (label_ref (match_operand 0 "" ""))))]
13946   ""
13947   "%+j%c1\t%l0"
13948   [(set_attr "type" "ibr")
13949    (set_attr "modrm" "0")
13950    (set (attr "length")
13951            (if_then_else (and (ge (minus (match_dup 0) (pc))
13952                                   (const_int -126))
13953                               (lt (minus (match_dup 0) (pc))
13954                                   (const_int 128)))
13955              (const_int 2)
13956              (const_int 6)))])
13957
13958 ;; In general it is not safe to assume too much about CCmode registers,
13959 ;; so simplify-rtx stops when it sees a second one.  Under certain
13960 ;; conditions this is safe on x86, so help combine not create
13961 ;;
13962 ;;      seta    %al
13963 ;;      testb   %al, %al
13964 ;;      je      Lfoo
13965
13966 (define_split
13967   [(set (pc)
13968         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13969                                       [(reg FLAGS_REG) (const_int 0)])
13970                           (const_int 0))
13971                       (label_ref (match_operand 1 "" ""))
13972                       (pc)))]
13973   ""
13974   [(set (pc)
13975         (if_then_else (match_dup 0)
13976                       (label_ref (match_dup 1))
13977                       (pc)))]
13978 {
13979   PUT_MODE (operands[0], VOIDmode);
13980 })
13981
13982 (define_split
13983   [(set (pc)
13984         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13985                                       [(reg FLAGS_REG) (const_int 0)])
13986                           (const_int 0))
13987                       (label_ref (match_operand 1 "" ""))
13988                       (pc)))]
13989   ""
13990   [(set (pc)
13991         (if_then_else (match_dup 0)
13992                       (label_ref (match_dup 1))
13993                       (pc)))]
13994 {
13995   rtx new_op0 = copy_rtx (operands[0]);
13996   operands[0] = new_op0;
13997   PUT_MODE (new_op0, VOIDmode);
13998   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13999                                              GET_MODE (XEXP (new_op0, 0))));
14000
14001   /* Make sure that (a) the CCmode we have for the flags is strong
14002      enough for the reversed compare or (b) we have a valid FP compare.  */
14003   if (! ix86_comparison_operator (new_op0, VOIDmode))
14004     FAIL;
14005 })
14006
14007 ;; Define combination compare-and-branch fp compare instructions to use
14008 ;; during early optimization.  Splitting the operation apart early makes
14009 ;; for bad code when we want to reverse the operation.
14010
14011 (define_insn "*fp_jcc_1_mixed"
14012   [(set (pc)
14013         (if_then_else (match_operator 0 "comparison_operator"
14014                         [(match_operand 1 "register_operand" "f,x")
14015                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14016           (label_ref (match_operand 3 "" ""))
14017           (pc)))
14018    (clobber (reg:CCFP FPSR_REG))
14019    (clobber (reg:CCFP FLAGS_REG))]
14020   "TARGET_MIX_SSE_I387
14021    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14022    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14023    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14024   "#")
14025
14026 (define_insn "*fp_jcc_1_sse"
14027   [(set (pc)
14028         (if_then_else (match_operator 0 "comparison_operator"
14029                         [(match_operand 1 "register_operand" "x")
14030                          (match_operand 2 "nonimmediate_operand" "xm")])
14031           (label_ref (match_operand 3 "" ""))
14032           (pc)))
14033    (clobber (reg:CCFP FPSR_REG))
14034    (clobber (reg:CCFP FLAGS_REG))]
14035   "TARGET_SSE_MATH
14036    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14037    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14038    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14039   "#")
14040
14041 (define_insn "*fp_jcc_1_387"
14042   [(set (pc)
14043         (if_then_else (match_operator 0 "comparison_operator"
14044                         [(match_operand 1 "register_operand" "f")
14045                          (match_operand 2 "register_operand" "f")])
14046           (label_ref (match_operand 3 "" ""))
14047           (pc)))
14048    (clobber (reg:CCFP FPSR_REG))
14049    (clobber (reg:CCFP FLAGS_REG))]
14050   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14051    && TARGET_CMOVE
14052    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14053    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14054   "#")
14055
14056 (define_insn "*fp_jcc_2_mixed"
14057   [(set (pc)
14058         (if_then_else (match_operator 0 "comparison_operator"
14059                         [(match_operand 1 "register_operand" "f,x")
14060                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14061           (pc)
14062           (label_ref (match_operand 3 "" ""))))
14063    (clobber (reg:CCFP FPSR_REG))
14064    (clobber (reg:CCFP FLAGS_REG))]
14065   "TARGET_MIX_SSE_I387
14066    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14067    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14068    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14069   "#")
14070
14071 (define_insn "*fp_jcc_2_sse"
14072   [(set (pc)
14073         (if_then_else (match_operator 0 "comparison_operator"
14074                         [(match_operand 1 "register_operand" "x")
14075                          (match_operand 2 "nonimmediate_operand" "xm")])
14076           (pc)
14077           (label_ref (match_operand 3 "" ""))))
14078    (clobber (reg:CCFP FPSR_REG))
14079    (clobber (reg:CCFP FLAGS_REG))]
14080   "TARGET_SSE_MATH
14081    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14082    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14083    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14084   "#")
14085
14086 (define_insn "*fp_jcc_2_387"
14087   [(set (pc)
14088         (if_then_else (match_operator 0 "comparison_operator"
14089                         [(match_operand 1 "register_operand" "f")
14090                          (match_operand 2 "register_operand" "f")])
14091           (pc)
14092           (label_ref (match_operand 3 "" ""))))
14093    (clobber (reg:CCFP FPSR_REG))
14094    (clobber (reg:CCFP FLAGS_REG))]
14095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14096    && TARGET_CMOVE
14097    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14098    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14099   "#")
14100
14101 (define_insn "*fp_jcc_3_387"
14102   [(set (pc)
14103         (if_then_else (match_operator 0 "comparison_operator"
14104                         [(match_operand 1 "register_operand" "f")
14105                          (match_operand 2 "nonimmediate_operand" "fm")])
14106           (label_ref (match_operand 3 "" ""))
14107           (pc)))
14108    (clobber (reg:CCFP FPSR_REG))
14109    (clobber (reg:CCFP FLAGS_REG))
14110    (clobber (match_scratch:HI 4 "=a"))]
14111   "TARGET_80387
14112    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14113    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14114    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14115    && SELECT_CC_MODE (GET_CODE (operands[0]),
14116                       operands[1], operands[2]) == CCFPmode
14117    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14118   "#")
14119
14120 (define_insn "*fp_jcc_4_387"
14121   [(set (pc)
14122         (if_then_else (match_operator 0 "comparison_operator"
14123                         [(match_operand 1 "register_operand" "f")
14124                          (match_operand 2 "nonimmediate_operand" "fm")])
14125           (pc)
14126           (label_ref (match_operand 3 "" ""))))
14127    (clobber (reg:CCFP FPSR_REG))
14128    (clobber (reg:CCFP FLAGS_REG))
14129    (clobber (match_scratch:HI 4 "=a"))]
14130   "TARGET_80387
14131    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14132    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134    && SELECT_CC_MODE (GET_CODE (operands[0]),
14135                       operands[1], operands[2]) == CCFPmode
14136    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137   "#")
14138
14139 (define_insn "*fp_jcc_5_387"
14140   [(set (pc)
14141         (if_then_else (match_operator 0 "comparison_operator"
14142                         [(match_operand 1 "register_operand" "f")
14143                          (match_operand 2 "register_operand" "f")])
14144           (label_ref (match_operand 3 "" ""))
14145           (pc)))
14146    (clobber (reg:CCFP FPSR_REG))
14147    (clobber (reg:CCFP FLAGS_REG))
14148    (clobber (match_scratch:HI 4 "=a"))]
14149   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14150    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14151    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14152   "#")
14153
14154 (define_insn "*fp_jcc_6_387"
14155   [(set (pc)
14156         (if_then_else (match_operator 0 "comparison_operator"
14157                         [(match_operand 1 "register_operand" "f")
14158                          (match_operand 2 "register_operand" "f")])
14159           (pc)
14160           (label_ref (match_operand 3 "" ""))))
14161    (clobber (reg:CCFP FPSR_REG))
14162    (clobber (reg:CCFP FLAGS_REG))
14163    (clobber (match_scratch:HI 4 "=a"))]
14164   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14165    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14167   "#")
14168
14169 (define_insn "*fp_jcc_7_387"
14170   [(set (pc)
14171         (if_then_else (match_operator 0 "comparison_operator"
14172                         [(match_operand 1 "register_operand" "f")
14173                          (match_operand 2 "const0_operand" "X")])
14174           (label_ref (match_operand 3 "" ""))
14175           (pc)))
14176    (clobber (reg:CCFP FPSR_REG))
14177    (clobber (reg:CCFP FLAGS_REG))
14178    (clobber (match_scratch:HI 4 "=a"))]
14179   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14180    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14181    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14182    && SELECT_CC_MODE (GET_CODE (operands[0]),
14183                       operands[1], operands[2]) == CCFPmode
14184    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14185   "#")
14186
14187 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14188 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14189 ;; with a precedence over other operators and is always put in the first
14190 ;; place. Swap condition and operands to match ficom instruction.
14191
14192 (define_insn "*fp_jcc_8<mode>_387"
14193   [(set (pc)
14194         (if_then_else (match_operator 0 "comparison_operator"
14195                         [(match_operator 1 "float_operator"
14196                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14197                            (match_operand 3 "register_operand" "f,f")])
14198           (label_ref (match_operand 4 "" ""))
14199           (pc)))
14200    (clobber (reg:CCFP FPSR_REG))
14201    (clobber (reg:CCFP FLAGS_REG))
14202    (clobber (match_scratch:HI 5 "=a,a"))]
14203   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14204    && TARGET_USE_<MODE>MODE_FIOP
14205    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14206    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14207    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14208    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14209   "#")
14210
14211 (define_split
14212   [(set (pc)
14213         (if_then_else (match_operator 0 "comparison_operator"
14214                         [(match_operand 1 "register_operand" "")
14215                          (match_operand 2 "nonimmediate_operand" "")])
14216           (match_operand 3 "" "")
14217           (match_operand 4 "" "")))
14218    (clobber (reg:CCFP FPSR_REG))
14219    (clobber (reg:CCFP FLAGS_REG))]
14220   "reload_completed"
14221   [(const_int 0)]
14222 {
14223   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14224                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14225   DONE;
14226 })
14227
14228 (define_split
14229   [(set (pc)
14230         (if_then_else (match_operator 0 "comparison_operator"
14231                         [(match_operand 1 "register_operand" "")
14232                          (match_operand 2 "general_operand" "")])
14233           (match_operand 3 "" "")
14234           (match_operand 4 "" "")))
14235    (clobber (reg:CCFP FPSR_REG))
14236    (clobber (reg:CCFP FLAGS_REG))
14237    (clobber (match_scratch:HI 5 "=a"))]
14238   "reload_completed"
14239   [(const_int 0)]
14240 {
14241   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14242                         operands[3], operands[4], operands[5], NULL_RTX);
14243   DONE;
14244 })
14245
14246 (define_split
14247   [(set (pc)
14248         (if_then_else (match_operator 0 "comparison_operator"
14249                         [(match_operator 1 "float_operator"
14250                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14251                            (match_operand 3 "register_operand" "")])
14252           (match_operand 4 "" "")
14253           (match_operand 5 "" "")))
14254    (clobber (reg:CCFP FPSR_REG))
14255    (clobber (reg:CCFP FLAGS_REG))
14256    (clobber (match_scratch:HI 6 "=a"))]
14257   "reload_completed"
14258   [(const_int 0)]
14259 {
14260   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14261   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14262                         operands[3], operands[7],
14263                         operands[4], operands[5], operands[6], NULL_RTX);
14264   DONE;
14265 })
14266
14267 ;; %%% Kill this when reload knows how to do it.
14268 (define_split
14269   [(set (pc)
14270         (if_then_else (match_operator 0 "comparison_operator"
14271                         [(match_operator 1 "float_operator"
14272                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14273                            (match_operand 3 "register_operand" "")])
14274           (match_operand 4 "" "")
14275           (match_operand 5 "" "")))
14276    (clobber (reg:CCFP FPSR_REG))
14277    (clobber (reg:CCFP FLAGS_REG))
14278    (clobber (match_scratch:HI 6 "=a"))]
14279   "reload_completed"
14280   [(const_int 0)]
14281 {
14282   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14283   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14284   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14285                         operands[3], operands[7],
14286                         operands[4], operands[5], operands[6], operands[2]);
14287   DONE;
14288 })
14289 \f
14290 ;; Unconditional and other jump instructions
14291
14292 (define_insn "jump"
14293   [(set (pc)
14294         (label_ref (match_operand 0 "" "")))]
14295   ""
14296   "jmp\t%l0"
14297   [(set_attr "type" "ibr")
14298    (set (attr "length")
14299            (if_then_else (and (ge (minus (match_dup 0) (pc))
14300                                   (const_int -126))
14301                               (lt (minus (match_dup 0) (pc))
14302                                   (const_int 128)))
14303              (const_int 2)
14304              (const_int 5)))
14305    (set_attr "modrm" "0")])
14306
14307 (define_expand "indirect_jump"
14308   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14309   ""
14310   "")
14311
14312 (define_insn "*indirect_jump"
14313   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14314   "!TARGET_64BIT"
14315   "jmp\t%A0"
14316   [(set_attr "type" "ibr")
14317    (set_attr "length_immediate" "0")])
14318
14319 (define_insn "*indirect_jump_rtx64"
14320   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14321   "TARGET_64BIT"
14322   "jmp\t%A0"
14323   [(set_attr "type" "ibr")
14324    (set_attr "length_immediate" "0")])
14325
14326 (define_expand "tablejump"
14327   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14328               (use (label_ref (match_operand 1 "" "")))])]
14329   ""
14330 {
14331   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14332      relative.  Convert the relative address to an absolute address.  */
14333   if (flag_pic)
14334     {
14335       rtx op0, op1;
14336       enum rtx_code code;
14337
14338       /* We can't use @GOTOFF for text labels on VxWorks;
14339          see gotoff_operand.  */
14340       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14341         {
14342           code = PLUS;
14343           op0 = operands[0];
14344           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14345         }
14346       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14347         {
14348           code = PLUS;
14349           op0 = operands[0];
14350           op1 = pic_offset_table_rtx;
14351         }
14352       else
14353         {
14354           code = MINUS;
14355           op0 = pic_offset_table_rtx;
14356           op1 = operands[0];
14357         }
14358
14359       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14360                                          OPTAB_DIRECT);
14361     }
14362 })
14363
14364 (define_insn "*tablejump_1"
14365   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14366    (use (label_ref (match_operand 1 "" "")))]
14367   "!TARGET_64BIT"
14368   "jmp\t%A0"
14369   [(set_attr "type" "ibr")
14370    (set_attr "length_immediate" "0")])
14371
14372 (define_insn "*tablejump_1_rtx64"
14373   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14374    (use (label_ref (match_operand 1 "" "")))]
14375   "TARGET_64BIT"
14376   "jmp\t%A0"
14377   [(set_attr "type" "ibr")
14378    (set_attr "length_immediate" "0")])
14379 \f
14380 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14381
14382 (define_peephole2
14383   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14384    (set (match_operand:QI 1 "register_operand" "")
14385         (match_operator:QI 2 "ix86_comparison_operator"
14386           [(reg FLAGS_REG) (const_int 0)]))
14387    (set (match_operand 3 "q_regs_operand" "")
14388         (zero_extend (match_dup 1)))]
14389   "(peep2_reg_dead_p (3, operands[1])
14390     || operands_match_p (operands[1], operands[3]))
14391    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14392   [(set (match_dup 4) (match_dup 0))
14393    (set (strict_low_part (match_dup 5))
14394         (match_dup 2))]
14395 {
14396   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14397   operands[5] = gen_lowpart (QImode, operands[3]);
14398   ix86_expand_clear (operands[3]);
14399 })
14400
14401 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14402
14403 (define_peephole2
14404   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14405    (set (match_operand:QI 1 "register_operand" "")
14406         (match_operator:QI 2 "ix86_comparison_operator"
14407           [(reg FLAGS_REG) (const_int 0)]))
14408    (parallel [(set (match_operand 3 "q_regs_operand" "")
14409                    (zero_extend (match_dup 1)))
14410               (clobber (reg:CC FLAGS_REG))])]
14411   "(peep2_reg_dead_p (3, operands[1])
14412     || operands_match_p (operands[1], operands[3]))
14413    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14414   [(set (match_dup 4) (match_dup 0))
14415    (set (strict_low_part (match_dup 5))
14416         (match_dup 2))]
14417 {
14418   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14419   operands[5] = gen_lowpart (QImode, operands[3]);
14420   ix86_expand_clear (operands[3]);
14421 })
14422 \f
14423 ;; Call instructions.
14424
14425 ;; The predicates normally associated with named expanders are not properly
14426 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14427 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14428
14429 ;; Call subroutine returning no value.
14430
14431 (define_expand "call_pop"
14432   [(parallel [(call (match_operand:QI 0 "" "")
14433                     (match_operand:SI 1 "" ""))
14434               (set (reg:SI SP_REG)
14435                    (plus:SI (reg:SI SP_REG)
14436                             (match_operand:SI 3 "" "")))])]
14437   "!TARGET_64BIT"
14438 {
14439   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14440   DONE;
14441 })
14442
14443 (define_insn "*call_pop_0"
14444   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14445          (match_operand:SI 1 "" ""))
14446    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14447                             (match_operand:SI 2 "immediate_operand" "")))]
14448   "!TARGET_64BIT"
14449 {
14450   if (SIBLING_CALL_P (insn))
14451     return "jmp\t%P0";
14452   else
14453     return "call\t%P0";
14454 }
14455   [(set_attr "type" "call")])
14456
14457 (define_insn "*call_pop_1"
14458   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14459          (match_operand:SI 1 "" ""))
14460    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14461                             (match_operand:SI 2 "immediate_operand" "i")))]
14462   "!TARGET_64BIT"
14463 {
14464   if (constant_call_address_operand (operands[0], Pmode))
14465     {
14466       if (SIBLING_CALL_P (insn))
14467         return "jmp\t%P0";
14468       else
14469         return "call\t%P0";
14470     }
14471   if (SIBLING_CALL_P (insn))
14472     return "jmp\t%A0";
14473   else
14474     return "call\t%A0";
14475 }
14476   [(set_attr "type" "call")])
14477
14478 (define_expand "call"
14479   [(call (match_operand:QI 0 "" "")
14480          (match_operand 1 "" ""))
14481    (use (match_operand 2 "" ""))]
14482   ""
14483 {
14484   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14485   DONE;
14486 })
14487
14488 (define_expand "sibcall"
14489   [(call (match_operand:QI 0 "" "")
14490          (match_operand 1 "" ""))
14491    (use (match_operand 2 "" ""))]
14492   ""
14493 {
14494   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14495   DONE;
14496 })
14497
14498 (define_insn "*call_0"
14499   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14500          (match_operand 1 "" ""))]
14501   ""
14502 {
14503   if (SIBLING_CALL_P (insn))
14504     return "jmp\t%P0";
14505   else
14506     return "call\t%P0";
14507 }
14508   [(set_attr "type" "call")])
14509
14510 (define_insn "*call_1"
14511   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14512          (match_operand 1 "" ""))]
14513   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14514 {
14515   if (constant_call_address_operand (operands[0], Pmode))
14516     return "call\t%P0";
14517   return "call\t%A0";
14518 }
14519   [(set_attr "type" "call")])
14520
14521 (define_insn "*sibcall_1"
14522   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14523          (match_operand 1 "" ""))]
14524   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14525 {
14526   if (constant_call_address_operand (operands[0], Pmode))
14527     return "jmp\t%P0";
14528   return "jmp\t%A0";
14529 }
14530   [(set_attr "type" "call")])
14531
14532 (define_insn "*call_1_rex64"
14533   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14534          (match_operand 1 "" ""))]
14535   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14536    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14537 {
14538   if (constant_call_address_operand (operands[0], Pmode))
14539     return "call\t%P0";
14540   return "call\t%A0";
14541 }
14542   [(set_attr "type" "call")])
14543
14544 (define_insn "*call_1_rex64_large"
14545   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14546          (match_operand 1 "" ""))]
14547   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14548   "call\t%A0"
14549   [(set_attr "type" "call")])
14550
14551 (define_insn "*sibcall_1_rex64"
14552   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14553          (match_operand 1 "" ""))]
14554   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14555   "jmp\t%P0"
14556   [(set_attr "type" "call")])
14557
14558 (define_insn "*sibcall_1_rex64_v"
14559   [(call (mem:QI (reg:DI R11_REG))
14560          (match_operand 0 "" ""))]
14561   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14562   "jmp\t{*%%}r11"
14563   [(set_attr "type" "call")])
14564
14565
14566 ;; Call subroutine, returning value in operand 0
14567
14568 (define_expand "call_value_pop"
14569   [(parallel [(set (match_operand 0 "" "")
14570                    (call (match_operand:QI 1 "" "")
14571                          (match_operand:SI 2 "" "")))
14572               (set (reg:SI SP_REG)
14573                    (plus:SI (reg:SI SP_REG)
14574                             (match_operand:SI 4 "" "")))])]
14575   "!TARGET_64BIT"
14576 {
14577   ix86_expand_call (operands[0], operands[1], operands[2],
14578                     operands[3], operands[4], 0);
14579   DONE;
14580 })
14581
14582 (define_expand "call_value"
14583   [(set (match_operand 0 "" "")
14584         (call (match_operand:QI 1 "" "")
14585               (match_operand:SI 2 "" "")))
14586    (use (match_operand:SI 3 "" ""))]
14587   ;; Operand 2 not used on the i386.
14588   ""
14589 {
14590   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14591   DONE;
14592 })
14593
14594 (define_expand "sibcall_value"
14595   [(set (match_operand 0 "" "")
14596         (call (match_operand:QI 1 "" "")
14597               (match_operand:SI 2 "" "")))
14598    (use (match_operand:SI 3 "" ""))]
14599   ;; Operand 2 not used on the i386.
14600   ""
14601 {
14602   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14603   DONE;
14604 })
14605
14606 ;; Call subroutine returning any type.
14607
14608 (define_expand "untyped_call"
14609   [(parallel [(call (match_operand 0 "" "")
14610                     (const_int 0))
14611               (match_operand 1 "" "")
14612               (match_operand 2 "" "")])]
14613   ""
14614 {
14615   int i;
14616
14617   /* In order to give reg-stack an easier job in validating two
14618      coprocessor registers as containing a possible return value,
14619      simply pretend the untyped call returns a complex long double
14620      value.  */
14621
14622   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14623                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14624                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14625                     NULL, 0);
14626
14627   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14628     {
14629       rtx set = XVECEXP (operands[2], 0, i);
14630       emit_move_insn (SET_DEST (set), SET_SRC (set));
14631     }
14632
14633   /* The optimizer does not know that the call sets the function value
14634      registers we stored in the result block.  We avoid problems by
14635      claiming that all hard registers are used and clobbered at this
14636      point.  */
14637   emit_insn (gen_blockage ());
14638
14639   DONE;
14640 })
14641 \f
14642 ;; Prologue and epilogue instructions
14643
14644 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14645 ;; all of memory.  This blocks insns from being moved across this point.
14646
14647 (define_insn "blockage"
14648   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14649   ""
14650   ""
14651   [(set_attr "length" "0")])
14652
14653 ;; As USE insns aren't meaningful after reload, this is used instead
14654 ;; to prevent deleting instructions setting registers for PIC code
14655 (define_insn "prologue_use"
14656   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14657   ""
14658   ""
14659   [(set_attr "length" "0")])
14660
14661 ;; Insn emitted into the body of a function to return from a function.
14662 ;; This is only done if the function's epilogue is known to be simple.
14663 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14664
14665 (define_expand "return"
14666   [(return)]
14667   "ix86_can_use_return_insn_p ()"
14668 {
14669   if (current_function_pops_args)
14670     {
14671       rtx popc = GEN_INT (current_function_pops_args);
14672       emit_jump_insn (gen_return_pop_internal (popc));
14673       DONE;
14674     }
14675 })
14676
14677 (define_insn "return_internal"
14678   [(return)]
14679   "reload_completed"
14680   "ret"
14681   [(set_attr "length" "1")
14682    (set_attr "length_immediate" "0")
14683    (set_attr "modrm" "0")])
14684
14685 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14686 ;; instruction Athlon and K8 have.
14687
14688 (define_insn "return_internal_long"
14689   [(return)
14690    (unspec [(const_int 0)] UNSPEC_REP)]
14691   "reload_completed"
14692   "rep\;ret"
14693   [(set_attr "length" "1")
14694    (set_attr "length_immediate" "0")
14695    (set_attr "prefix_rep" "1")
14696    (set_attr "modrm" "0")])
14697
14698 (define_insn "return_pop_internal"
14699   [(return)
14700    (use (match_operand:SI 0 "const_int_operand" ""))]
14701   "reload_completed"
14702   "ret\t%0"
14703   [(set_attr "length" "3")
14704    (set_attr "length_immediate" "2")
14705    (set_attr "modrm" "0")])
14706
14707 (define_insn "return_indirect_internal"
14708   [(return)
14709    (use (match_operand:SI 0 "register_operand" "r"))]
14710   "reload_completed"
14711   "jmp\t%A0"
14712   [(set_attr "type" "ibr")
14713    (set_attr "length_immediate" "0")])
14714
14715 (define_insn "nop"
14716   [(const_int 0)]
14717   ""
14718   "nop"
14719   [(set_attr "length" "1")
14720    (set_attr "length_immediate" "0")
14721    (set_attr "modrm" "0")])
14722
14723 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14724 ;; branch prediction penalty for the third jump in a 16-byte
14725 ;; block on K8.
14726
14727 (define_insn "align"
14728   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14729   ""
14730 {
14731 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14732   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14733 #else
14734   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14735      The align insn is used to avoid 3 jump instructions in the row to improve
14736      branch prediction and the benefits hardly outweigh the cost of extra 8
14737      nops on the average inserted by full alignment pseudo operation.  */
14738 #endif
14739   return "";
14740 }
14741   [(set_attr "length" "16")])
14742
14743 (define_expand "prologue"
14744   [(const_int 0)]
14745   ""
14746   "ix86_expand_prologue (); DONE;")
14747
14748 (define_insn "set_got"
14749   [(set (match_operand:SI 0 "register_operand" "=r")
14750         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14751    (clobber (reg:CC FLAGS_REG))]
14752   "!TARGET_64BIT"
14753   { return output_set_got (operands[0], NULL_RTX); }
14754   [(set_attr "type" "multi")
14755    (set_attr "length" "12")])
14756
14757 (define_insn "set_got_labelled"
14758   [(set (match_operand:SI 0 "register_operand" "=r")
14759         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14760          UNSPEC_SET_GOT))
14761    (clobber (reg:CC FLAGS_REG))]
14762   "!TARGET_64BIT"
14763   { return output_set_got (operands[0], operands[1]); }
14764   [(set_attr "type" "multi")
14765    (set_attr "length" "12")])
14766
14767 (define_insn "set_got_rex64"
14768   [(set (match_operand:DI 0 "register_operand" "=r")
14769         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14770   "TARGET_64BIT"
14771   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14772   [(set_attr "type" "lea")
14773    (set_attr "length" "6")])
14774
14775 (define_insn "set_rip_rex64"
14776   [(set (match_operand:DI 0 "register_operand" "=r")
14777         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14778   "TARGET_64BIT"
14779   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14780   [(set_attr "type" "lea")
14781    (set_attr "length" "6")])
14782
14783 (define_insn "set_got_offset_rex64"
14784   [(set (match_operand:DI 0 "register_operand" "=r")
14785         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14786   "TARGET_64BIT"
14787   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14788   [(set_attr "type" "imov")
14789    (set_attr "length" "11")])
14790
14791 (define_expand "epilogue"
14792   [(const_int 0)]
14793   ""
14794   "ix86_expand_epilogue (1); DONE;")
14795
14796 (define_expand "sibcall_epilogue"
14797   [(const_int 0)]
14798   ""
14799   "ix86_expand_epilogue (0); DONE;")
14800
14801 (define_expand "eh_return"
14802   [(use (match_operand 0 "register_operand" ""))]
14803   ""
14804 {
14805   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14806
14807   /* Tricky bit: we write the address of the handler to which we will
14808      be returning into someone else's stack frame, one word below the
14809      stack address we wish to restore.  */
14810   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14811   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14812   tmp = gen_rtx_MEM (Pmode, tmp);
14813   emit_move_insn (tmp, ra);
14814
14815   if (Pmode == SImode)
14816     emit_jump_insn (gen_eh_return_si (sa));
14817   else
14818     emit_jump_insn (gen_eh_return_di (sa));
14819   emit_barrier ();
14820   DONE;
14821 })
14822
14823 (define_insn_and_split "eh_return_si"
14824   [(set (pc)
14825         (unspec [(match_operand:SI 0 "register_operand" "c")]
14826                  UNSPEC_EH_RETURN))]
14827   "!TARGET_64BIT"
14828   "#"
14829   "reload_completed"
14830   [(const_int 0)]
14831   "ix86_expand_epilogue (2); DONE;")
14832
14833 (define_insn_and_split "eh_return_di"
14834   [(set (pc)
14835         (unspec [(match_operand:DI 0 "register_operand" "c")]
14836                  UNSPEC_EH_RETURN))]
14837   "TARGET_64BIT"
14838   "#"
14839   "reload_completed"
14840   [(const_int 0)]
14841   "ix86_expand_epilogue (2); DONE;")
14842
14843 (define_insn "leave"
14844   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14845    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14846    (clobber (mem:BLK (scratch)))]
14847   "!TARGET_64BIT"
14848   "leave"
14849   [(set_attr "type" "leave")])
14850
14851 (define_insn "leave_rex64"
14852   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14853    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14854    (clobber (mem:BLK (scratch)))]
14855   "TARGET_64BIT"
14856   "leave"
14857   [(set_attr "type" "leave")])
14858 \f
14859 (define_expand "ffssi2"
14860   [(parallel
14861      [(set (match_operand:SI 0 "register_operand" "")
14862            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14863       (clobber (match_scratch:SI 2 ""))
14864       (clobber (reg:CC FLAGS_REG))])]
14865   ""
14866 {
14867   if (TARGET_CMOVE)
14868     {
14869       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14870       DONE;
14871     }
14872 })
14873
14874 (define_expand "ffs_cmove"
14875   [(set (match_dup 2) (const_int -1))
14876    (parallel [(set (reg:CCZ FLAGS_REG)
14877                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14878                                 (const_int 0)))
14879               (set (match_operand:SI 0 "nonimmediate_operand" "")
14880                    (ctz:SI (match_dup 1)))])
14881    (set (match_dup 0) (if_then_else:SI
14882                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14883                         (match_dup 2)
14884                         (match_dup 0)))
14885    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14886               (clobber (reg:CC FLAGS_REG))])]
14887   "TARGET_CMOVE"
14888   "operands[2] = gen_reg_rtx (SImode);")
14889
14890 (define_insn_and_split "*ffs_no_cmove"
14891   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14892         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14893    (clobber (match_scratch:SI 2 "=&q"))
14894    (clobber (reg:CC FLAGS_REG))]
14895   "!TARGET_CMOVE"
14896   "#"
14897   "&& reload_completed"
14898   [(parallel [(set (reg:CCZ FLAGS_REG)
14899                    (compare:CCZ (match_dup 1) (const_int 0)))
14900               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14901    (set (strict_low_part (match_dup 3))
14902         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14903    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14904               (clobber (reg:CC FLAGS_REG))])
14905    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14906               (clobber (reg:CC FLAGS_REG))])
14907    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14908               (clobber (reg:CC FLAGS_REG))])]
14909 {
14910   operands[3] = gen_lowpart (QImode, operands[2]);
14911   ix86_expand_clear (operands[2]);
14912 })
14913
14914 (define_insn "*ffssi_1"
14915   [(set (reg:CCZ FLAGS_REG)
14916         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14917                      (const_int 0)))
14918    (set (match_operand:SI 0 "register_operand" "=r")
14919         (ctz:SI (match_dup 1)))]
14920   ""
14921   "bsf{l}\t{%1, %0|%0, %1}"
14922   [(set_attr "prefix_0f" "1")])
14923
14924 (define_expand "ffsdi2"
14925   [(set (match_dup 2) (const_int -1))
14926    (parallel [(set (reg:CCZ FLAGS_REG)
14927                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
14928                                 (const_int 0)))
14929               (set (match_operand:DI 0 "nonimmediate_operand" "")
14930                    (ctz:DI (match_dup 1)))])
14931    (set (match_dup 0) (if_then_else:DI
14932                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14933                         (match_dup 2)
14934                         (match_dup 0)))
14935    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14936               (clobber (reg:CC FLAGS_REG))])]
14937   "TARGET_64BIT"
14938   "operands[2] = gen_reg_rtx (DImode);")
14939
14940 (define_insn "*ffsdi_1"
14941   [(set (reg:CCZ FLAGS_REG)
14942         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14943                      (const_int 0)))
14944    (set (match_operand:DI 0 "register_operand" "=r")
14945         (ctz:DI (match_dup 1)))]
14946   "TARGET_64BIT"
14947   "bsf{q}\t{%1, %0|%0, %1}"
14948   [(set_attr "prefix_0f" "1")])
14949
14950 (define_insn "ctzsi2"
14951   [(set (match_operand:SI 0 "register_operand" "=r")
14952         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14953    (clobber (reg:CC FLAGS_REG))]
14954   ""
14955   "bsf{l}\t{%1, %0|%0, %1}"
14956   [(set_attr "prefix_0f" "1")])
14957
14958 (define_insn "ctzdi2"
14959   [(set (match_operand:DI 0 "register_operand" "=r")
14960         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_64BIT"
14963   "bsf{q}\t{%1, %0|%0, %1}"
14964   [(set_attr "prefix_0f" "1")])
14965
14966 (define_expand "clzsi2"
14967   [(parallel
14968      [(set (match_operand:SI 0 "register_operand" "")
14969            (minus:SI (const_int 31)
14970                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14971       (clobber (reg:CC FLAGS_REG))])
14972    (parallel
14973      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14974       (clobber (reg:CC FLAGS_REG))])]
14975   ""
14976 {
14977   if (TARGET_ABM)
14978     {
14979       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14980       DONE;
14981     }
14982 })
14983
14984 (define_insn "clzsi2_abm"
14985   [(set (match_operand:SI 0 "register_operand" "=r")
14986         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14987    (clobber (reg:CC FLAGS_REG))]
14988   "TARGET_ABM"
14989   "lzcnt{l}\t{%1, %0|%0, %1}"
14990   [(set_attr "prefix_rep" "1")
14991    (set_attr "type" "bitmanip")
14992    (set_attr "mode" "SI")])
14993
14994 (define_insn "*bsr"
14995   [(set (match_operand:SI 0 "register_operand" "=r")
14996         (minus:SI (const_int 31)
14997                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14998    (clobber (reg:CC FLAGS_REG))]
14999   ""
15000   "bsr{l}\t{%1, %0|%0, %1}"
15001   [(set_attr "prefix_0f" "1")
15002    (set_attr "mode" "SI")])
15003
15004 (define_insn "popcountsi2"
15005   [(set (match_operand:SI 0 "register_operand" "=r")
15006         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15007    (clobber (reg:CC FLAGS_REG))]
15008   "TARGET_POPCNT"
15009   "popcnt{l}\t{%1, %0|%0, %1}"
15010   [(set_attr "prefix_rep" "1")
15011    (set_attr "type" "bitmanip")
15012    (set_attr "mode" "SI")])
15013
15014 (define_insn "*popcountsi2_cmp"
15015   [(set (reg FLAGS_REG)
15016         (compare
15017           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15018           (const_int 0)))
15019    (set (match_operand:SI 0 "register_operand" "=r")
15020         (popcount:SI (match_dup 1)))]
15021   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15022   "popcnt{l}\t{%1, %0|%0, %1}"
15023   [(set_attr "prefix_rep" "1")
15024    (set_attr "type" "bitmanip")
15025    (set_attr "mode" "SI")])
15026
15027 (define_insn "*popcountsi2_cmp_zext"
15028   [(set (reg FLAGS_REG)
15029         (compare
15030           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15031           (const_int 0)))
15032    (set (match_operand:DI 0 "register_operand" "=r")
15033         (zero_extend:DI(popcount:SI (match_dup 1))))]
15034   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15035   "popcnt{l}\t{%1, %0|%0, %1}"
15036   [(set_attr "prefix_rep" "1")
15037    (set_attr "type" "bitmanip")
15038    (set_attr "mode" "SI")])
15039
15040 (define_expand "bswapsi2"
15041   [(set (match_operand:SI 0 "register_operand" "")
15042         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15043   ""
15044 {
15045   if (!TARGET_BSWAP)
15046     {
15047       rtx x = operands[0];
15048
15049       emit_move_insn (x, operands[1]);
15050       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15051       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15052       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15053       DONE;
15054     }
15055 })
15056
15057 (define_insn "*bswapsi_1"
15058   [(set (match_operand:SI 0 "register_operand" "=r")
15059         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15060   "TARGET_BSWAP"
15061   "bswap\t%0"
15062   [(set_attr "prefix_0f" "1")
15063    (set_attr "length" "2")])
15064
15065 (define_insn "*bswaphi_lowpart_1"
15066   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15067         (bswap:HI (match_dup 0)))
15068    (clobber (reg:CC FLAGS_REG))]
15069   "TARGET_USE_XCHGB || optimize_size"
15070   "@
15071     xchg{b}\t{%h0, %b0|%b0, %h0}
15072     rol{w}\t{$8, %0|%0, 8}"
15073   [(set_attr "length" "2,4")
15074    (set_attr "mode" "QI,HI")])
15075
15076 (define_insn "bswaphi_lowpart"
15077   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15078         (bswap:HI (match_dup 0)))
15079    (clobber (reg:CC FLAGS_REG))]
15080   ""
15081   "rol{w}\t{$8, %0|%0, 8}"
15082   [(set_attr "length" "4")
15083    (set_attr "mode" "HI")])
15084
15085 (define_insn "bswapdi2"
15086   [(set (match_operand:DI 0 "register_operand" "=r")
15087         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15088   "TARGET_64BIT"
15089   "bswap\t%0"
15090   [(set_attr "prefix_0f" "1")
15091    (set_attr "length" "3")])
15092
15093 (define_expand "clzdi2"
15094   [(parallel
15095      [(set (match_operand:DI 0 "register_operand" "")
15096            (minus:DI (const_int 63)
15097                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15098       (clobber (reg:CC FLAGS_REG))])
15099    (parallel
15100      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15101       (clobber (reg:CC FLAGS_REG))])]
15102   "TARGET_64BIT"
15103 {
15104   if (TARGET_ABM)
15105     {
15106       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15107       DONE;
15108     }
15109 })
15110
15111 (define_insn "clzdi2_abm"
15112   [(set (match_operand:DI 0 "register_operand" "=r")
15113         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15114    (clobber (reg:CC FLAGS_REG))]
15115   "TARGET_64BIT && TARGET_ABM"
15116   "lzcnt{q}\t{%1, %0|%0, %1}"
15117   [(set_attr "prefix_rep" "1")
15118    (set_attr "type" "bitmanip")
15119    (set_attr "mode" "DI")])
15120
15121 (define_insn "*bsr_rex64"
15122   [(set (match_operand:DI 0 "register_operand" "=r")
15123         (minus:DI (const_int 63)
15124                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15125    (clobber (reg:CC FLAGS_REG))]
15126   "TARGET_64BIT"
15127   "bsr{q}\t{%1, %0|%0, %1}"
15128   [(set_attr "prefix_0f" "1")
15129    (set_attr "mode" "DI")])
15130
15131 (define_insn "popcountdi2"
15132   [(set (match_operand:DI 0 "register_operand" "=r")
15133         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15134    (clobber (reg:CC FLAGS_REG))]
15135   "TARGET_64BIT && TARGET_POPCNT"
15136   "popcnt{q}\t{%1, %0|%0, %1}"
15137   [(set_attr "prefix_rep" "1")
15138    (set_attr "type" "bitmanip")
15139    (set_attr "mode" "DI")])
15140
15141 (define_insn "*popcountdi2_cmp"
15142   [(set (reg FLAGS_REG)
15143         (compare
15144           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15145           (const_int 0)))
15146    (set (match_operand:DI 0 "register_operand" "=r")
15147         (popcount:DI (match_dup 1)))]
15148   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15149   "popcnt{q}\t{%1, %0|%0, %1}"
15150   [(set_attr "prefix_rep" "1")
15151    (set_attr "type" "bitmanip")
15152    (set_attr "mode" "DI")])
15153
15154 (define_expand "clzhi2"
15155   [(parallel
15156      [(set (match_operand:HI 0 "register_operand" "")
15157            (minus:HI (const_int 15)
15158                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15159       (clobber (reg:CC FLAGS_REG))])
15160    (parallel
15161      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15162       (clobber (reg:CC FLAGS_REG))])]
15163   ""
15164 {
15165   if (TARGET_ABM)
15166     {
15167       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15168       DONE;
15169     }
15170 })
15171
15172 (define_insn "clzhi2_abm"
15173   [(set (match_operand:HI 0 "register_operand" "=r")
15174         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15175    (clobber (reg:CC FLAGS_REG))]
15176   "TARGET_ABM"
15177   "lzcnt{w}\t{%1, %0|%0, %1}"
15178   [(set_attr "prefix_rep" "1")
15179    (set_attr "type" "bitmanip")
15180    (set_attr "mode" "HI")])
15181
15182 (define_insn "*bsrhi"
15183   [(set (match_operand:HI 0 "register_operand" "=r")
15184         (minus:HI (const_int 15)
15185                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15186    (clobber (reg:CC FLAGS_REG))]
15187   ""
15188   "bsr{w}\t{%1, %0|%0, %1}"
15189   [(set_attr "prefix_0f" "1")
15190    (set_attr "mode" "HI")])
15191
15192 (define_insn "popcounthi2"
15193   [(set (match_operand:HI 0 "register_operand" "=r")
15194         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15195    (clobber (reg:CC FLAGS_REG))]
15196   "TARGET_POPCNT"
15197   "popcnt{w}\t{%1, %0|%0, %1}"
15198   [(set_attr "prefix_rep" "1")
15199    (set_attr "type" "bitmanip")
15200    (set_attr "mode" "HI")])
15201
15202 (define_insn "*popcounthi2_cmp"
15203   [(set (reg FLAGS_REG)
15204         (compare
15205           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15206           (const_int 0)))
15207    (set (match_operand:HI 0 "register_operand" "=r")
15208         (popcount:HI (match_dup 1)))]
15209   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15210   "popcnt{w}\t{%1, %0|%0, %1}"
15211   [(set_attr "prefix_rep" "1")
15212    (set_attr "type" "bitmanip")
15213    (set_attr "mode" "HI")])
15214
15215 (define_expand "paritydi2"
15216   [(set (match_operand:DI 0 "register_operand" "")
15217         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15218   "! TARGET_POPCNT"
15219 {
15220   rtx scratch = gen_reg_rtx (QImode);
15221   rtx cond;
15222
15223   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15224                                 NULL_RTX, operands[1]));
15225
15226   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15227                          gen_rtx_REG (CCmode, FLAGS_REG),
15228                          const0_rtx);
15229   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15230
15231   if (TARGET_64BIT)
15232     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15233   else
15234     {
15235       rtx tmp = gen_reg_rtx (SImode);
15236
15237       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15238       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15239     }
15240   DONE;
15241 })
15242
15243 (define_insn_and_split "paritydi2_cmp"
15244   [(set (reg:CC FLAGS_REG)
15245         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15246    (clobber (match_scratch:DI 0 "=r"))
15247    (clobber (match_scratch:SI 1 "=&r"))
15248    (clobber (match_scratch:HI 2 "=Q"))]
15249   "! TARGET_POPCNT"
15250   "#"
15251   "&& reload_completed"
15252   [(parallel
15253      [(set (match_dup 1)
15254            (xor:SI (match_dup 1) (match_dup 4)))
15255       (clobber (reg:CC FLAGS_REG))])
15256    (parallel
15257      [(set (reg:CC FLAGS_REG)
15258            (parity:CC (match_dup 1)))
15259       (clobber (match_dup 1))
15260       (clobber (match_dup 2))])]
15261 {
15262   operands[4] = gen_lowpart (SImode, operands[3]);
15263
15264   if (TARGET_64BIT)
15265     {
15266       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15267       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15268     }
15269   else
15270     operands[1] = gen_highpart (SImode, operands[3]);
15271 })
15272
15273 (define_expand "paritysi2"
15274   [(set (match_operand:SI 0 "register_operand" "")
15275         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15276   "! TARGET_POPCNT"
15277 {
15278   rtx scratch = gen_reg_rtx (QImode);
15279   rtx cond;
15280
15281   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15282
15283   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15284                          gen_rtx_REG (CCmode, FLAGS_REG),
15285                          const0_rtx);
15286   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15287
15288   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15289   DONE;
15290 })
15291
15292 (define_insn_and_split "paritysi2_cmp"
15293   [(set (reg:CC FLAGS_REG)
15294         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15295    (clobber (match_scratch:SI 0 "=r"))
15296    (clobber (match_scratch:HI 1 "=&Q"))]
15297   "! TARGET_POPCNT"
15298   "#"
15299   "&& reload_completed"
15300   [(parallel
15301      [(set (match_dup 1)
15302            (xor:HI (match_dup 1) (match_dup 3)))
15303       (clobber (reg:CC FLAGS_REG))])
15304    (parallel
15305      [(set (reg:CC FLAGS_REG)
15306            (parity:CC (match_dup 1)))
15307       (clobber (match_dup 1))])]
15308 {
15309   operands[3] = gen_lowpart (HImode, operands[2]);
15310
15311   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15312   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15313 })
15314
15315 (define_insn "*parityhi2_cmp"
15316   [(set (reg:CC FLAGS_REG)
15317         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15318    (clobber (match_scratch:HI 0 "=Q"))]
15319   "! TARGET_POPCNT"
15320   "xor{b}\t{%h0, %b0|%b0, %h0}"
15321   [(set_attr "length" "2")
15322    (set_attr "mode" "HI")])
15323
15324 (define_insn "*parityqi2_cmp"
15325   [(set (reg:CC FLAGS_REG)
15326         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15327   "! TARGET_POPCNT"
15328   "test{b}\t%0, %0"
15329   [(set_attr "length" "2")
15330    (set_attr "mode" "QI")])
15331 \f
15332 ;; Thread-local storage patterns for ELF.
15333 ;;
15334 ;; Note that these code sequences must appear exactly as shown
15335 ;; in order to allow linker relaxation.
15336
15337 (define_insn "*tls_global_dynamic_32_gnu"
15338   [(set (match_operand:SI 0 "register_operand" "=a")
15339         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15340                     (match_operand:SI 2 "tls_symbolic_operand" "")
15341                     (match_operand:SI 3 "call_insn_operand" "")]
15342                     UNSPEC_TLS_GD))
15343    (clobber (match_scratch:SI 4 "=d"))
15344    (clobber (match_scratch:SI 5 "=c"))
15345    (clobber (reg:CC FLAGS_REG))]
15346   "!TARGET_64BIT && TARGET_GNU_TLS"
15347   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15348   [(set_attr "type" "multi")
15349    (set_attr "length" "12")])
15350
15351 (define_insn "*tls_global_dynamic_32_sun"
15352   [(set (match_operand:SI 0 "register_operand" "=a")
15353         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15354                     (match_operand:SI 2 "tls_symbolic_operand" "")
15355                     (match_operand:SI 3 "call_insn_operand" "")]
15356                     UNSPEC_TLS_GD))
15357    (clobber (match_scratch:SI 4 "=d"))
15358    (clobber (match_scratch:SI 5 "=c"))
15359    (clobber (reg:CC FLAGS_REG))]
15360   "!TARGET_64BIT && TARGET_SUN_TLS"
15361   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15362         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15363   [(set_attr "type" "multi")
15364    (set_attr "length" "14")])
15365
15366 (define_expand "tls_global_dynamic_32"
15367   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15368                    (unspec:SI
15369                     [(match_dup 2)
15370                      (match_operand:SI 1 "tls_symbolic_operand" "")
15371                      (match_dup 3)]
15372                     UNSPEC_TLS_GD))
15373               (clobber (match_scratch:SI 4 ""))
15374               (clobber (match_scratch:SI 5 ""))
15375               (clobber (reg:CC FLAGS_REG))])]
15376   ""
15377 {
15378   if (flag_pic)
15379     operands[2] = pic_offset_table_rtx;
15380   else
15381     {
15382       operands[2] = gen_reg_rtx (Pmode);
15383       emit_insn (gen_set_got (operands[2]));
15384     }
15385   if (TARGET_GNU2_TLS)
15386     {
15387        emit_insn (gen_tls_dynamic_gnu2_32
15388                   (operands[0], operands[1], operands[2]));
15389        DONE;
15390     }
15391   operands[3] = ix86_tls_get_addr ();
15392 })
15393
15394 (define_insn "*tls_global_dynamic_64"
15395   [(set (match_operand:DI 0 "register_operand" "=a")
15396         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15397                  (match_operand:DI 3 "" "")))
15398    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15399               UNSPEC_TLS_GD)]
15400   "TARGET_64BIT"
15401   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15402   [(set_attr "type" "multi")
15403    (set_attr "length" "16")])
15404
15405 (define_expand "tls_global_dynamic_64"
15406   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15407                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15408               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15409                          UNSPEC_TLS_GD)])]
15410   ""
15411 {
15412   if (TARGET_GNU2_TLS)
15413     {
15414        emit_insn (gen_tls_dynamic_gnu2_64
15415                   (operands[0], operands[1]));
15416        DONE;
15417     }
15418   operands[2] = ix86_tls_get_addr ();
15419 })
15420
15421 (define_insn "*tls_local_dynamic_base_32_gnu"
15422   [(set (match_operand:SI 0 "register_operand" "=a")
15423         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15424                     (match_operand:SI 2 "call_insn_operand" "")]
15425                    UNSPEC_TLS_LD_BASE))
15426    (clobber (match_scratch:SI 3 "=d"))
15427    (clobber (match_scratch:SI 4 "=c"))
15428    (clobber (reg:CC FLAGS_REG))]
15429   "!TARGET_64BIT && TARGET_GNU_TLS"
15430   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15431   [(set_attr "type" "multi")
15432    (set_attr "length" "11")])
15433
15434 (define_insn "*tls_local_dynamic_base_32_sun"
15435   [(set (match_operand:SI 0 "register_operand" "=a")
15436         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15437                     (match_operand:SI 2 "call_insn_operand" "")]
15438                    UNSPEC_TLS_LD_BASE))
15439    (clobber (match_scratch:SI 3 "=d"))
15440    (clobber (match_scratch:SI 4 "=c"))
15441    (clobber (reg:CC FLAGS_REG))]
15442   "!TARGET_64BIT && TARGET_SUN_TLS"
15443   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15444         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15445   [(set_attr "type" "multi")
15446    (set_attr "length" "13")])
15447
15448 (define_expand "tls_local_dynamic_base_32"
15449   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15450                    (unspec:SI [(match_dup 1) (match_dup 2)]
15451                               UNSPEC_TLS_LD_BASE))
15452               (clobber (match_scratch:SI 3 ""))
15453               (clobber (match_scratch:SI 4 ""))
15454               (clobber (reg:CC FLAGS_REG))])]
15455   ""
15456 {
15457   if (flag_pic)
15458     operands[1] = pic_offset_table_rtx;
15459   else
15460     {
15461       operands[1] = gen_reg_rtx (Pmode);
15462       emit_insn (gen_set_got (operands[1]));
15463     }
15464   if (TARGET_GNU2_TLS)
15465     {
15466        emit_insn (gen_tls_dynamic_gnu2_32
15467                   (operands[0], ix86_tls_module_base (), operands[1]));
15468        DONE;
15469     }
15470   operands[2] = ix86_tls_get_addr ();
15471 })
15472
15473 (define_insn "*tls_local_dynamic_base_64"
15474   [(set (match_operand:DI 0 "register_operand" "=a")
15475         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15476                  (match_operand:DI 2 "" "")))
15477    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15478   "TARGET_64BIT"
15479   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15480   [(set_attr "type" "multi")
15481    (set_attr "length" "12")])
15482
15483 (define_expand "tls_local_dynamic_base_64"
15484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15485                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15486               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15487   ""
15488 {
15489   if (TARGET_GNU2_TLS)
15490     {
15491        emit_insn (gen_tls_dynamic_gnu2_64
15492                   (operands[0], ix86_tls_module_base ()));
15493        DONE;
15494     }
15495   operands[1] = ix86_tls_get_addr ();
15496 })
15497
15498 ;; Local dynamic of a single variable is a lose.  Show combine how
15499 ;; to convert that back to global dynamic.
15500
15501 (define_insn_and_split "*tls_local_dynamic_32_once"
15502   [(set (match_operand:SI 0 "register_operand" "=a")
15503         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15504                              (match_operand:SI 2 "call_insn_operand" "")]
15505                             UNSPEC_TLS_LD_BASE)
15506                  (const:SI (unspec:SI
15507                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15508                             UNSPEC_DTPOFF))))
15509    (clobber (match_scratch:SI 4 "=d"))
15510    (clobber (match_scratch:SI 5 "=c"))
15511    (clobber (reg:CC FLAGS_REG))]
15512   ""
15513   "#"
15514   ""
15515   [(parallel [(set (match_dup 0)
15516                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15517                               UNSPEC_TLS_GD))
15518               (clobber (match_dup 4))
15519               (clobber (match_dup 5))
15520               (clobber (reg:CC FLAGS_REG))])]
15521   "")
15522
15523 ;; Load and add the thread base pointer from %gs:0.
15524
15525 (define_insn "*load_tp_si"
15526   [(set (match_operand:SI 0 "register_operand" "=r")
15527         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15528   "!TARGET_64BIT"
15529   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15530   [(set_attr "type" "imov")
15531    (set_attr "modrm" "0")
15532    (set_attr "length" "7")
15533    (set_attr "memory" "load")
15534    (set_attr "imm_disp" "false")])
15535
15536 (define_insn "*add_tp_si"
15537   [(set (match_operand:SI 0 "register_operand" "=r")
15538         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15539                  (match_operand:SI 1 "register_operand" "0")))
15540    (clobber (reg:CC FLAGS_REG))]
15541   "!TARGET_64BIT"
15542   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15543   [(set_attr "type" "alu")
15544    (set_attr "modrm" "0")
15545    (set_attr "length" "7")
15546    (set_attr "memory" "load")
15547    (set_attr "imm_disp" "false")])
15548
15549 (define_insn "*load_tp_di"
15550   [(set (match_operand:DI 0 "register_operand" "=r")
15551         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15552   "TARGET_64BIT"
15553   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15554   [(set_attr "type" "imov")
15555    (set_attr "modrm" "0")
15556    (set_attr "length" "7")
15557    (set_attr "memory" "load")
15558    (set_attr "imm_disp" "false")])
15559
15560 (define_insn "*add_tp_di"
15561   [(set (match_operand:DI 0 "register_operand" "=r")
15562         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15563                  (match_operand:DI 1 "register_operand" "0")))
15564    (clobber (reg:CC FLAGS_REG))]
15565   "TARGET_64BIT"
15566   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15567   [(set_attr "type" "alu")
15568    (set_attr "modrm" "0")
15569    (set_attr "length" "7")
15570    (set_attr "memory" "load")
15571    (set_attr "imm_disp" "false")])
15572
15573 ;; GNU2 TLS patterns can be split.
15574
15575 (define_expand "tls_dynamic_gnu2_32"
15576   [(set (match_dup 3)
15577         (plus:SI (match_operand:SI 2 "register_operand" "")
15578                  (const:SI
15579                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15580                              UNSPEC_TLSDESC))))
15581    (parallel
15582     [(set (match_operand:SI 0 "register_operand" "")
15583           (unspec:SI [(match_dup 1) (match_dup 3)
15584                       (match_dup 2) (reg:SI SP_REG)]
15585                       UNSPEC_TLSDESC))
15586      (clobber (reg:CC FLAGS_REG))])]
15587   "!TARGET_64BIT && TARGET_GNU2_TLS"
15588 {
15589   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15590   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15591 })
15592
15593 (define_insn "*tls_dynamic_lea_32"
15594   [(set (match_operand:SI 0 "register_operand" "=r")
15595         (plus:SI (match_operand:SI 1 "register_operand" "b")
15596                  (const:SI
15597                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15598                               UNSPEC_TLSDESC))))]
15599   "!TARGET_64BIT && TARGET_GNU2_TLS"
15600   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15601   [(set_attr "type" "lea")
15602    (set_attr "mode" "SI")
15603    (set_attr "length" "6")
15604    (set_attr "length_address" "4")])
15605
15606 (define_insn "*tls_dynamic_call_32"
15607   [(set (match_operand:SI 0 "register_operand" "=a")
15608         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15609                     (match_operand:SI 2 "register_operand" "0")
15610                     ;; we have to make sure %ebx still points to the GOT
15611                     (match_operand:SI 3 "register_operand" "b")
15612                     (reg:SI SP_REG)]
15613                    UNSPEC_TLSDESC))
15614    (clobber (reg:CC FLAGS_REG))]
15615   "!TARGET_64BIT && TARGET_GNU2_TLS"
15616   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15617   [(set_attr "type" "call")
15618    (set_attr "length" "2")
15619    (set_attr "length_address" "0")])
15620
15621 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15622   [(set (match_operand:SI 0 "register_operand" "=&a")
15623         (plus:SI
15624          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15625                      (match_operand:SI 4 "" "")
15626                      (match_operand:SI 2 "register_operand" "b")
15627                      (reg:SI SP_REG)]
15628                     UNSPEC_TLSDESC)
15629          (const:SI (unspec:SI
15630                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15631                     UNSPEC_DTPOFF))))
15632    (clobber (reg:CC FLAGS_REG))]
15633   "!TARGET_64BIT && TARGET_GNU2_TLS"
15634   "#"
15635   ""
15636   [(set (match_dup 0) (match_dup 5))]
15637 {
15638   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15639   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15640 })
15641
15642 (define_expand "tls_dynamic_gnu2_64"
15643   [(set (match_dup 2)
15644         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15645                    UNSPEC_TLSDESC))
15646    (parallel
15647     [(set (match_operand:DI 0 "register_operand" "")
15648           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15649                      UNSPEC_TLSDESC))
15650      (clobber (reg:CC FLAGS_REG))])]
15651   "TARGET_64BIT && TARGET_GNU2_TLS"
15652 {
15653   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15654   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15655 })
15656
15657 (define_insn "*tls_dynamic_lea_64"
15658   [(set (match_operand:DI 0 "register_operand" "=r")
15659         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15660                    UNSPEC_TLSDESC))]
15661   "TARGET_64BIT && TARGET_GNU2_TLS"
15662   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15663   [(set_attr "type" "lea")
15664    (set_attr "mode" "DI")
15665    (set_attr "length" "7")
15666    (set_attr "length_address" "4")])
15667
15668 (define_insn "*tls_dynamic_call_64"
15669   [(set (match_operand:DI 0 "register_operand" "=a")
15670         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15671                     (match_operand:DI 2 "register_operand" "0")
15672                     (reg:DI SP_REG)]
15673                    UNSPEC_TLSDESC))
15674    (clobber (reg:CC FLAGS_REG))]
15675   "TARGET_64BIT && TARGET_GNU2_TLS"
15676   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15677   [(set_attr "type" "call")
15678    (set_attr "length" "2")
15679    (set_attr "length_address" "0")])
15680
15681 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15682   [(set (match_operand:DI 0 "register_operand" "=&a")
15683         (plus:DI
15684          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15685                      (match_operand:DI 3 "" "")
15686                      (reg:DI SP_REG)]
15687                     UNSPEC_TLSDESC)
15688          (const:DI (unspec:DI
15689                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15690                     UNSPEC_DTPOFF))))
15691    (clobber (reg:CC FLAGS_REG))]
15692   "TARGET_64BIT && TARGET_GNU2_TLS"
15693   "#"
15694   ""
15695   [(set (match_dup 0) (match_dup 4))]
15696 {
15697   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15698   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15699 })
15700
15701 ;;
15702 \f
15703 ;; These patterns match the binary 387 instructions for addM3, subM3,
15704 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15705 ;; SFmode.  The first is the normal insn, the second the same insn but
15706 ;; with one operand a conversion, and the third the same insn but with
15707 ;; the other operand a conversion.  The conversion may be SFmode or
15708 ;; SImode if the target mode DFmode, but only SImode if the target mode
15709 ;; is SFmode.
15710
15711 ;; Gcc is slightly more smart about handling normal two address instructions
15712 ;; so use special patterns for add and mull.
15713
15714 (define_insn "*fop_sf_comm_mixed"
15715   [(set (match_operand:SF 0 "register_operand" "=f,x")
15716         (match_operator:SF 3 "binary_fp_operator"
15717                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15718                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15719   "TARGET_MIX_SSE_I387
15720    && COMMUTATIVE_ARITH_P (operands[3])
15721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15722   "* return output_387_binary_op (insn, operands);"
15723   [(set (attr "type")
15724         (if_then_else (eq_attr "alternative" "1")
15725            (if_then_else (match_operand:SF 3 "mult_operator" "")
15726               (const_string "ssemul")
15727               (const_string "sseadd"))
15728            (if_then_else (match_operand:SF 3 "mult_operator" "")
15729               (const_string "fmul")
15730               (const_string "fop"))))
15731    (set_attr "mode" "SF")])
15732
15733 (define_insn "*fop_sf_comm_sse"
15734   [(set (match_operand:SF 0 "register_operand" "=x")
15735         (match_operator:SF 3 "binary_fp_operator"
15736                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15737                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15738   "TARGET_SSE_MATH
15739    && COMMUTATIVE_ARITH_P (operands[3])
15740    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15741   "* return output_387_binary_op (insn, operands);"
15742   [(set (attr "type")
15743         (if_then_else (match_operand:SF 3 "mult_operator" "")
15744            (const_string "ssemul")
15745            (const_string "sseadd")))
15746    (set_attr "mode" "SF")])
15747
15748 (define_insn "*fop_sf_comm_i387"
15749   [(set (match_operand:SF 0 "register_operand" "=f")
15750         (match_operator:SF 3 "binary_fp_operator"
15751                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15752                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15753   "TARGET_80387
15754    && COMMUTATIVE_ARITH_P (operands[3])
15755    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15756   "* return output_387_binary_op (insn, operands);"
15757   [(set (attr "type")
15758         (if_then_else (match_operand:SF 3 "mult_operator" "")
15759            (const_string "fmul")
15760            (const_string "fop")))
15761    (set_attr "mode" "SF")])
15762
15763 (define_insn "*fop_sf_1_mixed"
15764   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15765         (match_operator:SF 3 "binary_fp_operator"
15766                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15767                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15768   "TARGET_MIX_SSE_I387
15769    && !COMMUTATIVE_ARITH_P (operands[3])
15770    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15771   "* return output_387_binary_op (insn, operands);"
15772   [(set (attr "type")
15773         (cond [(and (eq_attr "alternative" "2")
15774                     (match_operand:SF 3 "mult_operator" ""))
15775                  (const_string "ssemul")
15776                (and (eq_attr "alternative" "2")
15777                     (match_operand:SF 3 "div_operator" ""))
15778                  (const_string "ssediv")
15779                (eq_attr "alternative" "2")
15780                  (const_string "sseadd")
15781                (match_operand:SF 3 "mult_operator" "")
15782                  (const_string "fmul")
15783                (match_operand:SF 3 "div_operator" "")
15784                  (const_string "fdiv")
15785               ]
15786               (const_string "fop")))
15787    (set_attr "mode" "SF")])
15788
15789 (define_insn "*rcpsf2_sse"
15790   [(set (match_operand:SF 0 "register_operand" "=x")
15791         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15792                    UNSPEC_RCP))]
15793   "TARGET_SSE_MATH"
15794   "rcpss\t{%1, %0|%0, %1}"
15795   [(set_attr "type" "sse")
15796    (set_attr "mode" "SF")])
15797
15798 (define_insn "*fop_sf_1_sse"
15799   [(set (match_operand:SF 0 "register_operand" "=x")
15800         (match_operator:SF 3 "binary_fp_operator"
15801                         [(match_operand:SF 1 "register_operand" "0")
15802                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15803   "TARGET_SSE_MATH
15804    && !COMMUTATIVE_ARITH_P (operands[3])"
15805   "* return output_387_binary_op (insn, operands);"
15806   [(set (attr "type")
15807         (cond [(match_operand:SF 3 "mult_operator" "")
15808                  (const_string "ssemul")
15809                (match_operand:SF 3 "div_operator" "")
15810                  (const_string "ssediv")
15811               ]
15812               (const_string "sseadd")))
15813    (set_attr "mode" "SF")])
15814
15815 ;; This pattern is not fully shadowed by the pattern above.
15816 (define_insn "*fop_sf_1_i387"
15817   [(set (match_operand:SF 0 "register_operand" "=f,f")
15818         (match_operator:SF 3 "binary_fp_operator"
15819                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15820                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15821   "TARGET_80387 && !TARGET_SSE_MATH
15822    && !COMMUTATIVE_ARITH_P (operands[3])
15823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15824   "* return output_387_binary_op (insn, operands);"
15825   [(set (attr "type")
15826         (cond [(match_operand:SF 3 "mult_operator" "")
15827                  (const_string "fmul")
15828                (match_operand:SF 3 "div_operator" "")
15829                  (const_string "fdiv")
15830               ]
15831               (const_string "fop")))
15832    (set_attr "mode" "SF")])
15833
15834 ;; ??? Add SSE splitters for these!
15835 (define_insn "*fop_sf_2<mode>_i387"
15836   [(set (match_operand:SF 0 "register_operand" "=f,f")
15837         (match_operator:SF 3 "binary_fp_operator"
15838           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15839            (match_operand:SF 2 "register_operand" "0,0")]))]
15840   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15841   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15842   [(set (attr "type")
15843         (cond [(match_operand:SF 3 "mult_operator" "")
15844                  (const_string "fmul")
15845                (match_operand:SF 3 "div_operator" "")
15846                  (const_string "fdiv")
15847               ]
15848               (const_string "fop")))
15849    (set_attr "fp_int_src" "true")
15850    (set_attr "mode" "<MODE>")])
15851
15852 (define_insn "*fop_sf_3<mode>_i387"
15853   [(set (match_operand:SF 0 "register_operand" "=f,f")
15854         (match_operator:SF 3 "binary_fp_operator"
15855           [(match_operand:SF 1 "register_operand" "0,0")
15856            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15857   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15858   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15859   [(set (attr "type")
15860         (cond [(match_operand:SF 3 "mult_operator" "")
15861                  (const_string "fmul")
15862                (match_operand:SF 3 "div_operator" "")
15863                  (const_string "fdiv")
15864               ]
15865               (const_string "fop")))
15866    (set_attr "fp_int_src" "true")
15867    (set_attr "mode" "<MODE>")])
15868
15869 (define_insn "*fop_df_comm_mixed"
15870   [(set (match_operand:DF 0 "register_operand" "=f,x")
15871         (match_operator:DF 3 "binary_fp_operator"
15872           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15873            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15874   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15875    && COMMUTATIVE_ARITH_P (operands[3])
15876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15877   "* return output_387_binary_op (insn, operands);"
15878   [(set (attr "type")
15879         (if_then_else (eq_attr "alternative" "1")
15880            (if_then_else (match_operand:DF 3 "mult_operator" "")
15881               (const_string "ssemul")
15882               (const_string "sseadd"))
15883            (if_then_else (match_operand:DF 3 "mult_operator" "")
15884               (const_string "fmul")
15885               (const_string "fop"))))
15886    (set_attr "mode" "DF")])
15887
15888 (define_insn "*fop_df_comm_sse"
15889   [(set (match_operand:DF 0 "register_operand" "=x")
15890         (match_operator:DF 3 "binary_fp_operator"
15891           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15892            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15893   "TARGET_SSE2 && TARGET_SSE_MATH
15894    && COMMUTATIVE_ARITH_P (operands[3])
15895    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15896   "* return output_387_binary_op (insn, operands);"
15897   [(set (attr "type")
15898         (if_then_else (match_operand:DF 3 "mult_operator" "")
15899            (const_string "ssemul")
15900            (const_string "sseadd")))
15901    (set_attr "mode" "DF")])
15902
15903 (define_insn "*fop_df_comm_i387"
15904   [(set (match_operand:DF 0 "register_operand" "=f")
15905         (match_operator:DF 3 "binary_fp_operator"
15906                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15907                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15908   "TARGET_80387
15909    && COMMUTATIVE_ARITH_P (operands[3])
15910    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911   "* return output_387_binary_op (insn, operands);"
15912   [(set (attr "type")
15913         (if_then_else (match_operand:DF 3 "mult_operator" "")
15914            (const_string "fmul")
15915            (const_string "fop")))
15916    (set_attr "mode" "DF")])
15917
15918 (define_insn "*fop_df_1_mixed"
15919   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15920         (match_operator:DF 3 "binary_fp_operator"
15921           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15922            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15923   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15924    && !COMMUTATIVE_ARITH_P (operands[3])
15925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15926   "* return output_387_binary_op (insn, operands);"
15927   [(set (attr "type")
15928         (cond [(and (eq_attr "alternative" "2")
15929                     (match_operand:DF 3 "mult_operator" ""))
15930                  (const_string "ssemul")
15931                (and (eq_attr "alternative" "2")
15932                     (match_operand:DF 3 "div_operator" ""))
15933                  (const_string "ssediv")
15934                (eq_attr "alternative" "2")
15935                  (const_string "sseadd")
15936                (match_operand:DF 3 "mult_operator" "")
15937                  (const_string "fmul")
15938                (match_operand:DF 3 "div_operator" "")
15939                  (const_string "fdiv")
15940               ]
15941               (const_string "fop")))
15942    (set_attr "mode" "DF")])
15943
15944 (define_insn "*fop_df_1_sse"
15945   [(set (match_operand:DF 0 "register_operand" "=x")
15946         (match_operator:DF 3 "binary_fp_operator"
15947           [(match_operand:DF 1 "register_operand" "0")
15948            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15949   "TARGET_SSE2 && TARGET_SSE_MATH
15950    && !COMMUTATIVE_ARITH_P (operands[3])"
15951   "* return output_387_binary_op (insn, operands);"
15952   [(set_attr "mode" "DF")
15953    (set (attr "type")
15954         (cond [(match_operand:DF 3 "mult_operator" "")
15955                  (const_string "ssemul")
15956                (match_operand:DF 3 "div_operator" "")
15957                  (const_string "ssediv")
15958               ]
15959               (const_string "sseadd")))])
15960
15961 ;; This pattern is not fully shadowed by the pattern above.
15962 (define_insn "*fop_df_1_i387"
15963   [(set (match_operand:DF 0 "register_operand" "=f,f")
15964         (match_operator:DF 3 "binary_fp_operator"
15965                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15966                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15967   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15968    && !COMMUTATIVE_ARITH_P (operands[3])
15969    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15970   "* return output_387_binary_op (insn, operands);"
15971   [(set (attr "type")
15972         (cond [(match_operand:DF 3 "mult_operator" "")
15973                  (const_string "fmul")
15974                (match_operand:DF 3 "div_operator" "")
15975                  (const_string "fdiv")
15976               ]
15977               (const_string "fop")))
15978    (set_attr "mode" "DF")])
15979
15980 ;; ??? Add SSE splitters for these!
15981 (define_insn "*fop_df_2<mode>_i387"
15982   [(set (match_operand:DF 0 "register_operand" "=f,f")
15983         (match_operator:DF 3 "binary_fp_operator"
15984            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15985             (match_operand:DF 2 "register_operand" "0,0")]))]
15986   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15987    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15988   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15989   [(set (attr "type")
15990         (cond [(match_operand:DF 3 "mult_operator" "")
15991                  (const_string "fmul")
15992                (match_operand:DF 3 "div_operator" "")
15993                  (const_string "fdiv")
15994               ]
15995               (const_string "fop")))
15996    (set_attr "fp_int_src" "true")
15997    (set_attr "mode" "<MODE>")])
15998
15999 (define_insn "*fop_df_3<mode>_i387"
16000   [(set (match_operand:DF 0 "register_operand" "=f,f")
16001         (match_operator:DF 3 "binary_fp_operator"
16002            [(match_operand:DF 1 "register_operand" "0,0")
16003             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16004   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16005    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16006   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16007   [(set (attr "type")
16008         (cond [(match_operand:DF 3 "mult_operator" "")
16009                  (const_string "fmul")
16010                (match_operand:DF 3 "div_operator" "")
16011                  (const_string "fdiv")
16012               ]
16013               (const_string "fop")))
16014    (set_attr "fp_int_src" "true")
16015    (set_attr "mode" "<MODE>")])
16016
16017 (define_insn "*fop_df_4_i387"
16018   [(set (match_operand:DF 0 "register_operand" "=f,f")
16019         (match_operator:DF 3 "binary_fp_operator"
16020            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16021             (match_operand:DF 2 "register_operand" "0,f")]))]
16022   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16024   "* return output_387_binary_op (insn, operands);"
16025   [(set (attr "type")
16026         (cond [(match_operand:DF 3 "mult_operator" "")
16027                  (const_string "fmul")
16028                (match_operand:DF 3 "div_operator" "")
16029                  (const_string "fdiv")
16030               ]
16031               (const_string "fop")))
16032    (set_attr "mode" "SF")])
16033
16034 (define_insn "*fop_df_5_i387"
16035   [(set (match_operand:DF 0 "register_operand" "=f,f")
16036         (match_operator:DF 3 "binary_fp_operator"
16037           [(match_operand:DF 1 "register_operand" "0,f")
16038            (float_extend:DF
16039             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16040   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16041   "* return output_387_binary_op (insn, operands);"
16042   [(set (attr "type")
16043         (cond [(match_operand:DF 3 "mult_operator" "")
16044                  (const_string "fmul")
16045                (match_operand:DF 3 "div_operator" "")
16046                  (const_string "fdiv")
16047               ]
16048               (const_string "fop")))
16049    (set_attr "mode" "SF")])
16050
16051 (define_insn "*fop_df_6_i387"
16052   [(set (match_operand:DF 0 "register_operand" "=f,f")
16053         (match_operator:DF 3 "binary_fp_operator"
16054           [(float_extend:DF
16055             (match_operand:SF 1 "register_operand" "0,f"))
16056            (float_extend:DF
16057             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16058   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16059   "* return output_387_binary_op (insn, operands);"
16060   [(set (attr "type")
16061         (cond [(match_operand:DF 3 "mult_operator" "")
16062                  (const_string "fmul")
16063                (match_operand:DF 3 "div_operator" "")
16064                  (const_string "fdiv")
16065               ]
16066               (const_string "fop")))
16067    (set_attr "mode" "SF")])
16068
16069 (define_insn "*fop_xf_comm_i387"
16070   [(set (match_operand:XF 0 "register_operand" "=f")
16071         (match_operator:XF 3 "binary_fp_operator"
16072                         [(match_operand:XF 1 "register_operand" "%0")
16073                          (match_operand:XF 2 "register_operand" "f")]))]
16074   "TARGET_80387
16075    && COMMUTATIVE_ARITH_P (operands[3])"
16076   "* return output_387_binary_op (insn, operands);"
16077   [(set (attr "type")
16078         (if_then_else (match_operand:XF 3 "mult_operator" "")
16079            (const_string "fmul")
16080            (const_string "fop")))
16081    (set_attr "mode" "XF")])
16082
16083 (define_insn "*fop_xf_1_i387"
16084   [(set (match_operand:XF 0 "register_operand" "=f,f")
16085         (match_operator:XF 3 "binary_fp_operator"
16086                         [(match_operand:XF 1 "register_operand" "0,f")
16087                          (match_operand:XF 2 "register_operand" "f,0")]))]
16088   "TARGET_80387
16089    && !COMMUTATIVE_ARITH_P (operands[3])"
16090   "* return output_387_binary_op (insn, operands);"
16091   [(set (attr "type")
16092         (cond [(match_operand:XF 3 "mult_operator" "")
16093                  (const_string "fmul")
16094                (match_operand:XF 3 "div_operator" "")
16095                  (const_string "fdiv")
16096               ]
16097               (const_string "fop")))
16098    (set_attr "mode" "XF")])
16099
16100 (define_insn "*fop_xf_2<mode>_i387"
16101   [(set (match_operand:XF 0 "register_operand" "=f,f")
16102         (match_operator:XF 3 "binary_fp_operator"
16103            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16104             (match_operand:XF 2 "register_operand" "0,0")]))]
16105   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16106   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16107   [(set (attr "type")
16108         (cond [(match_operand:XF 3 "mult_operator" "")
16109                  (const_string "fmul")
16110                (match_operand:XF 3 "div_operator" "")
16111                  (const_string "fdiv")
16112               ]
16113               (const_string "fop")))
16114    (set_attr "fp_int_src" "true")
16115    (set_attr "mode" "<MODE>")])
16116
16117 (define_insn "*fop_xf_3<mode>_i387"
16118   [(set (match_operand:XF 0 "register_operand" "=f,f")
16119         (match_operator:XF 3 "binary_fp_operator"
16120           [(match_operand:XF 1 "register_operand" "0,0")
16121            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16122   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16123   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16124   [(set (attr "type")
16125         (cond [(match_operand:XF 3 "mult_operator" "")
16126                  (const_string "fmul")
16127                (match_operand:XF 3 "div_operator" "")
16128                  (const_string "fdiv")
16129               ]
16130               (const_string "fop")))
16131    (set_attr "fp_int_src" "true")
16132    (set_attr "mode" "<MODE>")])
16133
16134 (define_insn "*fop_xf_4_i387"
16135   [(set (match_operand:XF 0 "register_operand" "=f,f")
16136         (match_operator:XF 3 "binary_fp_operator"
16137            [(float_extend:XF
16138               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16139             (match_operand:XF 2 "register_operand" "0,f")]))]
16140   "TARGET_80387"
16141   "* return output_387_binary_op (insn, operands);"
16142   [(set (attr "type")
16143         (cond [(match_operand:XF 3 "mult_operator" "")
16144                  (const_string "fmul")
16145                (match_operand:XF 3 "div_operator" "")
16146                  (const_string "fdiv")
16147               ]
16148               (const_string "fop")))
16149    (set_attr "mode" "SF")])
16150
16151 (define_insn "*fop_xf_5_i387"
16152   [(set (match_operand:XF 0 "register_operand" "=f,f")
16153         (match_operator:XF 3 "binary_fp_operator"
16154           [(match_operand:XF 1 "register_operand" "0,f")
16155            (float_extend:XF
16156              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16157   "TARGET_80387"
16158   "* return output_387_binary_op (insn, operands);"
16159   [(set (attr "type")
16160         (cond [(match_operand:XF 3 "mult_operator" "")
16161                  (const_string "fmul")
16162                (match_operand:XF 3 "div_operator" "")
16163                  (const_string "fdiv")
16164               ]
16165               (const_string "fop")))
16166    (set_attr "mode" "SF")])
16167
16168 (define_insn "*fop_xf_6_i387"
16169   [(set (match_operand:XF 0 "register_operand" "=f,f")
16170         (match_operator:XF 3 "binary_fp_operator"
16171           [(float_extend:XF
16172              (match_operand:MODEF 1 "register_operand" "0,f"))
16173            (float_extend:XF
16174              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16175   "TARGET_80387"
16176   "* return output_387_binary_op (insn, operands);"
16177   [(set (attr "type")
16178         (cond [(match_operand:XF 3 "mult_operator" "")
16179                  (const_string "fmul")
16180                (match_operand:XF 3 "div_operator" "")
16181                  (const_string "fdiv")
16182               ]
16183               (const_string "fop")))
16184    (set_attr "mode" "SF")])
16185
16186 (define_split
16187   [(set (match_operand 0 "register_operand" "")
16188         (match_operator 3 "binary_fp_operator"
16189            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16190             (match_operand 2 "register_operand" "")]))]
16191   "reload_completed
16192    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16193   [(const_int 0)]
16194 {
16195   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16196   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16197   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16198                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16199                                           GET_MODE (operands[3]),
16200                                           operands[4],
16201                                           operands[2])));
16202   ix86_free_from_memory (GET_MODE (operands[1]));
16203   DONE;
16204 })
16205
16206 (define_split
16207   [(set (match_operand 0 "register_operand" "")
16208         (match_operator 3 "binary_fp_operator"
16209            [(match_operand 1 "register_operand" "")
16210             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16211   "reload_completed
16212    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16213   [(const_int 0)]
16214 {
16215   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16216   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16217   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16218                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16219                                           GET_MODE (operands[3]),
16220                                           operands[1],
16221                                           operands[4])));
16222   ix86_free_from_memory (GET_MODE (operands[2]));
16223   DONE;
16224 })
16225 \f
16226 ;; FPU special functions.
16227
16228 ;; This pattern implements a no-op XFmode truncation for
16229 ;; all fancy i386 XFmode math functions.
16230
16231 (define_insn "truncxf<mode>2_i387_noop_unspec"
16232   [(set (match_operand:MODEF 0 "register_operand" "=f")
16233         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16234         UNSPEC_TRUNC_NOOP))]
16235   "TARGET_USE_FANCY_MATH_387"
16236   "* return output_387_reg_move (insn, operands);"
16237   [(set_attr "type" "fmov")
16238    (set_attr "mode" "<MODE>")])
16239
16240 (define_insn "sqrtxf2"
16241   [(set (match_operand:XF 0 "register_operand" "=f")
16242         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16243   "TARGET_USE_FANCY_MATH_387"
16244   "fsqrt"
16245   [(set_attr "type" "fpspc")
16246    (set_attr "mode" "XF")
16247    (set_attr "athlon_decode" "direct")
16248    (set_attr "amdfam10_decode" "direct")])
16249
16250 (define_insn "sqrt_extend<mode>xf2_i387"
16251   [(set (match_operand:XF 0 "register_operand" "=f")
16252         (sqrt:XF
16253           (float_extend:XF
16254             (match_operand:MODEF 1 "register_operand" "0"))))]
16255   "TARGET_USE_FANCY_MATH_387"
16256   "fsqrt"
16257   [(set_attr "type" "fpspc")
16258    (set_attr "mode" "XF")
16259    (set_attr "athlon_decode" "direct")
16260    (set_attr "amdfam10_decode" "direct")])
16261
16262 (define_insn "*rsqrtsf2_sse"
16263   [(set (match_operand:SF 0 "register_operand" "=x")
16264         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16265                    UNSPEC_RSQRT))]
16266   "TARGET_SSE_MATH"
16267   "rsqrtss\t{%1, %0|%0, %1}"
16268   [(set_attr "type" "sse")
16269    (set_attr "mode" "SF")])
16270
16271 (define_expand "rsqrtsf2"
16272   [(set (match_operand:SF 0 "register_operand" "")
16273         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16274                    UNSPEC_RSQRT))]
16275   "TARGET_SSE_MATH"
16276 {
16277   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16278   DONE;
16279 })
16280
16281 (define_insn "*sqrt<mode>2_sse"
16282   [(set (match_operand:MODEF 0 "register_operand" "=x")
16283         (sqrt:MODEF
16284           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16285   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16286   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16287   [(set_attr "type" "sse")
16288    (set_attr "mode" "<MODE>")
16289    (set_attr "athlon_decode" "*")
16290    (set_attr "amdfam10_decode" "*")])
16291
16292 (define_expand "sqrt<mode>2"
16293   [(set (match_operand:MODEF 0 "register_operand" "")
16294         (sqrt:MODEF
16295           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16296   "TARGET_USE_FANCY_MATH_387
16297    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16298 {
16299   if (<MODE>mode == SFmode
16300       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16301       && flag_finite_math_only && !flag_trapping_math
16302       && flag_unsafe_math_optimizations)
16303     {
16304       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16305       DONE;
16306     }
16307
16308   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16309     {
16310       rtx op0 = gen_reg_rtx (XFmode);
16311       rtx op1 = force_reg (<MODE>mode, operands[1]);
16312
16313       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16314       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16315       DONE;
16316    }
16317 })
16318
16319 (define_insn "fpremxf4_i387"
16320   [(set (match_operand:XF 0 "register_operand" "=f")
16321         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16322                     (match_operand:XF 3 "register_operand" "1")]
16323                    UNSPEC_FPREM_F))
16324    (set (match_operand:XF 1 "register_operand" "=u")
16325         (unspec:XF [(match_dup 2) (match_dup 3)]
16326                    UNSPEC_FPREM_U))
16327    (set (reg:CCFP FPSR_REG)
16328         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16329                      UNSPEC_C2_FLAG))]
16330   "TARGET_USE_FANCY_MATH_387"
16331   "fprem"
16332   [(set_attr "type" "fpspc")
16333    (set_attr "mode" "XF")])
16334
16335 (define_expand "fmodxf3"
16336   [(use (match_operand:XF 0 "register_operand" ""))
16337    (use (match_operand:XF 1 "register_operand" ""))
16338    (use (match_operand:XF 2 "register_operand" ""))]
16339   "TARGET_USE_FANCY_MATH_387"
16340 {
16341   rtx label = gen_label_rtx ();
16342
16343   rtx op2;
16344
16345   if (rtx_equal_p (operands[1], operands[2]))
16346     {
16347       op2 = gen_reg_rtx (XFmode);
16348       emit_move_insn (op2, operands[2]);
16349     }
16350   else
16351     op2 = operands[2];
16352
16353   emit_label (label);
16354   emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16355   ix86_emit_fp_unordered_jump (label);
16356   LABEL_NUSES (label) = 1;
16357
16358   emit_move_insn (operands[0], operands[1]);
16359   DONE;
16360 })
16361
16362 (define_expand "fmod<mode>3"
16363   [(use (match_operand:MODEF 0 "register_operand" ""))
16364    (use (match_operand:MODEF 1 "general_operand" ""))
16365    (use (match_operand:MODEF 2 "general_operand" ""))]
16366   "TARGET_USE_FANCY_MATH_387"
16367 {
16368   rtx label = gen_label_rtx ();
16369
16370   rtx op1 = gen_reg_rtx (XFmode);
16371   rtx op2 = gen_reg_rtx (XFmode);
16372
16373   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16374   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16375
16376   emit_label (label);
16377   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16378   ix86_emit_fp_unordered_jump (label);
16379   LABEL_NUSES (label) = 1;
16380
16381   /* Truncate the result properly for strict SSE math.  */
16382   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16383       && !TARGET_MIX_SSE_I387)
16384     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16385   else
16386     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16387
16388   DONE;
16389 })
16390
16391 (define_insn "fprem1xf4_i387"
16392   [(set (match_operand:XF 0 "register_operand" "=f")
16393         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16394                     (match_operand:XF 3 "register_operand" "1")]
16395                    UNSPEC_FPREM1_F))
16396    (set (match_operand:XF 1 "register_operand" "=u")
16397         (unspec:XF [(match_dup 2) (match_dup 3)]
16398                    UNSPEC_FPREM1_U))
16399    (set (reg:CCFP FPSR_REG)
16400         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16401                      UNSPEC_C2_FLAG))]
16402   "TARGET_USE_FANCY_MATH_387"
16403   "fprem1"
16404   [(set_attr "type" "fpspc")
16405    (set_attr "mode" "XF")])
16406
16407 (define_expand "remainderxf3"
16408   [(use (match_operand:XF 0 "register_operand" ""))
16409    (use (match_operand:XF 1 "register_operand" ""))
16410    (use (match_operand:XF 2 "register_operand" ""))]
16411   "TARGET_USE_FANCY_MATH_387"
16412 {
16413   rtx label = gen_label_rtx ();
16414
16415   rtx op2;
16416
16417   if (rtx_equal_p (operands[1], operands[2]))
16418     {
16419       op2 = gen_reg_rtx (XFmode);
16420       emit_move_insn (op2, operands[2]);
16421     }
16422   else
16423     op2 = operands[2];
16424
16425   emit_label (label);
16426   emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16427   ix86_emit_fp_unordered_jump (label);
16428   LABEL_NUSES (label) = 1;
16429
16430   emit_move_insn (operands[0], operands[1]);
16431   DONE;
16432 })
16433
16434 (define_expand "remainder<mode>3"
16435   [(use (match_operand:MODEF 0 "register_operand" ""))
16436    (use (match_operand:MODEF 1 "general_operand" ""))
16437    (use (match_operand:MODEF 2 "general_operand" ""))]
16438   "TARGET_USE_FANCY_MATH_387"
16439 {
16440   rtx label = gen_label_rtx ();
16441
16442   rtx op1 = gen_reg_rtx (XFmode);
16443   rtx op2 = gen_reg_rtx (XFmode);
16444
16445   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16446   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16447
16448   emit_label (label);
16449
16450   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16451   ix86_emit_fp_unordered_jump (label);
16452   LABEL_NUSES (label) = 1;
16453
16454   /* Truncate the result properly for strict SSE math.  */
16455   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16456       && !TARGET_MIX_SSE_I387)
16457     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16458   else
16459     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16460
16461   DONE;
16462 })
16463
16464 (define_insn "*sinxf2_i387"
16465   [(set (match_operand:XF 0 "register_operand" "=f")
16466         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16467   "TARGET_USE_FANCY_MATH_387
16468    && flag_unsafe_math_optimizations"
16469   "fsin"
16470   [(set_attr "type" "fpspc")
16471    (set_attr "mode" "XF")])
16472
16473 (define_insn "*sin_extend<mode>xf2_i387"
16474   [(set (match_operand:XF 0 "register_operand" "=f")
16475         (unspec:XF [(float_extend:XF
16476                       (match_operand:MODEF 1 "register_operand" "0"))]
16477                    UNSPEC_SIN))]
16478   "TARGET_USE_FANCY_MATH_387
16479    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16480        || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16482   "fsin"
16483   [(set_attr "type" "fpspc")
16484    (set_attr "mode" "XF")])
16485
16486 (define_insn "*cosxf2_i387"
16487   [(set (match_operand:XF 0 "register_operand" "=f")
16488         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16489   "TARGET_USE_FANCY_MATH_387
16490    && flag_unsafe_math_optimizations"
16491   "fcos"
16492   [(set_attr "type" "fpspc")
16493    (set_attr "mode" "XF")])
16494
16495 (define_insn "*cos_extend<mode>xf2_i387"
16496   [(set (match_operand:XF 0 "register_operand" "=f")
16497         (unspec:XF [(float_extend:XF
16498                       (match_operand:MODEF 1 "register_operand" "0"))]
16499                    UNSPEC_COS))]
16500   "TARGET_USE_FANCY_MATH_387
16501    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16502        || TARGET_MIX_SSE_I387)
16503    && flag_unsafe_math_optimizations"
16504   "fcos"
16505   [(set_attr "type" "fpspc")
16506    (set_attr "mode" "XF")])
16507
16508 ;; When sincos pattern is defined, sin and cos builtin functions will be
16509 ;; expanded to sincos pattern with one of its outputs left unused.
16510 ;; CSE pass will figure out if two sincos patterns can be combined,
16511 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16512 ;; depending on the unused output.
16513
16514 (define_insn "sincosxf3"
16515   [(set (match_operand:XF 0 "register_operand" "=f")
16516         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16517                    UNSPEC_SINCOS_COS))
16518    (set (match_operand:XF 1 "register_operand" "=u")
16519         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16520   "TARGET_USE_FANCY_MATH_387
16521    && flag_unsafe_math_optimizations"
16522   "fsincos"
16523   [(set_attr "type" "fpspc")
16524    (set_attr "mode" "XF")])
16525
16526 (define_split
16527   [(set (match_operand:XF 0 "register_operand" "")
16528         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16529                    UNSPEC_SINCOS_COS))
16530    (set (match_operand:XF 1 "register_operand" "")
16531         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16532   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16533    && !(reload_completed || reload_in_progress)"
16534   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16535   "")
16536
16537 (define_split
16538   [(set (match_operand:XF 0 "register_operand" "")
16539         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16540                    UNSPEC_SINCOS_COS))
16541    (set (match_operand:XF 1 "register_operand" "")
16542         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16543   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16544    && !(reload_completed || reload_in_progress)"
16545   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16546   "")
16547
16548 (define_insn "sincos_extend<mode>xf3_i387"
16549   [(set (match_operand:XF 0 "register_operand" "=f")
16550         (unspec:XF [(float_extend:XF
16551                       (match_operand:MODEF 2 "register_operand" "0"))]
16552                    UNSPEC_SINCOS_COS))
16553    (set (match_operand:XF 1 "register_operand" "=u")
16554         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16555   "TARGET_USE_FANCY_MATH_387
16556    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16557        || TARGET_MIX_SSE_I387)
16558    && flag_unsafe_math_optimizations"
16559   "fsincos"
16560   [(set_attr "type" "fpspc")
16561    (set_attr "mode" "XF")])
16562
16563 (define_split
16564   [(set (match_operand:XF 0 "register_operand" "")
16565         (unspec:XF [(float_extend:XF
16566                       (match_operand:MODEF 2 "register_operand" ""))]
16567                    UNSPEC_SINCOS_COS))
16568    (set (match_operand:XF 1 "register_operand" "")
16569         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16570   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16571    && !(reload_completed || reload_in_progress)"
16572   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16573   "")
16574
16575 (define_split
16576   [(set (match_operand:XF 0 "register_operand" "")
16577         (unspec:XF [(float_extend:XF
16578                       (match_operand:MODEF 2 "register_operand" ""))]
16579                    UNSPEC_SINCOS_COS))
16580    (set (match_operand:XF 1 "register_operand" "")
16581         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16582   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16583    && !(reload_completed || reload_in_progress)"
16584   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16585   "")
16586
16587 (define_expand "sincos<mode>3"
16588   [(use (match_operand:MODEF 0 "register_operand" ""))
16589    (use (match_operand:MODEF 1 "register_operand" ""))
16590    (use (match_operand:MODEF 2 "register_operand" ""))]
16591   "TARGET_USE_FANCY_MATH_387
16592    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16593        || TARGET_MIX_SSE_I387)
16594    && flag_unsafe_math_optimizations"
16595 {
16596   rtx op0 = gen_reg_rtx (XFmode);
16597   rtx op1 = gen_reg_rtx (XFmode);
16598
16599   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16600   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16601   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16602   DONE;
16603 })
16604
16605 (define_insn "fptanxf4_i387"
16606   [(set (match_operand:XF 0 "register_operand" "=f")
16607         (match_operand:XF 3 "const_double_operand" "F"))
16608    (set (match_operand:XF 1 "register_operand" "=u")
16609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16610                    UNSPEC_TAN))]
16611   "TARGET_USE_FANCY_MATH_387
16612    && flag_unsafe_math_optimizations
16613    && standard_80387_constant_p (operands[3]) == 2"
16614   "fptan"
16615   [(set_attr "type" "fpspc")
16616    (set_attr "mode" "XF")])
16617
16618 (define_insn "fptan_extend<mode>xf4_i387"
16619   [(set (match_operand:MODEF 0 "register_operand" "=f")
16620         (match_operand:MODEF 3 "const_double_operand" "F"))
16621    (set (match_operand:XF 1 "register_operand" "=u")
16622         (unspec:XF [(float_extend:XF
16623                       (match_operand:MODEF 2 "register_operand" "0"))]
16624                    UNSPEC_TAN))]
16625   "TARGET_USE_FANCY_MATH_387
16626    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16627        || TARGET_MIX_SSE_I387)
16628    && flag_unsafe_math_optimizations
16629    && standard_80387_constant_p (operands[3]) == 2"
16630   "fptan"
16631   [(set_attr "type" "fpspc")
16632    (set_attr "mode" "XF")])
16633
16634 (define_expand "tanxf2"
16635   [(use (match_operand:XF 0 "register_operand" ""))
16636    (use (match_operand:XF 1 "register_operand" ""))]
16637   "TARGET_USE_FANCY_MATH_387
16638    && flag_unsafe_math_optimizations"
16639 {
16640   rtx one = gen_reg_rtx (XFmode);
16641   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16642
16643   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16644   DONE;
16645 })
16646
16647 (define_expand "tan<mode>2"
16648   [(use (match_operand:MODEF 0 "register_operand" ""))
16649    (use (match_operand:MODEF 1 "register_operand" ""))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16652        || TARGET_MIX_SSE_I387)
16653    && flag_unsafe_math_optimizations"
16654 {
16655   rtx op0 = gen_reg_rtx (XFmode);
16656
16657   rtx one = gen_reg_rtx (<MODE>mode);
16658   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16659
16660   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16661                                              operands[1], op2));
16662   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16663   DONE;
16664 })
16665
16666 (define_insn "*fpatanxf3_i387"
16667   [(set (match_operand:XF 0 "register_operand" "=f")
16668         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16669                     (match_operand:XF 2 "register_operand" "u")]
16670                    UNSPEC_FPATAN))
16671    (clobber (match_scratch:XF 3 "=2"))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && flag_unsafe_math_optimizations"
16674   "fpatan"
16675   [(set_attr "type" "fpspc")
16676    (set_attr "mode" "XF")])
16677
16678 (define_insn "fpatan_extend<mode>xf3_i387"
16679   [(set (match_operand:XF 0 "register_operand" "=f")
16680         (unspec:XF [(float_extend:XF
16681                       (match_operand:MODEF 1 "register_operand" "0"))
16682                     (float_extend:XF
16683                       (match_operand:MODEF 2 "register_operand" "u"))]
16684                    UNSPEC_FPATAN))
16685    (clobber (match_scratch:XF 3 "=2"))]
16686   "TARGET_USE_FANCY_MATH_387
16687    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16688        || TARGET_MIX_SSE_I387)
16689    && flag_unsafe_math_optimizations"
16690   "fpatan"
16691   [(set_attr "type" "fpspc")
16692    (set_attr "mode" "XF")])
16693
16694 (define_expand "atan2xf3"
16695   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16696                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16697                                (match_operand:XF 1 "register_operand" "")]
16698                               UNSPEC_FPATAN))
16699               (clobber (match_scratch:XF 3 ""))])]
16700   "TARGET_USE_FANCY_MATH_387
16701    && flag_unsafe_math_optimizations"
16702   "")
16703
16704 (define_expand "atan2<mode>3"
16705   [(use (match_operand:MODEF 0 "register_operand" ""))
16706    (use (match_operand:MODEF 1 "register_operand" ""))
16707    (use (match_operand:MODEF 2 "register_operand" ""))]
16708   "TARGET_USE_FANCY_MATH_387
16709    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16710        || TARGET_MIX_SSE_I387)
16711    && flag_unsafe_math_optimizations"
16712 {
16713   rtx op0 = gen_reg_rtx (XFmode);
16714
16715   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16716   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16717   DONE;
16718 })
16719
16720 (define_expand "atanxf2"
16721   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16722                    (unspec:XF [(match_dup 2)
16723                                (match_operand:XF 1 "register_operand" "")]
16724                               UNSPEC_FPATAN))
16725               (clobber (match_scratch:XF 3 ""))])]
16726   "TARGET_USE_FANCY_MATH_387
16727    && flag_unsafe_math_optimizations"
16728 {
16729   operands[2] = gen_reg_rtx (XFmode);
16730   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16731 })
16732
16733 (define_expand "atan<mode>2"
16734   [(use (match_operand:MODEF 0 "register_operand" ""))
16735    (use (match_operand:MODEF 1 "register_operand" ""))]
16736   "TARGET_USE_FANCY_MATH_387
16737    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16738        || TARGET_MIX_SSE_I387)
16739    && flag_unsafe_math_optimizations"
16740 {
16741   rtx op0 = gen_reg_rtx (XFmode);
16742
16743   rtx op2 = gen_reg_rtx (<MODE>mode);
16744   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16745
16746   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16747   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16748   DONE;
16749 })
16750
16751 (define_expand "asinxf2"
16752   [(set (match_dup 2)
16753         (mult:XF (match_operand:XF 1 "register_operand" "")
16754                  (match_dup 1)))
16755    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16756    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16757    (parallel [(set (match_operand:XF 0 "register_operand" "")
16758                    (unspec:XF [(match_dup 5) (match_dup 1)]
16759                               UNSPEC_FPATAN))
16760               (clobber (match_scratch:XF 6 ""))])]
16761   "TARGET_USE_FANCY_MATH_387
16762    && flag_unsafe_math_optimizations && !optimize_size"
16763 {
16764   int i;
16765
16766   for (i = 2; i < 6; i++)
16767     operands[i] = gen_reg_rtx (XFmode);
16768
16769   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16770 })
16771
16772 (define_expand "asin<mode>2"
16773   [(use (match_operand:MODEF 0 "register_operand" ""))
16774    (use (match_operand:MODEF 1 "general_operand" ""))]
16775  "TARGET_USE_FANCY_MATH_387
16776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777        || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations && !optimize_size"
16779 {
16780   rtx op0 = gen_reg_rtx (XFmode);
16781   rtx op1 = gen_reg_rtx (XFmode);
16782
16783   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16784   emit_insn (gen_asinxf2 (op0, op1));
16785   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16786   DONE;
16787 })
16788
16789 (define_expand "acosxf2"
16790   [(set (match_dup 2)
16791         (mult:XF (match_operand:XF 1 "register_operand" "")
16792                  (match_dup 1)))
16793    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16794    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16795    (parallel [(set (match_operand:XF 0 "register_operand" "")
16796                    (unspec:XF [(match_dup 1) (match_dup 5)]
16797                               UNSPEC_FPATAN))
16798               (clobber (match_scratch:XF 6 ""))])]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations && !optimize_size"
16801 {
16802   int i;
16803
16804   for (i = 2; i < 6; i++)
16805     operands[i] = gen_reg_rtx (XFmode);
16806
16807   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16808 })
16809
16810 (define_expand "acos<mode>2"
16811   [(use (match_operand:MODEF 0 "register_operand" ""))
16812    (use (match_operand:MODEF 1 "general_operand" ""))]
16813  "TARGET_USE_FANCY_MATH_387
16814    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16815        || TARGET_MIX_SSE_I387)
16816    && flag_unsafe_math_optimizations && !optimize_size"
16817 {
16818   rtx op0 = gen_reg_rtx (XFmode);
16819   rtx op1 = gen_reg_rtx (XFmode);
16820
16821   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16822   emit_insn (gen_acosxf2 (op0, op1));
16823   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16824   DONE;
16825 })
16826
16827 (define_insn "fyl2xxf3_i387"
16828   [(set (match_operand:XF 0 "register_operand" "=f")
16829         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16830                     (match_operand:XF 2 "register_operand" "u")]
16831                    UNSPEC_FYL2X))
16832    (clobber (match_scratch:XF 3 "=2"))]
16833   "TARGET_USE_FANCY_MATH_387
16834    && flag_unsafe_math_optimizations"
16835   "fyl2x"
16836   [(set_attr "type" "fpspc")
16837    (set_attr "mode" "XF")])
16838
16839 (define_insn "fyl2x_extend<mode>xf3_i387"
16840   [(set (match_operand:XF 0 "register_operand" "=f")
16841         (unspec:XF [(float_extend:XF
16842                       (match_operand:MODEF 1 "register_operand" "0"))
16843                     (match_operand:XF 2 "register_operand" "u")]
16844                    UNSPEC_FYL2X))
16845    (clobber (match_scratch:XF 3 "=2"))]
16846   "TARGET_USE_FANCY_MATH_387
16847    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16848        || TARGET_MIX_SSE_I387)
16849    && flag_unsafe_math_optimizations"
16850   "fyl2x"
16851   [(set_attr "type" "fpspc")
16852    (set_attr "mode" "XF")])
16853
16854 (define_expand "logxf2"
16855   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16856                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16857                                (match_dup 2)] UNSPEC_FYL2X))
16858               (clobber (match_scratch:XF 3 ""))])]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861 {
16862   operands[2] = gen_reg_rtx (XFmode);
16863   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16864 })
16865
16866 (define_expand "log<mode>2"
16867   [(use (match_operand:MODEF 0 "register_operand" ""))
16868    (use (match_operand:MODEF 1 "register_operand" ""))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16871        || TARGET_MIX_SSE_I387)
16872    && flag_unsafe_math_optimizations"
16873 {
16874   rtx op0 = gen_reg_rtx (XFmode);
16875
16876   rtx op2 = gen_reg_rtx (XFmode);
16877   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16878
16879   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16880   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16881   DONE;
16882 })
16883
16884 (define_expand "log10xf2"
16885   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16886                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16887                                (match_dup 2)] UNSPEC_FYL2X))
16888               (clobber (match_scratch:XF 3 ""))])]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16891 {
16892   operands[2] = gen_reg_rtx (XFmode);
16893   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16894 })
16895
16896 (define_expand "log10<mode>2"
16897   [(use (match_operand:MODEF 0 "register_operand" ""))
16898    (use (match_operand:MODEF 1 "register_operand" ""))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16901        || TARGET_MIX_SSE_I387)
16902    && flag_unsafe_math_optimizations"
16903 {
16904   rtx op0 = gen_reg_rtx (XFmode);
16905
16906   rtx op2 = gen_reg_rtx (XFmode);
16907   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16908
16909   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16910   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16911   DONE;
16912 })
16913
16914 (define_expand "log2xf2"
16915   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16916                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16917                                (match_dup 2)] UNSPEC_FYL2X))
16918               (clobber (match_scratch:XF 3 ""))])]
16919   "TARGET_USE_FANCY_MATH_387
16920    && flag_unsafe_math_optimizations"
16921 {
16922   operands[2] = gen_reg_rtx (XFmode);
16923   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16924 })
16925
16926 (define_expand "log2<mode>2"
16927   [(use (match_operand:MODEF 0 "register_operand" ""))
16928    (use (match_operand:MODEF 1 "register_operand" ""))]
16929   "TARGET_USE_FANCY_MATH_387
16930    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931        || TARGET_MIX_SSE_I387)
16932    && flag_unsafe_math_optimizations"
16933 {
16934   rtx op0 = gen_reg_rtx (XFmode);
16935
16936   rtx op2 = gen_reg_rtx (XFmode);
16937   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16938
16939   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16940   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16941   DONE;
16942 })
16943
16944 (define_insn "fyl2xp1xf3_i387"
16945   [(set (match_operand:XF 0 "register_operand" "=f")
16946         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16947                     (match_operand:XF 2 "register_operand" "u")]
16948                    UNSPEC_FYL2XP1))
16949    (clobber (match_scratch:XF 3 "=2"))]
16950   "TARGET_USE_FANCY_MATH_387
16951    && flag_unsafe_math_optimizations"
16952   "fyl2xp1"
16953   [(set_attr "type" "fpspc")
16954    (set_attr "mode" "XF")])
16955
16956 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16957   [(set (match_operand:XF 0 "register_operand" "=f")
16958         (unspec:XF [(float_extend:XF
16959                       (match_operand:MODEF 1 "register_operand" "0"))
16960                     (match_operand:XF 2 "register_operand" "u")]
16961                    UNSPEC_FYL2XP1))
16962    (clobber (match_scratch:XF 3 "=2"))]
16963   "TARGET_USE_FANCY_MATH_387
16964    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965        || TARGET_MIX_SSE_I387)
16966    && flag_unsafe_math_optimizations"
16967   "fyl2xp1"
16968   [(set_attr "type" "fpspc")
16969    (set_attr "mode" "XF")])
16970
16971 (define_expand "log1pxf2"
16972   [(use (match_operand:XF 0 "register_operand" ""))
16973    (use (match_operand:XF 1 "register_operand" ""))]
16974   "TARGET_USE_FANCY_MATH_387
16975    && flag_unsafe_math_optimizations && !optimize_size"
16976 {
16977   ix86_emit_i387_log1p (operands[0], operands[1]);
16978   DONE;
16979 })
16980
16981 (define_expand "log1p<mode>2"
16982   [(use (match_operand:MODEF 0 "register_operand" ""))
16983    (use (match_operand:MODEF 1 "register_operand" ""))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16986        || TARGET_MIX_SSE_I387)
16987    && flag_unsafe_math_optimizations && !optimize_size"
16988 {
16989   rtx op0 = gen_reg_rtx (XFmode);
16990
16991   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16992
16993   ix86_emit_i387_log1p (op0, operands[1]);
16994   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16995   DONE;
16996 })
16997
16998 (define_insn "fxtractxf3_i387"
16999   [(set (match_operand:XF 0 "register_operand" "=f")
17000         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17001                    UNSPEC_XTRACT_FRACT))
17002    (set (match_operand:XF 1 "register_operand" "=u")
17003         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17004   "TARGET_USE_FANCY_MATH_387
17005    && flag_unsafe_math_optimizations"
17006   "fxtract"
17007   [(set_attr "type" "fpspc")
17008    (set_attr "mode" "XF")])
17009
17010 (define_insn "fxtract_extend<mode>xf3_i387"
17011   [(set (match_operand:XF 0 "register_operand" "=f")
17012         (unspec:XF [(float_extend:XF
17013                       (match_operand:MODEF 2 "register_operand" "0"))]
17014                    UNSPEC_XTRACT_FRACT))
17015    (set (match_operand:XF 1 "register_operand" "=u")
17016         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17017   "TARGET_USE_FANCY_MATH_387
17018    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17019        || TARGET_MIX_SSE_I387)
17020    && flag_unsafe_math_optimizations"
17021   "fxtract"
17022   [(set_attr "type" "fpspc")
17023    (set_attr "mode" "XF")])
17024
17025 (define_expand "logbxf2"
17026   [(parallel [(set (match_dup 2)
17027                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17028                               UNSPEC_XTRACT_FRACT))
17029               (set (match_operand:XF 0 "register_operand" "")
17030                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations"
17033 {
17034   operands[2] = gen_reg_rtx (XFmode);
17035 })
17036
17037 (define_expand "logb<mode>2"
17038   [(use (match_operand:MODEF 0 "register_operand" ""))
17039    (use (match_operand:MODEF 1 "register_operand" ""))]
17040   "TARGET_USE_FANCY_MATH_387
17041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17042        || TARGET_MIX_SSE_I387)
17043    && flag_unsafe_math_optimizations"
17044 {
17045   rtx op0 = gen_reg_rtx (XFmode);
17046   rtx op1 = gen_reg_rtx (XFmode);
17047
17048   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17049   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17050   DONE;
17051 })
17052
17053 (define_expand "ilogbxf2"
17054   [(use (match_operand:SI 0 "register_operand" ""))
17055    (use (match_operand:XF 1 "register_operand" ""))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && flag_unsafe_math_optimizations && !optimize_size"
17058 {
17059   rtx op0 = gen_reg_rtx (XFmode);
17060   rtx op1 = gen_reg_rtx (XFmode);
17061
17062   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17063   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17064   DONE;
17065 })
17066
17067 (define_expand "ilogb<mode>2"
17068   [(use (match_operand:SI 0 "register_operand" ""))
17069    (use (match_operand:MODEF 1 "register_operand" ""))]
17070   "TARGET_USE_FANCY_MATH_387
17071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17072        || TARGET_MIX_SSE_I387)
17073    && flag_unsafe_math_optimizations && !optimize_size"
17074 {
17075   rtx op0 = gen_reg_rtx (XFmode);
17076   rtx op1 = gen_reg_rtx (XFmode);
17077
17078   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17079   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17080   DONE;
17081 })
17082
17083 (define_insn "*f2xm1xf2_i387"
17084   [(set (match_operand:XF 0 "register_operand" "=f")
17085         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17086                    UNSPEC_F2XM1))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations"
17089   "f2xm1"
17090   [(set_attr "type" "fpspc")
17091    (set_attr "mode" "XF")])
17092
17093 (define_insn "*fscalexf4_i387"
17094   [(set (match_operand:XF 0 "register_operand" "=f")
17095         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17096                     (match_operand:XF 3 "register_operand" "1")]
17097                    UNSPEC_FSCALE_FRACT))
17098    (set (match_operand:XF 1 "register_operand" "=u")
17099         (unspec:XF [(match_dup 2) (match_dup 3)]
17100                    UNSPEC_FSCALE_EXP))]
17101   "TARGET_USE_FANCY_MATH_387
17102    && flag_unsafe_math_optimizations"
17103   "fscale"
17104   [(set_attr "type" "fpspc")
17105    (set_attr "mode" "XF")])
17106
17107 (define_expand "expNcorexf3"
17108   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17109                                (match_operand:XF 2 "register_operand" "")))
17110    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17111    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17112    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17113    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17114    (parallel [(set (match_operand:XF 0 "register_operand" "")
17115                    (unspec:XF [(match_dup 8) (match_dup 4)]
17116                               UNSPEC_FSCALE_FRACT))
17117               (set (match_dup 9)
17118                    (unspec:XF [(match_dup 8) (match_dup 4)]
17119                               UNSPEC_FSCALE_EXP))])]
17120   "TARGET_USE_FANCY_MATH_387
17121    && flag_unsafe_math_optimizations && !optimize_size"
17122 {
17123   int i;
17124
17125   for (i = 3; i < 10; i++)
17126     operands[i] = gen_reg_rtx (XFmode);
17127
17128   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17129 })
17130
17131 (define_expand "expxf2"
17132   [(use (match_operand:XF 0 "register_operand" ""))
17133    (use (match_operand:XF 1 "register_operand" ""))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && flag_unsafe_math_optimizations && !optimize_size"
17136 {
17137   rtx op2 = gen_reg_rtx (XFmode);
17138   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17139
17140   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17141   DONE;
17142 })
17143
17144 (define_expand "exp<mode>2"
17145   [(use (match_operand:MODEF 0 "register_operand" ""))
17146    (use (match_operand:MODEF 1 "general_operand" ""))]
17147  "TARGET_USE_FANCY_MATH_387
17148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17149        || TARGET_MIX_SSE_I387)
17150    && flag_unsafe_math_optimizations && !optimize_size"
17151 {
17152   rtx op0 = gen_reg_rtx (XFmode);
17153   rtx op1 = gen_reg_rtx (XFmode);
17154
17155   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17156   emit_insn (gen_expxf2 (op0, op1));
17157   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17158   DONE;
17159 })
17160
17161 (define_expand "exp10xf2"
17162   [(use (match_operand:XF 0 "register_operand" ""))
17163    (use (match_operand:XF 1 "register_operand" ""))]
17164   "TARGET_USE_FANCY_MATH_387
17165    && flag_unsafe_math_optimizations && !optimize_size"
17166 {
17167   rtx op2 = gen_reg_rtx (XFmode);
17168   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17169
17170   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17171   DONE;
17172 })
17173
17174 (define_expand "exp10<mode>2"
17175   [(use (match_operand:MODEF 0 "register_operand" ""))
17176    (use (match_operand:MODEF 1 "general_operand" ""))]
17177  "TARGET_USE_FANCY_MATH_387
17178    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17179        || TARGET_MIX_SSE_I387)
17180    && flag_unsafe_math_optimizations && !optimize_size"
17181 {
17182   rtx op0 = gen_reg_rtx (XFmode);
17183   rtx op1 = gen_reg_rtx (XFmode);
17184
17185   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17186   emit_insn (gen_exp10xf2 (op0, op1));
17187   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17188   DONE;
17189 })
17190
17191 (define_expand "exp2xf2"
17192   [(use (match_operand:XF 0 "register_operand" ""))
17193    (use (match_operand:XF 1 "register_operand" ""))]
17194   "TARGET_USE_FANCY_MATH_387
17195    && flag_unsafe_math_optimizations && !optimize_size"
17196 {
17197   rtx op2 = gen_reg_rtx (XFmode);
17198   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17199
17200   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17201   DONE;
17202 })
17203
17204 (define_expand "exp2<mode>2"
17205   [(use (match_operand:MODEF 0 "register_operand" ""))
17206    (use (match_operand:MODEF 1 "general_operand" ""))]
17207  "TARGET_USE_FANCY_MATH_387
17208    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17209        || TARGET_MIX_SSE_I387)
17210    && flag_unsafe_math_optimizations && !optimize_size"
17211 {
17212   rtx op0 = gen_reg_rtx (XFmode);
17213   rtx op1 = gen_reg_rtx (XFmode);
17214
17215   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17216   emit_insn (gen_exp2xf2 (op0, op1));
17217   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17218   DONE;
17219 })
17220
17221 (define_expand "expm1xf2"
17222   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17223                                (match_dup 2)))
17224    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17225    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17226    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17227    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17228    (parallel [(set (match_dup 7)
17229                    (unspec:XF [(match_dup 6) (match_dup 4)]
17230                               UNSPEC_FSCALE_FRACT))
17231               (set (match_dup 8)
17232                    (unspec:XF [(match_dup 6) (match_dup 4)]
17233                               UNSPEC_FSCALE_EXP))])
17234    (parallel [(set (match_dup 10)
17235                    (unspec:XF [(match_dup 9) (match_dup 8)]
17236                               UNSPEC_FSCALE_FRACT))
17237               (set (match_dup 11)
17238                    (unspec:XF [(match_dup 9) (match_dup 8)]
17239                               UNSPEC_FSCALE_EXP))])
17240    (set (match_dup 12) (minus:XF (match_dup 10)
17241                                  (float_extend:XF (match_dup 13))))
17242    (set (match_operand:XF 0 "register_operand" "")
17243         (plus:XF (match_dup 12) (match_dup 7)))]
17244   "TARGET_USE_FANCY_MATH_387
17245    && flag_unsafe_math_optimizations && !optimize_size"
17246 {
17247   int i;
17248
17249   for (i = 2; i < 13; i++)
17250     operands[i] = gen_reg_rtx (XFmode);
17251
17252   operands[13]
17253     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17254
17255   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17256 })
17257
17258 (define_expand "expm1<mode>2"
17259   [(use (match_operand:MODEF 0 "register_operand" ""))
17260    (use (match_operand:MODEF 1 "general_operand" ""))]
17261  "TARGET_USE_FANCY_MATH_387
17262    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17263        || TARGET_MIX_SSE_I387)
17264    && flag_unsafe_math_optimizations && !optimize_size"
17265 {
17266   rtx op0 = gen_reg_rtx (XFmode);
17267   rtx op1 = gen_reg_rtx (XFmode);
17268
17269   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17270   emit_insn (gen_expm1xf2 (op0, op1));
17271   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17272   DONE;
17273 })
17274
17275 (define_expand "ldexpxf3"
17276   [(set (match_dup 3)
17277         (float:XF (match_operand:SI 2 "register_operand" "")))
17278    (parallel [(set (match_operand:XF 0 " register_operand" "")
17279                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17280                                (match_dup 3)]
17281                               UNSPEC_FSCALE_FRACT))
17282               (set (match_dup 4)
17283                    (unspec:XF [(match_dup 1) (match_dup 3)]
17284                               UNSPEC_FSCALE_EXP))])]
17285   "TARGET_USE_FANCY_MATH_387
17286    && flag_unsafe_math_optimizations && !optimize_size"
17287 {
17288   operands[3] = gen_reg_rtx (XFmode);
17289   operands[4] = gen_reg_rtx (XFmode);
17290 })
17291
17292 (define_expand "ldexp<mode>3"
17293   [(use (match_operand:MODEF 0 "register_operand" ""))
17294    (use (match_operand:MODEF 1 "general_operand" ""))
17295    (use (match_operand:SI 2 "register_operand" ""))]
17296  "TARGET_USE_FANCY_MATH_387
17297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17298        || TARGET_MIX_SSE_I387)
17299    && flag_unsafe_math_optimizations && !optimize_size"
17300 {
17301   rtx op0 = gen_reg_rtx (XFmode);
17302   rtx op1 = gen_reg_rtx (XFmode);
17303
17304   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17305   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17306   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17307   DONE;
17308 })
17309
17310 (define_expand "scalbxf3"
17311   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17312                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313                                (match_operand:XF 2 "register_operand" "")]
17314                               UNSPEC_FSCALE_FRACT))
17315               (set (match_dup 3)
17316                    (unspec:XF [(match_dup 1) (match_dup 2)]
17317                               UNSPEC_FSCALE_EXP))])]
17318   "TARGET_USE_FANCY_MATH_387
17319    && flag_unsafe_math_optimizations && !optimize_size"
17320 {
17321   operands[3] = gen_reg_rtx (XFmode);
17322 })
17323
17324 (define_expand "scalb<mode>3"
17325   [(use (match_operand:MODEF 0 "register_operand" ""))
17326    (use (match_operand:MODEF 1 "general_operand" ""))
17327    (use (match_operand:MODEF 2 "register_operand" ""))]
17328  "TARGET_USE_FANCY_MATH_387
17329    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17330        || TARGET_MIX_SSE_I387)
17331    && flag_unsafe_math_optimizations && !optimize_size"
17332 {
17333   rtx op0 = gen_reg_rtx (XFmode);
17334   rtx op1 = gen_reg_rtx (XFmode);
17335   rtx op2 = gen_reg_rtx (XFmode);
17336
17337   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17338   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17339   emit_insn (gen_scalbxf3 (op0, op1, op2));
17340   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341   DONE;
17342 })
17343 \f
17344
17345 (define_insn "sse4_1_round<mode>2"
17346   [(set (match_operand:MODEF 0 "register_operand" "=x")
17347         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17348                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17349                       UNSPEC_ROUND))]
17350   "TARGET_ROUND"
17351   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17352   [(set_attr "type" "ssecvt")
17353    (set_attr "prefix_extra" "1")
17354    (set_attr "mode" "<MODE>")])
17355
17356 (define_insn "rintxf2"
17357   [(set (match_operand:XF 0 "register_operand" "=f")
17358         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17359                    UNSPEC_FRNDINT))]
17360   "TARGET_USE_FANCY_MATH_387
17361    && flag_unsafe_math_optimizations"
17362   "frndint"
17363   [(set_attr "type" "fpspc")
17364    (set_attr "mode" "XF")])
17365
17366 (define_expand "rint<mode>2"
17367   [(use (match_operand:MODEF 0 "register_operand" ""))
17368    (use (match_operand:MODEF 1 "register_operand" ""))]
17369   "(TARGET_USE_FANCY_MATH_387
17370     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17371         || TARGET_MIX_SSE_I387)
17372     && flag_unsafe_math_optimizations)
17373    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17374        && !flag_trapping_math
17375        && (TARGET_ROUND || !optimize_size))"
17376 {
17377   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17378       && !flag_trapping_math
17379       && (TARGET_ROUND || !optimize_size))
17380     {
17381       if (TARGET_ROUND)
17382         emit_insn (gen_sse4_1_round<mode>2
17383                    (operands[0], operands[1], GEN_INT (0x04)));
17384       else
17385         ix86_expand_rint (operand0, operand1);
17386     }
17387   else
17388     {
17389       rtx op0 = gen_reg_rtx (XFmode);
17390       rtx op1 = gen_reg_rtx (XFmode);
17391
17392       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17393       emit_insn (gen_rintxf2 (op0, op1));
17394
17395       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17396     }
17397   DONE;
17398 })
17399
17400 (define_expand "round<mode>2"
17401   [(match_operand:MODEF 0 "register_operand" "")
17402    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17403   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17404    && !flag_trapping_math && !flag_rounding_math
17405    && !optimize_size"
17406 {
17407   if (TARGET_64BIT || (<MODE>mode != DFmode))
17408     ix86_expand_round (operand0, operand1);
17409   else
17410     ix86_expand_rounddf_32 (operand0, operand1);
17411   DONE;
17412 })
17413
17414 (define_insn_and_split "*fistdi2_1"
17415   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17416         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17417                    UNSPEC_FIST))]
17418   "TARGET_USE_FANCY_MATH_387
17419    && !(reload_completed || reload_in_progress)"
17420   "#"
17421   "&& 1"
17422   [(const_int 0)]
17423 {
17424   if (memory_operand (operands[0], VOIDmode))
17425     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17426   else
17427     {
17428       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17429       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17430                                          operands[2]));
17431     }
17432   DONE;
17433 }
17434   [(set_attr "type" "fpspc")
17435    (set_attr "mode" "DI")])
17436
17437 (define_insn "fistdi2"
17438   [(set (match_operand:DI 0 "memory_operand" "=m")
17439         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17440                    UNSPEC_FIST))
17441    (clobber (match_scratch:XF 2 "=&1f"))]
17442   "TARGET_USE_FANCY_MATH_387"
17443   "* return output_fix_trunc (insn, operands, 0);"
17444   [(set_attr "type" "fpspc")
17445    (set_attr "mode" "DI")])
17446
17447 (define_insn "fistdi2_with_temp"
17448   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17449         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17450                    UNSPEC_FIST))
17451    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17452    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17453   "TARGET_USE_FANCY_MATH_387"
17454   "#"
17455   [(set_attr "type" "fpspc")
17456    (set_attr "mode" "DI")])
17457
17458 (define_split
17459   [(set (match_operand:DI 0 "register_operand" "")
17460         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17461                    UNSPEC_FIST))
17462    (clobber (match_operand:DI 2 "memory_operand" ""))
17463    (clobber (match_scratch 3 ""))]
17464   "reload_completed"
17465   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17466               (clobber (match_dup 3))])
17467    (set (match_dup 0) (match_dup 2))]
17468   "")
17469
17470 (define_split
17471   [(set (match_operand:DI 0 "memory_operand" "")
17472         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17473                    UNSPEC_FIST))
17474    (clobber (match_operand:DI 2 "memory_operand" ""))
17475    (clobber (match_scratch 3 ""))]
17476   "reload_completed"
17477   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17478               (clobber (match_dup 3))])]
17479   "")
17480
17481 (define_insn_and_split "*fist<mode>2_1"
17482   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17483         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17484                            UNSPEC_FIST))]
17485   "TARGET_USE_FANCY_MATH_387
17486    && !(reload_completed || reload_in_progress)"
17487   "#"
17488   "&& 1"
17489   [(const_int 0)]
17490 {
17491   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17492   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17493                                         operands[2]));
17494   DONE;
17495 }
17496   [(set_attr "type" "fpspc")
17497    (set_attr "mode" "<MODE>")])
17498
17499 (define_insn "fist<mode>2"
17500   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17501         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17502                            UNSPEC_FIST))]
17503   "TARGET_USE_FANCY_MATH_387"
17504   "* return output_fix_trunc (insn, operands, 0);"
17505   [(set_attr "type" "fpspc")
17506    (set_attr "mode" "<MODE>")])
17507
17508 (define_insn "fist<mode>2_with_temp"
17509   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17510         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17511                            UNSPEC_FIST))
17512    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17513   "TARGET_USE_FANCY_MATH_387"
17514   "#"
17515   [(set_attr "type" "fpspc")
17516    (set_attr "mode" "<MODE>")])
17517
17518 (define_split
17519   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17520         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17521                            UNSPEC_FIST))
17522    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17523   "reload_completed"
17524   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17525    (set (match_dup 0) (match_dup 2))]
17526   "")
17527
17528 (define_split
17529   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17530         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17531                            UNSPEC_FIST))
17532    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17533   "reload_completed"
17534   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17535   "")
17536
17537 (define_expand "lrintxf<mode>2"
17538   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17539      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17540                       UNSPEC_FIST))]
17541   "TARGET_USE_FANCY_MATH_387"
17542   "")
17543
17544 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17545   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17546      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17547                         UNSPEC_FIX_NOTRUNC))]
17548   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17549    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17550   "")
17551
17552 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17553   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17554    (match_operand:MODEF 1 "register_operand" "")]
17555   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17556    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17557    && !flag_trapping_math && !flag_rounding_math
17558    && !optimize_size"
17559 {
17560   ix86_expand_lround (operand0, operand1);
17561   DONE;
17562 })
17563
17564 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17565 (define_insn_and_split "frndintxf2_floor"
17566   [(set (match_operand:XF 0 "register_operand" "")
17567         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17568          UNSPEC_FRNDINT_FLOOR))
17569    (clobber (reg:CC FLAGS_REG))]
17570   "TARGET_USE_FANCY_MATH_387
17571    && flag_unsafe_math_optimizations
17572    && !(reload_completed || reload_in_progress)"
17573   "#"
17574   "&& 1"
17575   [(const_int 0)]
17576 {
17577   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17578
17579   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17580   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17581
17582   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17583                                         operands[2], operands[3]));
17584   DONE;
17585 }
17586   [(set_attr "type" "frndint")
17587    (set_attr "i387_cw" "floor")
17588    (set_attr "mode" "XF")])
17589
17590 (define_insn "frndintxf2_floor_i387"
17591   [(set (match_operand:XF 0 "register_operand" "=f")
17592         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17593          UNSPEC_FRNDINT_FLOOR))
17594    (use (match_operand:HI 2 "memory_operand" "m"))
17595    (use (match_operand:HI 3 "memory_operand" "m"))]
17596   "TARGET_USE_FANCY_MATH_387
17597    && flag_unsafe_math_optimizations"
17598   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17599   [(set_attr "type" "frndint")
17600    (set_attr "i387_cw" "floor")
17601    (set_attr "mode" "XF")])
17602
17603 (define_expand "floorxf2"
17604   [(use (match_operand:XF 0 "register_operand" ""))
17605    (use (match_operand:XF 1 "register_operand" ""))]
17606   "TARGET_USE_FANCY_MATH_387
17607    && flag_unsafe_math_optimizations && !optimize_size"
17608 {
17609   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17610   DONE;
17611 })
17612
17613 (define_expand "floor<mode>2"
17614   [(use (match_operand:MODEF 0 "register_operand" ""))
17615    (use (match_operand:MODEF 1 "register_operand" ""))]
17616   "(TARGET_USE_FANCY_MATH_387
17617     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17618         || TARGET_MIX_SSE_I387)
17619     && flag_unsafe_math_optimizations && !optimize_size)
17620    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17621        && !flag_trapping_math
17622        && (TARGET_ROUND || !optimize_size))"
17623 {
17624   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17625       && !flag_trapping_math
17626       && (TARGET_ROUND || !optimize_size))
17627     {
17628       if (TARGET_ROUND)
17629         emit_insn (gen_sse4_1_round<mode>2
17630                    (operands[0], operands[1], GEN_INT (0x01)));
17631       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17632         ix86_expand_floorceil (operand0, operand1, true);
17633       else
17634         ix86_expand_floorceildf_32 (operand0, operand1, true);
17635     }
17636   else
17637     {
17638       rtx op0 = gen_reg_rtx (XFmode);
17639       rtx op1 = gen_reg_rtx (XFmode);
17640
17641       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17642       emit_insn (gen_frndintxf2_floor (op0, op1));
17643
17644       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17645     }
17646   DONE;
17647 })
17648
17649 (define_insn_and_split "*fist<mode>2_floor_1"
17650   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17651         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17652          UNSPEC_FIST_FLOOR))
17653    (clobber (reg:CC FLAGS_REG))]
17654   "TARGET_USE_FANCY_MATH_387
17655    && flag_unsafe_math_optimizations
17656    && !(reload_completed || reload_in_progress)"
17657   "#"
17658   "&& 1"
17659   [(const_int 0)]
17660 {
17661   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17662
17663   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17664   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17665   if (memory_operand (operands[0], VOIDmode))
17666     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17667                                       operands[2], operands[3]));
17668   else
17669     {
17670       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17671       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17672                                                   operands[2], operands[3],
17673                                                   operands[4]));
17674     }
17675   DONE;
17676 }
17677   [(set_attr "type" "fistp")
17678    (set_attr "i387_cw" "floor")
17679    (set_attr "mode" "<MODE>")])
17680
17681 (define_insn "fistdi2_floor"
17682   [(set (match_operand:DI 0 "memory_operand" "=m")
17683         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17684          UNSPEC_FIST_FLOOR))
17685    (use (match_operand:HI 2 "memory_operand" "m"))
17686    (use (match_operand:HI 3 "memory_operand" "m"))
17687    (clobber (match_scratch:XF 4 "=&1f"))]
17688   "TARGET_USE_FANCY_MATH_387
17689    && flag_unsafe_math_optimizations"
17690   "* return output_fix_trunc (insn, operands, 0);"
17691   [(set_attr "type" "fistp")
17692    (set_attr "i387_cw" "floor")
17693    (set_attr "mode" "DI")])
17694
17695 (define_insn "fistdi2_floor_with_temp"
17696   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17697         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17698          UNSPEC_FIST_FLOOR))
17699    (use (match_operand:HI 2 "memory_operand" "m,m"))
17700    (use (match_operand:HI 3 "memory_operand" "m,m"))
17701    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17702    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17703   "TARGET_USE_FANCY_MATH_387
17704    && flag_unsafe_math_optimizations"
17705   "#"
17706   [(set_attr "type" "fistp")
17707    (set_attr "i387_cw" "floor")
17708    (set_attr "mode" "DI")])
17709
17710 (define_split
17711   [(set (match_operand:DI 0 "register_operand" "")
17712         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17713          UNSPEC_FIST_FLOOR))
17714    (use (match_operand:HI 2 "memory_operand" ""))
17715    (use (match_operand:HI 3 "memory_operand" ""))
17716    (clobber (match_operand:DI 4 "memory_operand" ""))
17717    (clobber (match_scratch 5 ""))]
17718   "reload_completed"
17719   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17720               (use (match_dup 2))
17721               (use (match_dup 3))
17722               (clobber (match_dup 5))])
17723    (set (match_dup 0) (match_dup 4))]
17724   "")
17725
17726 (define_split
17727   [(set (match_operand:DI 0 "memory_operand" "")
17728         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17729          UNSPEC_FIST_FLOOR))
17730    (use (match_operand:HI 2 "memory_operand" ""))
17731    (use (match_operand:HI 3 "memory_operand" ""))
17732    (clobber (match_operand:DI 4 "memory_operand" ""))
17733    (clobber (match_scratch 5 ""))]
17734   "reload_completed"
17735   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17736               (use (match_dup 2))
17737               (use (match_dup 3))
17738               (clobber (match_dup 5))])]
17739   "")
17740
17741 (define_insn "fist<mode>2_floor"
17742   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17743         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17744          UNSPEC_FIST_FLOOR))
17745    (use (match_operand:HI 2 "memory_operand" "m"))
17746    (use (match_operand:HI 3 "memory_operand" "m"))]
17747   "TARGET_USE_FANCY_MATH_387
17748    && flag_unsafe_math_optimizations"
17749   "* return output_fix_trunc (insn, operands, 0);"
17750   [(set_attr "type" "fistp")
17751    (set_attr "i387_cw" "floor")
17752    (set_attr "mode" "<MODE>")])
17753
17754 (define_insn "fist<mode>2_floor_with_temp"
17755   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17756         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17757          UNSPEC_FIST_FLOOR))
17758    (use (match_operand:HI 2 "memory_operand" "m,m"))
17759    (use (match_operand:HI 3 "memory_operand" "m,m"))
17760    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17761   "TARGET_USE_FANCY_MATH_387
17762    && flag_unsafe_math_optimizations"
17763   "#"
17764   [(set_attr "type" "fistp")
17765    (set_attr "i387_cw" "floor")
17766    (set_attr "mode" "<MODE>")])
17767
17768 (define_split
17769   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17770         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17771          UNSPEC_FIST_FLOOR))
17772    (use (match_operand:HI 2 "memory_operand" ""))
17773    (use (match_operand:HI 3 "memory_operand" ""))
17774    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17775   "reload_completed"
17776   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17777                                   UNSPEC_FIST_FLOOR))
17778               (use (match_dup 2))
17779               (use (match_dup 3))])
17780    (set (match_dup 0) (match_dup 4))]
17781   "")
17782
17783 (define_split
17784   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17785         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17786          UNSPEC_FIST_FLOOR))
17787    (use (match_operand:HI 2 "memory_operand" ""))
17788    (use (match_operand:HI 3 "memory_operand" ""))
17789    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17790   "reload_completed"
17791   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17792                                   UNSPEC_FIST_FLOOR))
17793               (use (match_dup 2))
17794               (use (match_dup 3))])]
17795   "")
17796
17797 (define_expand "lfloorxf<mode>2"
17798   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17799                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17800                     UNSPEC_FIST_FLOOR))
17801               (clobber (reg:CC FLAGS_REG))])]
17802   "TARGET_USE_FANCY_MATH_387
17803    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17804    && flag_unsafe_math_optimizations"
17805   "")
17806
17807 (define_expand "lfloor<mode>di2"
17808   [(match_operand:DI 0 "nonimmediate_operand" "")
17809    (match_operand:MODEF 1 "register_operand" "")]
17810   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17811    && !flag_trapping_math
17812    && !optimize_size"
17813 {
17814   ix86_expand_lfloorceil (operand0, operand1, true);
17815   DONE;
17816 })
17817
17818 (define_expand "lfloor<mode>si2"
17819   [(match_operand:SI 0 "nonimmediate_operand" "")
17820    (match_operand:MODEF 1 "register_operand" "")]
17821   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17822    && !flag_trapping_math
17823    && (!optimize_size || !TARGET_64BIT)"
17824 {
17825   ix86_expand_lfloorceil (operand0, operand1, true);
17826   DONE;
17827 })
17828
17829 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17830 (define_insn_and_split "frndintxf2_ceil"
17831   [(set (match_operand:XF 0 "register_operand" "")
17832         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17833          UNSPEC_FRNDINT_CEIL))
17834    (clobber (reg:CC FLAGS_REG))]
17835   "TARGET_USE_FANCY_MATH_387
17836    && flag_unsafe_math_optimizations
17837    && !(reload_completed || reload_in_progress)"
17838   "#"
17839   "&& 1"
17840   [(const_int 0)]
17841 {
17842   ix86_optimize_mode_switching[I387_CEIL] = 1;
17843
17844   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17845   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17846
17847   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17848                                        operands[2], operands[3]));
17849   DONE;
17850 }
17851   [(set_attr "type" "frndint")
17852    (set_attr "i387_cw" "ceil")
17853    (set_attr "mode" "XF")])
17854
17855 (define_insn "frndintxf2_ceil_i387"
17856   [(set (match_operand:XF 0 "register_operand" "=f")
17857         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17858          UNSPEC_FRNDINT_CEIL))
17859    (use (match_operand:HI 2 "memory_operand" "m"))
17860    (use (match_operand:HI 3 "memory_operand" "m"))]
17861   "TARGET_USE_FANCY_MATH_387
17862    && flag_unsafe_math_optimizations"
17863   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17864   [(set_attr "type" "frndint")
17865    (set_attr "i387_cw" "ceil")
17866    (set_attr "mode" "XF")])
17867
17868 (define_expand "ceilxf2"
17869   [(use (match_operand:XF 0 "register_operand" ""))
17870    (use (match_operand:XF 1 "register_operand" ""))]
17871   "TARGET_USE_FANCY_MATH_387
17872    && flag_unsafe_math_optimizations && !optimize_size"
17873 {
17874   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17875   DONE;
17876 })
17877
17878 (define_expand "ceil<mode>2"
17879   [(use (match_operand:MODEF 0 "register_operand" ""))
17880    (use (match_operand:MODEF 1 "register_operand" ""))]
17881   "(TARGET_USE_FANCY_MATH_387
17882     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17883         || TARGET_MIX_SSE_I387)
17884     && flag_unsafe_math_optimizations && !optimize_size)
17885    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17886        && !flag_trapping_math
17887        && (TARGET_ROUND || !optimize_size))"
17888 {
17889   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17890       && !flag_trapping_math
17891       && (TARGET_ROUND || !optimize_size))
17892     {
17893       if (TARGET_ROUND)
17894         emit_insn (gen_sse4_1_round<mode>2
17895                    (operands[0], operands[1], GEN_INT (0x02)));
17896       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17897         ix86_expand_floorceil (operand0, operand1, false);
17898       else
17899         ix86_expand_floorceildf_32 (operand0, operand1, false);
17900     }
17901   else
17902     {
17903       rtx op0 = gen_reg_rtx (XFmode);
17904       rtx op1 = gen_reg_rtx (XFmode);
17905
17906       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17907       emit_insn (gen_frndintxf2_ceil (op0, op1));
17908
17909       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17910     }
17911   DONE;
17912 })
17913
17914 (define_insn_and_split "*fist<mode>2_ceil_1"
17915   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17916         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17917          UNSPEC_FIST_CEIL))
17918    (clobber (reg:CC FLAGS_REG))]
17919   "TARGET_USE_FANCY_MATH_387
17920    && flag_unsafe_math_optimizations
17921    && !(reload_completed || reload_in_progress)"
17922   "#"
17923   "&& 1"
17924   [(const_int 0)]
17925 {
17926   ix86_optimize_mode_switching[I387_CEIL] = 1;
17927
17928   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17929   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17930   if (memory_operand (operands[0], VOIDmode))
17931     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17932                                      operands[2], operands[3]));
17933   else
17934     {
17935       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17936       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17937                                                  operands[2], operands[3],
17938                                                  operands[4]));
17939     }
17940   DONE;
17941 }
17942   [(set_attr "type" "fistp")
17943    (set_attr "i387_cw" "ceil")
17944    (set_attr "mode" "<MODE>")])
17945
17946 (define_insn "fistdi2_ceil"
17947   [(set (match_operand:DI 0 "memory_operand" "=m")
17948         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17949          UNSPEC_FIST_CEIL))
17950    (use (match_operand:HI 2 "memory_operand" "m"))
17951    (use (match_operand:HI 3 "memory_operand" "m"))
17952    (clobber (match_scratch:XF 4 "=&1f"))]
17953   "TARGET_USE_FANCY_MATH_387
17954    && flag_unsafe_math_optimizations"
17955   "* return output_fix_trunc (insn, operands, 0);"
17956   [(set_attr "type" "fistp")
17957    (set_attr "i387_cw" "ceil")
17958    (set_attr "mode" "DI")])
17959
17960 (define_insn "fistdi2_ceil_with_temp"
17961   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17962         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17963          UNSPEC_FIST_CEIL))
17964    (use (match_operand:HI 2 "memory_operand" "m,m"))
17965    (use (match_operand:HI 3 "memory_operand" "m,m"))
17966    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17967    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17968   "TARGET_USE_FANCY_MATH_387
17969    && flag_unsafe_math_optimizations"
17970   "#"
17971   [(set_attr "type" "fistp")
17972    (set_attr "i387_cw" "ceil")
17973    (set_attr "mode" "DI")])
17974
17975 (define_split
17976   [(set (match_operand:DI 0 "register_operand" "")
17977         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17978          UNSPEC_FIST_CEIL))
17979    (use (match_operand:HI 2 "memory_operand" ""))
17980    (use (match_operand:HI 3 "memory_operand" ""))
17981    (clobber (match_operand:DI 4 "memory_operand" ""))
17982    (clobber (match_scratch 5 ""))]
17983   "reload_completed"
17984   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17985               (use (match_dup 2))
17986               (use (match_dup 3))
17987               (clobber (match_dup 5))])
17988    (set (match_dup 0) (match_dup 4))]
17989   "")
17990
17991 (define_split
17992   [(set (match_operand:DI 0 "memory_operand" "")
17993         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17994          UNSPEC_FIST_CEIL))
17995    (use (match_operand:HI 2 "memory_operand" ""))
17996    (use (match_operand:HI 3 "memory_operand" ""))
17997    (clobber (match_operand:DI 4 "memory_operand" ""))
17998    (clobber (match_scratch 5 ""))]
17999   "reload_completed"
18000   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18001               (use (match_dup 2))
18002               (use (match_dup 3))
18003               (clobber (match_dup 5))])]
18004   "")
18005
18006 (define_insn "fist<mode>2_ceil"
18007   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18008         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18009          UNSPEC_FIST_CEIL))
18010    (use (match_operand:HI 2 "memory_operand" "m"))
18011    (use (match_operand:HI 3 "memory_operand" "m"))]
18012   "TARGET_USE_FANCY_MATH_387
18013    && flag_unsafe_math_optimizations"
18014   "* return output_fix_trunc (insn, operands, 0);"
18015   [(set_attr "type" "fistp")
18016    (set_attr "i387_cw" "ceil")
18017    (set_attr "mode" "<MODE>")])
18018
18019 (define_insn "fist<mode>2_ceil_with_temp"
18020   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18021         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18022          UNSPEC_FIST_CEIL))
18023    (use (match_operand:HI 2 "memory_operand" "m,m"))
18024    (use (match_operand:HI 3 "memory_operand" "m,m"))
18025    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18026   "TARGET_USE_FANCY_MATH_387
18027    && flag_unsafe_math_optimizations"
18028   "#"
18029   [(set_attr "type" "fistp")
18030    (set_attr "i387_cw" "ceil")
18031    (set_attr "mode" "<MODE>")])
18032
18033 (define_split
18034   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18035         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18036          UNSPEC_FIST_CEIL))
18037    (use (match_operand:HI 2 "memory_operand" ""))
18038    (use (match_operand:HI 3 "memory_operand" ""))
18039    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18040   "reload_completed"
18041   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18042                                   UNSPEC_FIST_CEIL))
18043               (use (match_dup 2))
18044               (use (match_dup 3))])
18045    (set (match_dup 0) (match_dup 4))]
18046   "")
18047
18048 (define_split
18049   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18050         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18051          UNSPEC_FIST_CEIL))
18052    (use (match_operand:HI 2 "memory_operand" ""))
18053    (use (match_operand:HI 3 "memory_operand" ""))
18054    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18055   "reload_completed"
18056   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18057                                   UNSPEC_FIST_CEIL))
18058               (use (match_dup 2))
18059               (use (match_dup 3))])]
18060   "")
18061
18062 (define_expand "lceilxf<mode>2"
18063   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18064                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18065                     UNSPEC_FIST_CEIL))
18066               (clobber (reg:CC FLAGS_REG))])]
18067   "TARGET_USE_FANCY_MATH_387
18068    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18069    && flag_unsafe_math_optimizations"
18070   "")
18071
18072 (define_expand "lceil<mode>di2"
18073   [(match_operand:DI 0 "nonimmediate_operand" "")
18074    (match_operand:MODEF 1 "register_operand" "")]
18075   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18076    && !flag_trapping_math"
18077 {
18078   ix86_expand_lfloorceil (operand0, operand1, false);
18079   DONE;
18080 })
18081
18082 (define_expand "lceil<mode>si2"
18083   [(match_operand:SI 0 "nonimmediate_operand" "")
18084    (match_operand:MODEF 1 "register_operand" "")]
18085   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18086    && !flag_trapping_math"
18087 {
18088   ix86_expand_lfloorceil (operand0, operand1, false);
18089   DONE;
18090 })
18091
18092 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18093 (define_insn_and_split "frndintxf2_trunc"
18094   [(set (match_operand:XF 0 "register_operand" "")
18095         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18096          UNSPEC_FRNDINT_TRUNC))
18097    (clobber (reg:CC FLAGS_REG))]
18098   "TARGET_USE_FANCY_MATH_387
18099    && flag_unsafe_math_optimizations
18100    && !(reload_completed || reload_in_progress)"
18101   "#"
18102   "&& 1"
18103   [(const_int 0)]
18104 {
18105   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18106
18107   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18108   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18109
18110   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18111                                         operands[2], operands[3]));
18112   DONE;
18113 }
18114   [(set_attr "type" "frndint")
18115    (set_attr "i387_cw" "trunc")
18116    (set_attr "mode" "XF")])
18117
18118 (define_insn "frndintxf2_trunc_i387"
18119   [(set (match_operand:XF 0 "register_operand" "=f")
18120         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18121          UNSPEC_FRNDINT_TRUNC))
18122    (use (match_operand:HI 2 "memory_operand" "m"))
18123    (use (match_operand:HI 3 "memory_operand" "m"))]
18124   "TARGET_USE_FANCY_MATH_387
18125    && flag_unsafe_math_optimizations"
18126   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18127   [(set_attr "type" "frndint")
18128    (set_attr "i387_cw" "trunc")
18129    (set_attr "mode" "XF")])
18130
18131 (define_expand "btruncxf2"
18132   [(use (match_operand:XF 0 "register_operand" ""))
18133    (use (match_operand:XF 1 "register_operand" ""))]
18134   "TARGET_USE_FANCY_MATH_387
18135    && flag_unsafe_math_optimizations && !optimize_size"
18136 {
18137   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18138   DONE;
18139 })
18140
18141 (define_expand "btrunc<mode>2"
18142   [(use (match_operand:MODEF 0 "register_operand" ""))
18143    (use (match_operand:MODEF 1 "register_operand" ""))]
18144   "(TARGET_USE_FANCY_MATH_387
18145     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18146         || TARGET_MIX_SSE_I387)
18147     && flag_unsafe_math_optimizations && !optimize_size)
18148    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18149        && !flag_trapping_math
18150        && (TARGET_ROUND || !optimize_size))"
18151 {
18152   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18153       && !flag_trapping_math
18154       && (TARGET_ROUND || !optimize_size))
18155     {
18156       if (TARGET_ROUND)
18157         emit_insn (gen_sse4_1_round<mode>2
18158                    (operands[0], operands[1], GEN_INT (0x03)));
18159       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18160         ix86_expand_trunc (operand0, operand1);
18161       else
18162         ix86_expand_truncdf_32 (operand0, operand1);
18163     }
18164   else
18165     {
18166       rtx op0 = gen_reg_rtx (XFmode);
18167       rtx op1 = gen_reg_rtx (XFmode);
18168
18169       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18170       emit_insn (gen_frndintxf2_trunc (op0, op1));
18171
18172       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18173     }
18174   DONE;
18175 })
18176
18177 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18178 (define_insn_and_split "frndintxf2_mask_pm"
18179   [(set (match_operand:XF 0 "register_operand" "")
18180         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18181          UNSPEC_FRNDINT_MASK_PM))
18182    (clobber (reg:CC FLAGS_REG))]
18183   "TARGET_USE_FANCY_MATH_387
18184    && flag_unsafe_math_optimizations
18185    && !(reload_completed || reload_in_progress)"
18186   "#"
18187   "&& 1"
18188   [(const_int 0)]
18189 {
18190   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18191
18192   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18193   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18194
18195   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18196                                           operands[2], operands[3]));
18197   DONE;
18198 }
18199   [(set_attr "type" "frndint")
18200    (set_attr "i387_cw" "mask_pm")
18201    (set_attr "mode" "XF")])
18202
18203 (define_insn "frndintxf2_mask_pm_i387"
18204   [(set (match_operand:XF 0 "register_operand" "=f")
18205         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18206          UNSPEC_FRNDINT_MASK_PM))
18207    (use (match_operand:HI 2 "memory_operand" "m"))
18208    (use (match_operand:HI 3 "memory_operand" "m"))]
18209   "TARGET_USE_FANCY_MATH_387
18210    && flag_unsafe_math_optimizations"
18211   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18212   [(set_attr "type" "frndint")
18213    (set_attr "i387_cw" "mask_pm")
18214    (set_attr "mode" "XF")])
18215
18216 (define_expand "nearbyintxf2"
18217   [(use (match_operand:XF 0 "register_operand" ""))
18218    (use (match_operand:XF 1 "register_operand" ""))]
18219   "TARGET_USE_FANCY_MATH_387
18220    && flag_unsafe_math_optimizations"
18221 {
18222   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18223
18224   DONE;
18225 })
18226
18227 (define_expand "nearbyint<mode>2"
18228   [(use (match_operand:MODEF 0 "register_operand" ""))
18229    (use (match_operand:MODEF 1 "register_operand" ""))]
18230   "TARGET_USE_FANCY_MATH_387
18231    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18232        || TARGET_MIX_SSE_I387)
18233    && flag_unsafe_math_optimizations"
18234 {
18235   rtx op0 = gen_reg_rtx (XFmode);
18236   rtx op1 = gen_reg_rtx (XFmode);
18237
18238   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18239   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18240
18241   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18242   DONE;
18243 })
18244
18245 (define_insn "fxam<mode>2_i387"
18246   [(set (match_operand:HI 0 "register_operand" "=a")
18247         (unspec:HI
18248           [(match_operand:X87MODEF 1 "register_operand" "f")]
18249           UNSPEC_FXAM))]
18250   "TARGET_USE_FANCY_MATH_387"
18251   "fxam\n\tfnstsw\t%0"
18252   [(set_attr "type" "multi")
18253    (set_attr "unit" "i387")
18254    (set_attr "mode" "<MODE>")])
18255
18256 (define_expand "isinf<mode>2"
18257   [(use (match_operand:SI 0 "register_operand" ""))
18258    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18259   "TARGET_USE_FANCY_MATH_387
18260    && TARGET_C99_FUNCTIONS
18261    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18262 {
18263   rtx mask = GEN_INT (0x45);
18264   rtx val = GEN_INT (0x05);
18265
18266   rtx cond;
18267
18268   rtx scratch = gen_reg_rtx (HImode);
18269   rtx res = gen_reg_rtx (QImode);
18270
18271   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18272   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18273   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18274   cond = gen_rtx_fmt_ee (EQ, QImode,
18275                          gen_rtx_REG (CCmode, FLAGS_REG),
18276                          const0_rtx);
18277   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18278   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18279   DONE;
18280 })
18281
18282 (define_expand "signbit<mode>2"
18283   [(use (match_operand:SI 0 "register_operand" ""))
18284    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18285   "TARGET_USE_FANCY_MATH_387
18286    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18287 {
18288   rtx mask = GEN_INT (0x0200);
18289
18290   rtx scratch = gen_reg_rtx (HImode);
18291
18292   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18293   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18294   DONE;
18295 })
18296 \f
18297 ;; Block operation instructions
18298
18299 (define_expand "movmemsi"
18300   [(use (match_operand:BLK 0 "memory_operand" ""))
18301    (use (match_operand:BLK 1 "memory_operand" ""))
18302    (use (match_operand:SI 2 "nonmemory_operand" ""))
18303    (use (match_operand:SI 3 "const_int_operand" ""))
18304    (use (match_operand:SI 4 "const_int_operand" ""))
18305    (use (match_operand:SI 5 "const_int_operand" ""))]
18306   ""
18307 {
18308  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18309                          operands[4], operands[5]))
18310    DONE;
18311  else
18312    FAIL;
18313 })
18314
18315 (define_expand "movmemdi"
18316   [(use (match_operand:BLK 0 "memory_operand" ""))
18317    (use (match_operand:BLK 1 "memory_operand" ""))
18318    (use (match_operand:DI 2 "nonmemory_operand" ""))
18319    (use (match_operand:DI 3 "const_int_operand" ""))
18320    (use (match_operand:SI 4 "const_int_operand" ""))
18321    (use (match_operand:SI 5 "const_int_operand" ""))]
18322   "TARGET_64BIT"
18323 {
18324  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18325                          operands[4], operands[5]))
18326    DONE;
18327  else
18328    FAIL;
18329 })
18330
18331 ;; Most CPUs don't like single string operations
18332 ;; Handle this case here to simplify previous expander.
18333
18334 (define_expand "strmov"
18335   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18336    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18337    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18338               (clobber (reg:CC FLAGS_REG))])
18339    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18340               (clobber (reg:CC FLAGS_REG))])]
18341   ""
18342 {
18343   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18344
18345   /* If .md ever supports :P for Pmode, these can be directly
18346      in the pattern above.  */
18347   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18348   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18349
18350   /* Can't use this if the user has appropriated esi or edi.  */
18351   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18352       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18353     {
18354       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18355                                       operands[2], operands[3],
18356                                       operands[5], operands[6]));
18357       DONE;
18358     }
18359
18360   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18361 })
18362
18363 (define_expand "strmov_singleop"
18364   [(parallel [(set (match_operand 1 "memory_operand" "")
18365                    (match_operand 3 "memory_operand" ""))
18366               (set (match_operand 0 "register_operand" "")
18367                    (match_operand 4 "" ""))
18368               (set (match_operand 2 "register_operand" "")
18369                    (match_operand 5 "" ""))])]
18370   "TARGET_SINGLE_STRINGOP || optimize_size"
18371   "")
18372
18373 (define_insn "*strmovdi_rex_1"
18374   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18375         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18376    (set (match_operand:DI 0 "register_operand" "=D")
18377         (plus:DI (match_dup 2)
18378                  (const_int 8)))
18379    (set (match_operand:DI 1 "register_operand" "=S")
18380         (plus:DI (match_dup 3)
18381                  (const_int 8)))]
18382   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18383   "movsq"
18384   [(set_attr "type" "str")
18385    (set_attr "mode" "DI")
18386    (set_attr "memory" "both")])
18387
18388 (define_insn "*strmovsi_1"
18389   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18390         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18391    (set (match_operand:SI 0 "register_operand" "=D")
18392         (plus:SI (match_dup 2)
18393                  (const_int 4)))
18394    (set (match_operand:SI 1 "register_operand" "=S")
18395         (plus:SI (match_dup 3)
18396                  (const_int 4)))]
18397   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18398   "{movsl|movsd}"
18399   [(set_attr "type" "str")
18400    (set_attr "mode" "SI")
18401    (set_attr "memory" "both")])
18402
18403 (define_insn "*strmovsi_rex_1"
18404   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18405         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18406    (set (match_operand:DI 0 "register_operand" "=D")
18407         (plus:DI (match_dup 2)
18408                  (const_int 4)))
18409    (set (match_operand:DI 1 "register_operand" "=S")
18410         (plus:DI (match_dup 3)
18411                  (const_int 4)))]
18412   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413   "{movsl|movsd}"
18414   [(set_attr "type" "str")
18415    (set_attr "mode" "SI")
18416    (set_attr "memory" "both")])
18417
18418 (define_insn "*strmovhi_1"
18419   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18420         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18421    (set (match_operand:SI 0 "register_operand" "=D")
18422         (plus:SI (match_dup 2)
18423                  (const_int 2)))
18424    (set (match_operand:SI 1 "register_operand" "=S")
18425         (plus:SI (match_dup 3)
18426                  (const_int 2)))]
18427   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18428   "movsw"
18429   [(set_attr "type" "str")
18430    (set_attr "memory" "both")
18431    (set_attr "mode" "HI")])
18432
18433 (define_insn "*strmovhi_rex_1"
18434   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18435         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18436    (set (match_operand:DI 0 "register_operand" "=D")
18437         (plus:DI (match_dup 2)
18438                  (const_int 2)))
18439    (set (match_operand:DI 1 "register_operand" "=S")
18440         (plus:DI (match_dup 3)
18441                  (const_int 2)))]
18442   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18443   "movsw"
18444   [(set_attr "type" "str")
18445    (set_attr "memory" "both")
18446    (set_attr "mode" "HI")])
18447
18448 (define_insn "*strmovqi_1"
18449   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18450         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18451    (set (match_operand:SI 0 "register_operand" "=D")
18452         (plus:SI (match_dup 2)
18453                  (const_int 1)))
18454    (set (match_operand:SI 1 "register_operand" "=S")
18455         (plus:SI (match_dup 3)
18456                  (const_int 1)))]
18457   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18458   "movsb"
18459   [(set_attr "type" "str")
18460    (set_attr "memory" "both")
18461    (set_attr "mode" "QI")])
18462
18463 (define_insn "*strmovqi_rex_1"
18464   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18465         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18466    (set (match_operand:DI 0 "register_operand" "=D")
18467         (plus:DI (match_dup 2)
18468                  (const_int 1)))
18469    (set (match_operand:DI 1 "register_operand" "=S")
18470         (plus:DI (match_dup 3)
18471                  (const_int 1)))]
18472   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18473   "movsb"
18474   [(set_attr "type" "str")
18475    (set_attr "memory" "both")
18476    (set_attr "mode" "QI")])
18477
18478 (define_expand "rep_mov"
18479   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18480               (set (match_operand 0 "register_operand" "")
18481                    (match_operand 5 "" ""))
18482               (set (match_operand 2 "register_operand" "")
18483                    (match_operand 6 "" ""))
18484               (set (match_operand 1 "memory_operand" "")
18485                    (match_operand 3 "memory_operand" ""))
18486               (use (match_dup 4))])]
18487   ""
18488   "")
18489
18490 (define_insn "*rep_movdi_rex64"
18491   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18492    (set (match_operand:DI 0 "register_operand" "=D")
18493         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18494                             (const_int 3))
18495                  (match_operand:DI 3 "register_operand" "0")))
18496    (set (match_operand:DI 1 "register_operand" "=S")
18497         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18498                  (match_operand:DI 4 "register_operand" "1")))
18499    (set (mem:BLK (match_dup 3))
18500         (mem:BLK (match_dup 4)))
18501    (use (match_dup 5))]
18502   "TARGET_64BIT"
18503   "rep movsq"
18504   [(set_attr "type" "str")
18505    (set_attr "prefix_rep" "1")
18506    (set_attr "memory" "both")
18507    (set_attr "mode" "DI")])
18508
18509 (define_insn "*rep_movsi"
18510   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18511    (set (match_operand:SI 0 "register_operand" "=D")
18512         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18513                             (const_int 2))
18514                  (match_operand:SI 3 "register_operand" "0")))
18515    (set (match_operand:SI 1 "register_operand" "=S")
18516         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18517                  (match_operand:SI 4 "register_operand" "1")))
18518    (set (mem:BLK (match_dup 3))
18519         (mem:BLK (match_dup 4)))
18520    (use (match_dup 5))]
18521   "!TARGET_64BIT"
18522   "rep movs{l|d}"
18523   [(set_attr "type" "str")
18524    (set_attr "prefix_rep" "1")
18525    (set_attr "memory" "both")
18526    (set_attr "mode" "SI")])
18527
18528 (define_insn "*rep_movsi_rex64"
18529   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18530    (set (match_operand:DI 0 "register_operand" "=D")
18531         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18532                             (const_int 2))
18533                  (match_operand:DI 3 "register_operand" "0")))
18534    (set (match_operand:DI 1 "register_operand" "=S")
18535         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18536                  (match_operand:DI 4 "register_operand" "1")))
18537    (set (mem:BLK (match_dup 3))
18538         (mem:BLK (match_dup 4)))
18539    (use (match_dup 5))]
18540   "TARGET_64BIT"
18541   "rep movs{l|d}"
18542   [(set_attr "type" "str")
18543    (set_attr "prefix_rep" "1")
18544    (set_attr "memory" "both")
18545    (set_attr "mode" "SI")])
18546
18547 (define_insn "*rep_movqi"
18548   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18549    (set (match_operand:SI 0 "register_operand" "=D")
18550         (plus:SI (match_operand:SI 3 "register_operand" "0")
18551                  (match_operand:SI 5 "register_operand" "2")))
18552    (set (match_operand:SI 1 "register_operand" "=S")
18553         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18554    (set (mem:BLK (match_dup 3))
18555         (mem:BLK (match_dup 4)))
18556    (use (match_dup 5))]
18557   "!TARGET_64BIT"
18558   "rep movsb"
18559   [(set_attr "type" "str")
18560    (set_attr "prefix_rep" "1")
18561    (set_attr "memory" "both")
18562    (set_attr "mode" "SI")])
18563
18564 (define_insn "*rep_movqi_rex64"
18565   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18566    (set (match_operand:DI 0 "register_operand" "=D")
18567         (plus:DI (match_operand:DI 3 "register_operand" "0")
18568                  (match_operand:DI 5 "register_operand" "2")))
18569    (set (match_operand:DI 1 "register_operand" "=S")
18570         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18571    (set (mem:BLK (match_dup 3))
18572         (mem:BLK (match_dup 4)))
18573    (use (match_dup 5))]
18574   "TARGET_64BIT"
18575   "rep movsb"
18576   [(set_attr "type" "str")
18577    (set_attr "prefix_rep" "1")
18578    (set_attr "memory" "both")
18579    (set_attr "mode" "SI")])
18580
18581 (define_expand "setmemsi"
18582    [(use (match_operand:BLK 0 "memory_operand" ""))
18583     (use (match_operand:SI 1 "nonmemory_operand" ""))
18584     (use (match_operand 2 "const_int_operand" ""))
18585     (use (match_operand 3 "const_int_operand" ""))
18586     (use (match_operand:SI 4 "const_int_operand" ""))
18587     (use (match_operand:SI 5 "const_int_operand" ""))]
18588   ""
18589 {
18590  if (ix86_expand_setmem (operands[0], operands[1],
18591                          operands[2], operands[3],
18592                          operands[4], operands[5]))
18593    DONE;
18594  else
18595    FAIL;
18596 })
18597
18598 (define_expand "setmemdi"
18599    [(use (match_operand:BLK 0 "memory_operand" ""))
18600     (use (match_operand:DI 1 "nonmemory_operand" ""))
18601     (use (match_operand 2 "const_int_operand" ""))
18602     (use (match_operand 3 "const_int_operand" ""))
18603     (use (match_operand 4 "const_int_operand" ""))
18604     (use (match_operand 5 "const_int_operand" ""))]
18605   "TARGET_64BIT"
18606 {
18607  if (ix86_expand_setmem (operands[0], operands[1],
18608                          operands[2], operands[3],
18609                          operands[4], operands[5]))
18610    DONE;
18611  else
18612    FAIL;
18613 })
18614
18615 ;; Most CPUs don't like single string operations
18616 ;; Handle this case here to simplify previous expander.
18617
18618 (define_expand "strset"
18619   [(set (match_operand 1 "memory_operand" "")
18620         (match_operand 2 "register_operand" ""))
18621    (parallel [(set (match_operand 0 "register_operand" "")
18622                    (match_dup 3))
18623               (clobber (reg:CC FLAGS_REG))])]
18624   ""
18625 {
18626   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18627     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18628
18629   /* If .md ever supports :P for Pmode, this can be directly
18630      in the pattern above.  */
18631   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18632                               GEN_INT (GET_MODE_SIZE (GET_MODE
18633                                                       (operands[2]))));
18634   if (TARGET_SINGLE_STRINGOP || optimize_size)
18635     {
18636       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18637                                       operands[3]));
18638       DONE;
18639     }
18640 })
18641
18642 (define_expand "strset_singleop"
18643   [(parallel [(set (match_operand 1 "memory_operand" "")
18644                    (match_operand 2 "register_operand" ""))
18645               (set (match_operand 0 "register_operand" "")
18646                    (match_operand 3 "" ""))])]
18647   "TARGET_SINGLE_STRINGOP || optimize_size"
18648   "")
18649
18650 (define_insn "*strsetdi_rex_1"
18651   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18652         (match_operand:DI 2 "register_operand" "a"))
18653    (set (match_operand:DI 0 "register_operand" "=D")
18654         (plus:DI (match_dup 1)
18655                  (const_int 8)))]
18656   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18657   "stosq"
18658   [(set_attr "type" "str")
18659    (set_attr "memory" "store")
18660    (set_attr "mode" "DI")])
18661
18662 (define_insn "*strsetsi_1"
18663   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18664         (match_operand:SI 2 "register_operand" "a"))
18665    (set (match_operand:SI 0 "register_operand" "=D")
18666         (plus:SI (match_dup 1)
18667                  (const_int 4)))]
18668   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18669   "{stosl|stosd}"
18670   [(set_attr "type" "str")
18671    (set_attr "memory" "store")
18672    (set_attr "mode" "SI")])
18673
18674 (define_insn "*strsetsi_rex_1"
18675   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18676         (match_operand:SI 2 "register_operand" "a"))
18677    (set (match_operand:DI 0 "register_operand" "=D")
18678         (plus:DI (match_dup 1)
18679                  (const_int 4)))]
18680   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18681   "{stosl|stosd}"
18682   [(set_attr "type" "str")
18683    (set_attr "memory" "store")
18684    (set_attr "mode" "SI")])
18685
18686 (define_insn "*strsethi_1"
18687   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18688         (match_operand:HI 2 "register_operand" "a"))
18689    (set (match_operand:SI 0 "register_operand" "=D")
18690         (plus:SI (match_dup 1)
18691                  (const_int 2)))]
18692   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18693   "stosw"
18694   [(set_attr "type" "str")
18695    (set_attr "memory" "store")
18696    (set_attr "mode" "HI")])
18697
18698 (define_insn "*strsethi_rex_1"
18699   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18700         (match_operand:HI 2 "register_operand" "a"))
18701    (set (match_operand:DI 0 "register_operand" "=D")
18702         (plus:DI (match_dup 1)
18703                  (const_int 2)))]
18704   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18705   "stosw"
18706   [(set_attr "type" "str")
18707    (set_attr "memory" "store")
18708    (set_attr "mode" "HI")])
18709
18710 (define_insn "*strsetqi_1"
18711   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18712         (match_operand:QI 2 "register_operand" "a"))
18713    (set (match_operand:SI 0 "register_operand" "=D")
18714         (plus:SI (match_dup 1)
18715                  (const_int 1)))]
18716   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18717   "stosb"
18718   [(set_attr "type" "str")
18719    (set_attr "memory" "store")
18720    (set_attr "mode" "QI")])
18721
18722 (define_insn "*strsetqi_rex_1"
18723   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18724         (match_operand:QI 2 "register_operand" "a"))
18725    (set (match_operand:DI 0 "register_operand" "=D")
18726         (plus:DI (match_dup 1)
18727                  (const_int 1)))]
18728   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18729   "stosb"
18730   [(set_attr "type" "str")
18731    (set_attr "memory" "store")
18732    (set_attr "mode" "QI")])
18733
18734 (define_expand "rep_stos"
18735   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18736               (set (match_operand 0 "register_operand" "")
18737                    (match_operand 4 "" ""))
18738               (set (match_operand 2 "memory_operand" "") (const_int 0))
18739               (use (match_operand 3 "register_operand" ""))
18740               (use (match_dup 1))])]
18741   ""
18742   "")
18743
18744 (define_insn "*rep_stosdi_rex64"
18745   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18746    (set (match_operand:DI 0 "register_operand" "=D")
18747         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18748                             (const_int 3))
18749                  (match_operand:DI 3 "register_operand" "0")))
18750    (set (mem:BLK (match_dup 3))
18751         (const_int 0))
18752    (use (match_operand:DI 2 "register_operand" "a"))
18753    (use (match_dup 4))]
18754   "TARGET_64BIT"
18755   "rep stosq"
18756   [(set_attr "type" "str")
18757    (set_attr "prefix_rep" "1")
18758    (set_attr "memory" "store")
18759    (set_attr "mode" "DI")])
18760
18761 (define_insn "*rep_stossi"
18762   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18763    (set (match_operand:SI 0 "register_operand" "=D")
18764         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18765                             (const_int 2))
18766                  (match_operand:SI 3 "register_operand" "0")))
18767    (set (mem:BLK (match_dup 3))
18768         (const_int 0))
18769    (use (match_operand:SI 2 "register_operand" "a"))
18770    (use (match_dup 4))]
18771   "!TARGET_64BIT"
18772   "rep stos{l|d}"
18773   [(set_attr "type" "str")
18774    (set_attr "prefix_rep" "1")
18775    (set_attr "memory" "store")
18776    (set_attr "mode" "SI")])
18777
18778 (define_insn "*rep_stossi_rex64"
18779   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18780    (set (match_operand:DI 0 "register_operand" "=D")
18781         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18782                             (const_int 2))
18783                  (match_operand:DI 3 "register_operand" "0")))
18784    (set (mem:BLK (match_dup 3))
18785         (const_int 0))
18786    (use (match_operand:SI 2 "register_operand" "a"))
18787    (use (match_dup 4))]
18788   "TARGET_64BIT"
18789   "rep stos{l|d}"
18790   [(set_attr "type" "str")
18791    (set_attr "prefix_rep" "1")
18792    (set_attr "memory" "store")
18793    (set_attr "mode" "SI")])
18794
18795 (define_insn "*rep_stosqi"
18796   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18797    (set (match_operand:SI 0 "register_operand" "=D")
18798         (plus:SI (match_operand:SI 3 "register_operand" "0")
18799                  (match_operand:SI 4 "register_operand" "1")))
18800    (set (mem:BLK (match_dup 3))
18801         (const_int 0))
18802    (use (match_operand:QI 2 "register_operand" "a"))
18803    (use (match_dup 4))]
18804   "!TARGET_64BIT"
18805   "rep stosb"
18806   [(set_attr "type" "str")
18807    (set_attr "prefix_rep" "1")
18808    (set_attr "memory" "store")
18809    (set_attr "mode" "QI")])
18810
18811 (define_insn "*rep_stosqi_rex64"
18812   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18813    (set (match_operand:DI 0 "register_operand" "=D")
18814         (plus:DI (match_operand:DI 3 "register_operand" "0")
18815                  (match_operand:DI 4 "register_operand" "1")))
18816    (set (mem:BLK (match_dup 3))
18817         (const_int 0))
18818    (use (match_operand:QI 2 "register_operand" "a"))
18819    (use (match_dup 4))]
18820   "TARGET_64BIT"
18821   "rep stosb"
18822   [(set_attr "type" "str")
18823    (set_attr "prefix_rep" "1")
18824    (set_attr "memory" "store")
18825    (set_attr "mode" "QI")])
18826
18827 (define_expand "cmpstrnsi"
18828   [(set (match_operand:SI 0 "register_operand" "")
18829         (compare:SI (match_operand:BLK 1 "general_operand" "")
18830                     (match_operand:BLK 2 "general_operand" "")))
18831    (use (match_operand 3 "general_operand" ""))
18832    (use (match_operand 4 "immediate_operand" ""))]
18833   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18834 {
18835   rtx addr1, addr2, out, outlow, count, countreg, align;
18836
18837   /* Can't use this if the user has appropriated esi or edi.  */
18838   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18839     FAIL;
18840
18841   out = operands[0];
18842   if (!REG_P (out))
18843     out = gen_reg_rtx (SImode);
18844
18845   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18846   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18847   if (addr1 != XEXP (operands[1], 0))
18848     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18849   if (addr2 != XEXP (operands[2], 0))
18850     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18851
18852   count = operands[3];
18853   countreg = ix86_zero_extend_to_Pmode (count);
18854
18855   /* %%% Iff we are testing strict equality, we can use known alignment
18856      to good advantage.  This may be possible with combine, particularly
18857      once cc0 is dead.  */
18858   align = operands[4];
18859
18860   if (CONST_INT_P (count))
18861     {
18862       if (INTVAL (count) == 0)
18863         {
18864           emit_move_insn (operands[0], const0_rtx);
18865           DONE;
18866         }
18867       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18868                                      operands[1], operands[2]));
18869     }
18870   else
18871     {
18872       if (TARGET_64BIT)
18873         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18874       else
18875         emit_insn (gen_cmpsi_1 (countreg, countreg));
18876       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18877                                   operands[1], operands[2]));
18878     }
18879
18880   outlow = gen_lowpart (QImode, out);
18881   emit_insn (gen_cmpintqi (outlow));
18882   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18883
18884   if (operands[0] != out)
18885     emit_move_insn (operands[0], out);
18886
18887   DONE;
18888 })
18889
18890 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18891
18892 (define_expand "cmpintqi"
18893   [(set (match_dup 1)
18894         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18895    (set (match_dup 2)
18896         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18897    (parallel [(set (match_operand:QI 0 "register_operand" "")
18898                    (minus:QI (match_dup 1)
18899                              (match_dup 2)))
18900               (clobber (reg:CC FLAGS_REG))])]
18901   ""
18902   "operands[1] = gen_reg_rtx (QImode);
18903    operands[2] = gen_reg_rtx (QImode);")
18904
18905 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18906 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18907
18908 (define_expand "cmpstrnqi_nz_1"
18909   [(parallel [(set (reg:CC FLAGS_REG)
18910                    (compare:CC (match_operand 4 "memory_operand" "")
18911                                (match_operand 5 "memory_operand" "")))
18912               (use (match_operand 2 "register_operand" ""))
18913               (use (match_operand:SI 3 "immediate_operand" ""))
18914               (clobber (match_operand 0 "register_operand" ""))
18915               (clobber (match_operand 1 "register_operand" ""))
18916               (clobber (match_dup 2))])]
18917   ""
18918   "")
18919
18920 (define_insn "*cmpstrnqi_nz_1"
18921   [(set (reg:CC FLAGS_REG)
18922         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18923                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18924    (use (match_operand:SI 6 "register_operand" "2"))
18925    (use (match_operand:SI 3 "immediate_operand" "i"))
18926    (clobber (match_operand:SI 0 "register_operand" "=S"))
18927    (clobber (match_operand:SI 1 "register_operand" "=D"))
18928    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18929   "!TARGET_64BIT"
18930   "repz cmpsb"
18931   [(set_attr "type" "str")
18932    (set_attr "mode" "QI")
18933    (set_attr "prefix_rep" "1")])
18934
18935 (define_insn "*cmpstrnqi_nz_rex_1"
18936   [(set (reg:CC FLAGS_REG)
18937         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18938                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18939    (use (match_operand:DI 6 "register_operand" "2"))
18940    (use (match_operand:SI 3 "immediate_operand" "i"))
18941    (clobber (match_operand:DI 0 "register_operand" "=S"))
18942    (clobber (match_operand:DI 1 "register_operand" "=D"))
18943    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18944   "TARGET_64BIT"
18945   "repz cmpsb"
18946   [(set_attr "type" "str")
18947    (set_attr "mode" "QI")
18948    (set_attr "prefix_rep" "1")])
18949
18950 ;; The same, but the count is not known to not be zero.
18951
18952 (define_expand "cmpstrnqi_1"
18953   [(parallel [(set (reg:CC FLAGS_REG)
18954                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18955                                      (const_int 0))
18956                   (compare:CC (match_operand 4 "memory_operand" "")
18957                               (match_operand 5 "memory_operand" ""))
18958                   (const_int 0)))
18959               (use (match_operand:SI 3 "immediate_operand" ""))
18960               (use (reg:CC FLAGS_REG))
18961               (clobber (match_operand 0 "register_operand" ""))
18962               (clobber (match_operand 1 "register_operand" ""))
18963               (clobber (match_dup 2))])]
18964   ""
18965   "")
18966
18967 (define_insn "*cmpstrnqi_1"
18968   [(set (reg:CC FLAGS_REG)
18969         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18970                              (const_int 0))
18971           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18972                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18973           (const_int 0)))
18974    (use (match_operand:SI 3 "immediate_operand" "i"))
18975    (use (reg:CC FLAGS_REG))
18976    (clobber (match_operand:SI 0 "register_operand" "=S"))
18977    (clobber (match_operand:SI 1 "register_operand" "=D"))
18978    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18979   "!TARGET_64BIT"
18980   "repz cmpsb"
18981   [(set_attr "type" "str")
18982    (set_attr "mode" "QI")
18983    (set_attr "prefix_rep" "1")])
18984
18985 (define_insn "*cmpstrnqi_rex_1"
18986   [(set (reg:CC FLAGS_REG)
18987         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18988                              (const_int 0))
18989           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18990                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18991           (const_int 0)))
18992    (use (match_operand:SI 3 "immediate_operand" "i"))
18993    (use (reg:CC FLAGS_REG))
18994    (clobber (match_operand:DI 0 "register_operand" "=S"))
18995    (clobber (match_operand:DI 1 "register_operand" "=D"))
18996    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18997   "TARGET_64BIT"
18998   "repz cmpsb"
18999   [(set_attr "type" "str")
19000    (set_attr "mode" "QI")
19001    (set_attr "prefix_rep" "1")])
19002
19003 (define_expand "strlensi"
19004   [(set (match_operand:SI 0 "register_operand" "")
19005         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19006                     (match_operand:QI 2 "immediate_operand" "")
19007                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19008   ""
19009 {
19010  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19011    DONE;
19012  else
19013    FAIL;
19014 })
19015
19016 (define_expand "strlendi"
19017   [(set (match_operand:DI 0 "register_operand" "")
19018         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19019                     (match_operand:QI 2 "immediate_operand" "")
19020                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19021   ""
19022 {
19023  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19024    DONE;
19025  else
19026    FAIL;
19027 })
19028
19029 (define_expand "strlenqi_1"
19030   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19031               (clobber (match_operand 1 "register_operand" ""))
19032               (clobber (reg:CC FLAGS_REG))])]
19033   ""
19034   "")
19035
19036 (define_insn "*strlenqi_1"
19037   [(set (match_operand:SI 0 "register_operand" "=&c")
19038         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19039                     (match_operand:QI 2 "register_operand" "a")
19040                     (match_operand:SI 3 "immediate_operand" "i")
19041                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19042    (clobber (match_operand:SI 1 "register_operand" "=D"))
19043    (clobber (reg:CC FLAGS_REG))]
19044   "!TARGET_64BIT"
19045   "repnz scasb"
19046   [(set_attr "type" "str")
19047    (set_attr "mode" "QI")
19048    (set_attr "prefix_rep" "1")])
19049
19050 (define_insn "*strlenqi_rex_1"
19051   [(set (match_operand:DI 0 "register_operand" "=&c")
19052         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19053                     (match_operand:QI 2 "register_operand" "a")
19054                     (match_operand:DI 3 "immediate_operand" "i")
19055                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19056    (clobber (match_operand:DI 1 "register_operand" "=D"))
19057    (clobber (reg:CC FLAGS_REG))]
19058   "TARGET_64BIT"
19059   "repnz scasb"
19060   [(set_attr "type" "str")
19061    (set_attr "mode" "QI")
19062    (set_attr "prefix_rep" "1")])
19063
19064 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19065 ;; handled in combine, but it is not currently up to the task.
19066 ;; When used for their truth value, the cmpstrn* expanders generate
19067 ;; code like this:
19068 ;;
19069 ;;   repz cmpsb
19070 ;;   seta       %al
19071 ;;   setb       %dl
19072 ;;   cmpb       %al, %dl
19073 ;;   jcc        label
19074 ;;
19075 ;; The intermediate three instructions are unnecessary.
19076
19077 ;; This one handles cmpstrn*_nz_1...
19078 (define_peephole2
19079   [(parallel[
19080      (set (reg:CC FLAGS_REG)
19081           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19082                       (mem:BLK (match_operand 5 "register_operand" ""))))
19083      (use (match_operand 6 "register_operand" ""))
19084      (use (match_operand:SI 3 "immediate_operand" ""))
19085      (clobber (match_operand 0 "register_operand" ""))
19086      (clobber (match_operand 1 "register_operand" ""))
19087      (clobber (match_operand 2 "register_operand" ""))])
19088    (set (match_operand:QI 7 "register_operand" "")
19089         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19090    (set (match_operand:QI 8 "register_operand" "")
19091         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19092    (set (reg FLAGS_REG)
19093         (compare (match_dup 7) (match_dup 8)))
19094   ]
19095   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19096   [(parallel[
19097      (set (reg:CC FLAGS_REG)
19098           (compare:CC (mem:BLK (match_dup 4))
19099                       (mem:BLK (match_dup 5))))
19100      (use (match_dup 6))
19101      (use (match_dup 3))
19102      (clobber (match_dup 0))
19103      (clobber (match_dup 1))
19104      (clobber (match_dup 2))])]
19105   "")
19106
19107 ;; ...and this one handles cmpstrn*_1.
19108 (define_peephole2
19109   [(parallel[
19110      (set (reg:CC FLAGS_REG)
19111           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19112                                (const_int 0))
19113             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19114                         (mem:BLK (match_operand 5 "register_operand" "")))
19115             (const_int 0)))
19116      (use (match_operand:SI 3 "immediate_operand" ""))
19117      (use (reg:CC FLAGS_REG))
19118      (clobber (match_operand 0 "register_operand" ""))
19119      (clobber (match_operand 1 "register_operand" ""))
19120      (clobber (match_operand 2 "register_operand" ""))])
19121    (set (match_operand:QI 7 "register_operand" "")
19122         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19123    (set (match_operand:QI 8 "register_operand" "")
19124         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19125    (set (reg FLAGS_REG)
19126         (compare (match_dup 7) (match_dup 8)))
19127   ]
19128   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19129   [(parallel[
19130      (set (reg:CC FLAGS_REG)
19131           (if_then_else:CC (ne (match_dup 6)
19132                                (const_int 0))
19133             (compare:CC (mem:BLK (match_dup 4))
19134                         (mem:BLK (match_dup 5)))
19135             (const_int 0)))
19136      (use (match_dup 3))
19137      (use (reg:CC FLAGS_REG))
19138      (clobber (match_dup 0))
19139      (clobber (match_dup 1))
19140      (clobber (match_dup 2))])]
19141   "")
19142
19143
19144 \f
19145 ;; Conditional move instructions.
19146
19147 (define_expand "movdicc"
19148   [(set (match_operand:DI 0 "register_operand" "")
19149         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19150                          (match_operand:DI 2 "general_operand" "")
19151                          (match_operand:DI 3 "general_operand" "")))]
19152   "TARGET_64BIT"
19153   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19154
19155 (define_insn "x86_movdicc_0_m1_rex64"
19156   [(set (match_operand:DI 0 "register_operand" "=r")
19157         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19158           (const_int -1)
19159           (const_int 0)))
19160    (clobber (reg:CC FLAGS_REG))]
19161   "TARGET_64BIT"
19162   "sbb{q}\t%0, %0"
19163   ; Since we don't have the proper number of operands for an alu insn,
19164   ; fill in all the blanks.
19165   [(set_attr "type" "alu")
19166    (set_attr "pent_pair" "pu")
19167    (set_attr "memory" "none")
19168    (set_attr "imm_disp" "false")
19169    (set_attr "mode" "DI")
19170    (set_attr "length_immediate" "0")])
19171
19172 (define_insn "*x86_movdicc_0_m1_se"
19173   [(set (match_operand:DI 0 "register_operand" "=r")
19174         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19175                          (const_int 1)
19176                          (const_int 0)))
19177    (clobber (reg:CC FLAGS_REG))]
19178   ""
19179   "sbb{q}\t%0, %0"
19180   [(set_attr "type" "alu")
19181    (set_attr "pent_pair" "pu")
19182    (set_attr "memory" "none")
19183    (set_attr "imm_disp" "false")
19184    (set_attr "mode" "DI")
19185    (set_attr "length_immediate" "0")])
19186
19187 (define_insn "*movdicc_c_rex64"
19188   [(set (match_operand:DI 0 "register_operand" "=r,r")
19189         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19190                                 [(reg FLAGS_REG) (const_int 0)])
19191                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19192                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19193   "TARGET_64BIT && TARGET_CMOVE
19194    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19195   "@
19196    cmov%O2%C1\t{%2, %0|%0, %2}
19197    cmov%O2%c1\t{%3, %0|%0, %3}"
19198   [(set_attr "type" "icmov")
19199    (set_attr "mode" "DI")])
19200
19201 (define_expand "movsicc"
19202   [(set (match_operand:SI 0 "register_operand" "")
19203         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19204                          (match_operand:SI 2 "general_operand" "")
19205                          (match_operand:SI 3 "general_operand" "")))]
19206   ""
19207   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19208
19209 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19210 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19211 ;; So just document what we're doing explicitly.
19212
19213 (define_insn "x86_movsicc_0_m1"
19214   [(set (match_operand:SI 0 "register_operand" "=r")
19215         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19216           (const_int -1)
19217           (const_int 0)))
19218    (clobber (reg:CC FLAGS_REG))]
19219   ""
19220   "sbb{l}\t%0, %0"
19221   ; Since we don't have the proper number of operands for an alu insn,
19222   ; fill in all the blanks.
19223   [(set_attr "type" "alu")
19224    (set_attr "pent_pair" "pu")
19225    (set_attr "memory" "none")
19226    (set_attr "imm_disp" "false")
19227    (set_attr "mode" "SI")
19228    (set_attr "length_immediate" "0")])
19229
19230 (define_insn "*x86_movsicc_0_m1_se"
19231   [(set (match_operand:SI 0 "register_operand" "=r")
19232         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19233                          (const_int 1)
19234                          (const_int 0)))
19235    (clobber (reg:CC FLAGS_REG))]
19236   ""
19237   "sbb{l}\t%0, %0"
19238   [(set_attr "type" "alu")
19239    (set_attr "pent_pair" "pu")
19240    (set_attr "memory" "none")
19241    (set_attr "imm_disp" "false")
19242    (set_attr "mode" "SI")
19243    (set_attr "length_immediate" "0")])
19244
19245 (define_insn "*movsicc_noc"
19246   [(set (match_operand:SI 0 "register_operand" "=r,r")
19247         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19248                                 [(reg FLAGS_REG) (const_int 0)])
19249                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19250                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19251   "TARGET_CMOVE
19252    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19253   "@
19254    cmov%O2%C1\t{%2, %0|%0, %2}
19255    cmov%O2%c1\t{%3, %0|%0, %3}"
19256   [(set_attr "type" "icmov")
19257    (set_attr "mode" "SI")])
19258
19259 (define_expand "movhicc"
19260   [(set (match_operand:HI 0 "register_operand" "")
19261         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19262                          (match_operand:HI 2 "general_operand" "")
19263                          (match_operand:HI 3 "general_operand" "")))]
19264   "TARGET_HIMODE_MATH"
19265   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19266
19267 (define_insn "*movhicc_noc"
19268   [(set (match_operand:HI 0 "register_operand" "=r,r")
19269         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19270                                 [(reg FLAGS_REG) (const_int 0)])
19271                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19272                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19273   "TARGET_CMOVE
19274    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19275   "@
19276    cmov%O2%C1\t{%2, %0|%0, %2}
19277    cmov%O2%c1\t{%3, %0|%0, %3}"
19278   [(set_attr "type" "icmov")
19279    (set_attr "mode" "HI")])
19280
19281 (define_expand "movqicc"
19282   [(set (match_operand:QI 0 "register_operand" "")
19283         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19284                          (match_operand:QI 2 "general_operand" "")
19285                          (match_operand:QI 3 "general_operand" "")))]
19286   "TARGET_QIMODE_MATH"
19287   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19288
19289 (define_insn_and_split "*movqicc_noc"
19290   [(set (match_operand:QI 0 "register_operand" "=r,r")
19291         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19292                                 [(match_operand 4 "flags_reg_operand" "")
19293                                  (const_int 0)])
19294                       (match_operand:QI 2 "register_operand" "r,0")
19295                       (match_operand:QI 3 "register_operand" "0,r")))]
19296   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19297   "#"
19298   "&& reload_completed"
19299   [(set (match_dup 0)
19300         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19301                       (match_dup 2)
19302                       (match_dup 3)))]
19303   "operands[0] = gen_lowpart (SImode, operands[0]);
19304    operands[2] = gen_lowpart (SImode, operands[2]);
19305    operands[3] = gen_lowpart (SImode, operands[3]);"
19306   [(set_attr "type" "icmov")
19307    (set_attr "mode" "SI")])
19308
19309 (define_expand "mov<mode>cc"
19310   [(set (match_operand:X87MODEF 0 "register_operand" "")
19311         (if_then_else:X87MODEF
19312           (match_operand 1 "comparison_operator" "")
19313           (match_operand:X87MODEF 2 "register_operand" "")
19314           (match_operand:X87MODEF 3 "register_operand" "")))]
19315   "(TARGET_80387 && TARGET_CMOVE)
19316    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19317   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19318
19319 (define_insn "*movsfcc_1_387"
19320   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19321         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19322                                 [(reg FLAGS_REG) (const_int 0)])
19323                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19324                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19325   "TARGET_80387 && TARGET_CMOVE
19326    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19327   "@
19328    fcmov%F1\t{%2, %0|%0, %2}
19329    fcmov%f1\t{%3, %0|%0, %3}
19330    cmov%O2%C1\t{%2, %0|%0, %2}
19331    cmov%O2%c1\t{%3, %0|%0, %3}"
19332   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19333    (set_attr "mode" "SF,SF,SI,SI")])
19334
19335 (define_insn "*movdfcc_1"
19336   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19337         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19338                                 [(reg FLAGS_REG) (const_int 0)])
19339                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19340                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19341   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19342    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19343   "@
19344    fcmov%F1\t{%2, %0|%0, %2}
19345    fcmov%f1\t{%3, %0|%0, %3}
19346    #
19347    #"
19348   [(set_attr "type" "fcmov,fcmov,multi,multi")
19349    (set_attr "mode" "DF")])
19350
19351 (define_insn "*movdfcc_1_rex64"
19352   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19353         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19354                                 [(reg FLAGS_REG) (const_int 0)])
19355                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19356                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19357   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19358    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19359   "@
19360    fcmov%F1\t{%2, %0|%0, %2}
19361    fcmov%f1\t{%3, %0|%0, %3}
19362    cmov%O2%C1\t{%2, %0|%0, %2}
19363    cmov%O2%c1\t{%3, %0|%0, %3}"
19364   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19365    (set_attr "mode" "DF")])
19366
19367 (define_split
19368   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19369         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19370                                 [(match_operand 4 "flags_reg_operand" "")
19371                                  (const_int 0)])
19372                       (match_operand:DF 2 "nonimmediate_operand" "")
19373                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19374   "!TARGET_64BIT && reload_completed"
19375   [(set (match_dup 2)
19376         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19377                       (match_dup 5)
19378                       (match_dup 7)))
19379    (set (match_dup 3)
19380         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19381                       (match_dup 6)
19382                       (match_dup 8)))]
19383   "split_di (operands+2, 1, operands+5, operands+6);
19384    split_di (operands+3, 1, operands+7, operands+8);
19385    split_di (operands, 1, operands+2, operands+3);")
19386
19387 (define_insn "*movxfcc_1"
19388   [(set (match_operand:XF 0 "register_operand" "=f,f")
19389         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19390                                 [(reg FLAGS_REG) (const_int 0)])
19391                       (match_operand:XF 2 "register_operand" "f,0")
19392                       (match_operand:XF 3 "register_operand" "0,f")))]
19393   "TARGET_80387 && TARGET_CMOVE"
19394   "@
19395    fcmov%F1\t{%2, %0|%0, %2}
19396    fcmov%f1\t{%3, %0|%0, %3}"
19397   [(set_attr "type" "fcmov")
19398    (set_attr "mode" "XF")])
19399
19400 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19401 ;; the scalar versions to have only XMM registers as operands.
19402
19403 ;; SSE5 conditional move
19404 (define_insn "*sse5_pcmov_<mode>"
19405   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19406         (if_then_else:MODEF
19407           (match_operand:MODEF 1 "register_operand" "x,0")
19408           (match_operand:MODEF 2 "register_operand" "0,x")
19409           (match_operand:MODEF 3 "register_operand" "x,x")))]
19410   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19411   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19412   [(set_attr "type" "sse4arg")])
19413
19414 ;; These versions of the min/max patterns are intentionally ignorant of
19415 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19416 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19417 ;; are undefined in this condition, we're certain this is correct.
19418
19419 (define_insn "smin<mode>3"
19420   [(set (match_operand:MODEF 0 "register_operand" "=x")
19421         (smin:MODEF
19422           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19423           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19424   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19425   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19426   [(set_attr "type" "sseadd")
19427    (set_attr "mode" "<MODE>")])
19428
19429 (define_insn "smax<mode>3"
19430   [(set (match_operand:MODEF 0 "register_operand" "=x")
19431         (smax:MODEF
19432           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19433           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19434   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19435   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19436   [(set_attr "type" "sseadd")
19437    (set_attr "mode" "<MODE>")])
19438
19439 ;; These versions of the min/max patterns implement exactly the operations
19440 ;;   min = (op1 < op2 ? op1 : op2)
19441 ;;   max = (!(op1 < op2) ? op1 : op2)
19442 ;; Their operands are not commutative, and thus they may be used in the
19443 ;; presence of -0.0 and NaN.
19444
19445 (define_insn "*ieee_smin<mode>3"
19446   [(set (match_operand:MODEF 0 "register_operand" "=x")
19447         (unspec:MODEF
19448           [(match_operand:MODEF 1 "register_operand" "0")
19449            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19450          UNSPEC_IEEE_MIN))]
19451   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19452   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19453   [(set_attr "type" "sseadd")
19454    (set_attr "mode" "<MODE>")])
19455
19456 (define_insn "*ieee_smax<mode>3"
19457   [(set (match_operand:MODEF 0 "register_operand" "=x")
19458         (unspec:MODEF
19459           [(match_operand:MODEF 1 "register_operand" "0")
19460            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19461          UNSPEC_IEEE_MAX))]
19462   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19463   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19464   [(set_attr "type" "sseadd")
19465    (set_attr "mode" "<MODE>")])
19466
19467 ;; Make two stack loads independent:
19468 ;;   fld aa              fld aa
19469 ;;   fld %st(0)     ->   fld bb
19470 ;;   fmul bb             fmul %st(1), %st
19471 ;;
19472 ;; Actually we only match the last two instructions for simplicity.
19473 (define_peephole2
19474   [(set (match_operand 0 "fp_register_operand" "")
19475         (match_operand 1 "fp_register_operand" ""))
19476    (set (match_dup 0)
19477         (match_operator 2 "binary_fp_operator"
19478            [(match_dup 0)
19479             (match_operand 3 "memory_operand" "")]))]
19480   "REGNO (operands[0]) != REGNO (operands[1])"
19481   [(set (match_dup 0) (match_dup 3))
19482    (set (match_dup 0) (match_dup 4))]
19483
19484   ;; The % modifier is not operational anymore in peephole2's, so we have to
19485   ;; swap the operands manually in the case of addition and multiplication.
19486   "if (COMMUTATIVE_ARITH_P (operands[2]))
19487      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488                                  operands[0], operands[1]);
19489    else
19490      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491                                  operands[1], operands[0]);")
19492
19493 ;; Conditional addition patterns
19494 (define_expand "addqicc"
19495   [(match_operand:QI 0 "register_operand" "")
19496    (match_operand 1 "comparison_operator" "")
19497    (match_operand:QI 2 "register_operand" "")
19498    (match_operand:QI 3 "const_int_operand" "")]
19499   ""
19500   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19501
19502 (define_expand "addhicc"
19503   [(match_operand:HI 0 "register_operand" "")
19504    (match_operand 1 "comparison_operator" "")
19505    (match_operand:HI 2 "register_operand" "")
19506    (match_operand:HI 3 "const_int_operand" "")]
19507   ""
19508   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19509
19510 (define_expand "addsicc"
19511   [(match_operand:SI 0 "register_operand" "")
19512    (match_operand 1 "comparison_operator" "")
19513    (match_operand:SI 2 "register_operand" "")
19514    (match_operand:SI 3 "const_int_operand" "")]
19515   ""
19516   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19517
19518 (define_expand "adddicc"
19519   [(match_operand:DI 0 "register_operand" "")
19520    (match_operand 1 "comparison_operator" "")
19521    (match_operand:DI 2 "register_operand" "")
19522    (match_operand:DI 3 "const_int_operand" "")]
19523   "TARGET_64BIT"
19524   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19525
19526 \f
19527 ;; Misc patterns (?)
19528
19529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530 ;; Otherwise there will be nothing to keep
19531 ;;
19532 ;; [(set (reg ebp) (reg esp))]
19533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534 ;;  (clobber (eflags)]
19535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19536 ;;
19537 ;; in proper program order.
19538 (define_insn "pro_epilogue_adjust_stack_1"
19539   [(set (match_operand:SI 0 "register_operand" "=r,r")
19540         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541                  (match_operand:SI 2 "immediate_operand" "i,i")))
19542    (clobber (reg:CC FLAGS_REG))
19543    (clobber (mem:BLK (scratch)))]
19544   "!TARGET_64BIT"
19545 {
19546   switch (get_attr_type (insn))
19547     {
19548     case TYPE_IMOV:
19549       return "mov{l}\t{%1, %0|%0, %1}";
19550
19551     case TYPE_ALU:
19552       if (CONST_INT_P (operands[2])
19553           && (INTVAL (operands[2]) == 128
19554               || (INTVAL (operands[2]) < 0
19555                   && INTVAL (operands[2]) != -128)))
19556         {
19557           operands[2] = GEN_INT (-INTVAL (operands[2]));
19558           return "sub{l}\t{%2, %0|%0, %2}";
19559         }
19560       return "add{l}\t{%2, %0|%0, %2}";
19561
19562     case TYPE_LEA:
19563       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564       return "lea{l}\t{%a2, %0|%0, %a2}";
19565
19566     default:
19567       gcc_unreachable ();
19568     }
19569 }
19570   [(set (attr "type")
19571         (cond [(eq_attr "alternative" "0")
19572                  (const_string "alu")
19573                (match_operand:SI 2 "const0_operand" "")
19574                  (const_string "imov")
19575               ]
19576               (const_string "lea")))
19577    (set_attr "mode" "SI")])
19578
19579 (define_insn "pro_epilogue_adjust_stack_rex64"
19580   [(set (match_operand:DI 0 "register_operand" "=r,r")
19581         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583    (clobber (reg:CC FLAGS_REG))
19584    (clobber (mem:BLK (scratch)))]
19585   "TARGET_64BIT"
19586 {
19587   switch (get_attr_type (insn))
19588     {
19589     case TYPE_IMOV:
19590       return "mov{q}\t{%1, %0|%0, %1}";
19591
19592     case TYPE_ALU:
19593       if (CONST_INT_P (operands[2])
19594           /* Avoid overflows.  */
19595           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596           && (INTVAL (operands[2]) == 128
19597               || (INTVAL (operands[2]) < 0
19598                   && INTVAL (operands[2]) != -128)))
19599         {
19600           operands[2] = GEN_INT (-INTVAL (operands[2]));
19601           return "sub{q}\t{%2, %0|%0, %2}";
19602         }
19603       return "add{q}\t{%2, %0|%0, %2}";
19604
19605     case TYPE_LEA:
19606       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607       return "lea{q}\t{%a2, %0|%0, %a2}";
19608
19609     default:
19610       gcc_unreachable ();
19611     }
19612 }
19613   [(set (attr "type")
19614         (cond [(eq_attr "alternative" "0")
19615                  (const_string "alu")
19616                (match_operand:DI 2 "const0_operand" "")
19617                  (const_string "imov")
19618               ]
19619               (const_string "lea")))
19620    (set_attr "mode" "DI")])
19621
19622 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19623   [(set (match_operand:DI 0 "register_operand" "=r,r")
19624         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625                  (match_operand:DI 3 "immediate_operand" "i,i")))
19626    (use (match_operand:DI 2 "register_operand" "r,r"))
19627    (clobber (reg:CC FLAGS_REG))
19628    (clobber (mem:BLK (scratch)))]
19629   "TARGET_64BIT"
19630 {
19631   switch (get_attr_type (insn))
19632     {
19633     case TYPE_ALU:
19634       return "add{q}\t{%2, %0|%0, %2}";
19635
19636     case TYPE_LEA:
19637       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638       return "lea{q}\t{%a2, %0|%0, %a2}";
19639
19640     default:
19641       gcc_unreachable ();
19642     }
19643 }
19644   [(set_attr "type" "alu,lea")
19645    (set_attr "mode" "DI")])
19646
19647 (define_insn "allocate_stack_worker_32"
19648   [(set (match_operand:SI 0 "register_operand" "+a")
19649         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19650    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19651    (clobber (reg:CC FLAGS_REG))]
19652   "!TARGET_64BIT && TARGET_STACK_PROBE"
19653   "call\t___chkstk"
19654   [(set_attr "type" "multi")
19655    (set_attr "length" "5")])
19656
19657 (define_insn "allocate_stack_worker_64"
19658   [(set (match_operand:DI 0 "register_operand" "=a")
19659         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19660    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19661    (clobber (reg:DI R10_REG))
19662    (clobber (reg:DI R11_REG))
19663    (clobber (reg:CC FLAGS_REG))]
19664   "TARGET_64BIT && TARGET_STACK_PROBE"
19665   "call\t___chkstk"
19666   [(set_attr "type" "multi")
19667    (set_attr "length" "5")])
19668
19669 (define_expand "allocate_stack"
19670   [(match_operand 0 "register_operand" "")
19671    (match_operand 1 "general_operand" "")]
19672   "TARGET_STACK_PROBE"
19673 {
19674   rtx x;
19675
19676 #ifndef CHECK_STACK_LIMIT
19677 #define CHECK_STACK_LIMIT 0
19678 #endif
19679
19680   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19681       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19682     {
19683       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19684                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19685       if (x != stack_pointer_rtx)
19686         emit_move_insn (stack_pointer_rtx, x);
19687     }
19688   else
19689     {
19690       x = copy_to_mode_reg (Pmode, operands[1]);
19691       if (TARGET_64BIT)
19692         x = gen_allocate_stack_worker_64 (x);
19693       else
19694         x = gen_allocate_stack_worker_32 (x);
19695       emit_insn (x);
19696     }
19697
19698   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19699   DONE;
19700 })
19701
19702 (define_expand "builtin_setjmp_receiver"
19703   [(label_ref (match_operand 0 "" ""))]
19704   "!TARGET_64BIT && flag_pic"
19705 {
19706   if (TARGET_MACHO)
19707     {
19708       rtx xops[3];
19709       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19710       rtx label_rtx = gen_label_rtx ();
19711       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19712       xops[0] = xops[1] = picreg;
19713       xops[2] = gen_rtx_CONST (SImode,
19714                   gen_rtx_MINUS (SImode,
19715                     gen_rtx_LABEL_REF (SImode, label_rtx),
19716                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19717       ix86_expand_binary_operator (MINUS, SImode, xops);
19718     }
19719   else
19720     emit_insn (gen_set_got (pic_offset_table_rtx));
19721   DONE;
19722 })
19723 \f
19724 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19725
19726 (define_split
19727   [(set (match_operand 0 "register_operand" "")
19728         (match_operator 3 "promotable_binary_operator"
19729            [(match_operand 1 "register_operand" "")
19730             (match_operand 2 "aligned_operand" "")]))
19731    (clobber (reg:CC FLAGS_REG))]
19732   "! TARGET_PARTIAL_REG_STALL && reload_completed
19733    && ((GET_MODE (operands[0]) == HImode
19734         && ((!optimize_size && !TARGET_FAST_PREFIX)
19735             /* ??? next two lines just !satisfies_constraint_K (...) */
19736             || !CONST_INT_P (operands[2])
19737             || satisfies_constraint_K (operands[2])))
19738        || (GET_MODE (operands[0]) == QImode
19739            && (TARGET_PROMOTE_QImode || optimize_size)))"
19740   [(parallel [(set (match_dup 0)
19741                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19742               (clobber (reg:CC FLAGS_REG))])]
19743   "operands[0] = gen_lowpart (SImode, operands[0]);
19744    operands[1] = gen_lowpart (SImode, operands[1]);
19745    if (GET_CODE (operands[3]) != ASHIFT)
19746      operands[2] = gen_lowpart (SImode, operands[2]);
19747    PUT_MODE (operands[3], SImode);")
19748
19749 ; Promote the QImode tests, as i386 has encoding of the AND
19750 ; instruction with 32-bit sign-extended immediate and thus the
19751 ; instruction size is unchanged, except in the %eax case for
19752 ; which it is increased by one byte, hence the ! optimize_size.
19753 (define_split
19754   [(set (match_operand 0 "flags_reg_operand" "")
19755         (match_operator 2 "compare_operator"
19756           [(and (match_operand 3 "aligned_operand" "")
19757                 (match_operand 4 "const_int_operand" ""))
19758            (const_int 0)]))
19759    (set (match_operand 1 "register_operand" "")
19760         (and (match_dup 3) (match_dup 4)))]
19761   "! TARGET_PARTIAL_REG_STALL && reload_completed
19762    && ! optimize_size
19763    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19764        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19765    /* Ensure that the operand will remain sign-extended immediate.  */
19766    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19767   [(parallel [(set (match_dup 0)
19768                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19769                                     (const_int 0)]))
19770               (set (match_dup 1)
19771                    (and:SI (match_dup 3) (match_dup 4)))])]
19772 {
19773   operands[4]
19774     = gen_int_mode (INTVAL (operands[4])
19775                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19776   operands[1] = gen_lowpart (SImode, operands[1]);
19777   operands[3] = gen_lowpart (SImode, operands[3]);
19778 })
19779
19780 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19781 ; the TEST instruction with 32-bit sign-extended immediate and thus
19782 ; the instruction size would at least double, which is not what we
19783 ; want even with ! optimize_size.
19784 (define_split
19785   [(set (match_operand 0 "flags_reg_operand" "")
19786         (match_operator 1 "compare_operator"
19787           [(and (match_operand:HI 2 "aligned_operand" "")
19788                 (match_operand:HI 3 "const_int_operand" ""))
19789            (const_int 0)]))]
19790   "! TARGET_PARTIAL_REG_STALL && reload_completed
19791    && ! TARGET_FAST_PREFIX
19792    && ! optimize_size
19793    /* Ensure that the operand will remain sign-extended immediate.  */
19794    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19795   [(set (match_dup 0)
19796         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19797                          (const_int 0)]))]
19798 {
19799   operands[3]
19800     = gen_int_mode (INTVAL (operands[3])
19801                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19802   operands[2] = gen_lowpart (SImode, operands[2]);
19803 })
19804
19805 (define_split
19806   [(set (match_operand 0 "register_operand" "")
19807         (neg (match_operand 1 "register_operand" "")))
19808    (clobber (reg:CC FLAGS_REG))]
19809   "! TARGET_PARTIAL_REG_STALL && reload_completed
19810    && (GET_MODE (operands[0]) == HImode
19811        || (GET_MODE (operands[0]) == QImode
19812            && (TARGET_PROMOTE_QImode || optimize_size)))"
19813   [(parallel [(set (match_dup 0)
19814                    (neg:SI (match_dup 1)))
19815               (clobber (reg:CC FLAGS_REG))])]
19816   "operands[0] = gen_lowpart (SImode, operands[0]);
19817    operands[1] = gen_lowpart (SImode, operands[1]);")
19818
19819 (define_split
19820   [(set (match_operand 0 "register_operand" "")
19821         (not (match_operand 1 "register_operand" "")))]
19822   "! TARGET_PARTIAL_REG_STALL && reload_completed
19823    && (GET_MODE (operands[0]) == HImode
19824        || (GET_MODE (operands[0]) == QImode
19825            && (TARGET_PROMOTE_QImode || optimize_size)))"
19826   [(set (match_dup 0)
19827         (not:SI (match_dup 1)))]
19828   "operands[0] = gen_lowpart (SImode, operands[0]);
19829    operands[1] = gen_lowpart (SImode, operands[1]);")
19830
19831 (define_split
19832   [(set (match_operand 0 "register_operand" "")
19833         (if_then_else (match_operator 1 "comparison_operator"
19834                                 [(reg FLAGS_REG) (const_int 0)])
19835                       (match_operand 2 "register_operand" "")
19836                       (match_operand 3 "register_operand" "")))]
19837   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19838    && (GET_MODE (operands[0]) == HImode
19839        || (GET_MODE (operands[0]) == QImode
19840            && (TARGET_PROMOTE_QImode || optimize_size)))"
19841   [(set (match_dup 0)
19842         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19843   "operands[0] = gen_lowpart (SImode, operands[0]);
19844    operands[2] = gen_lowpart (SImode, operands[2]);
19845    operands[3] = gen_lowpart (SImode, operands[3]);")
19846
19847 \f
19848 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19849 ;; transform a complex memory operation into two memory to register operations.
19850
19851 ;; Don't push memory operands
19852 (define_peephole2
19853   [(set (match_operand:SI 0 "push_operand" "")
19854         (match_operand:SI 1 "memory_operand" ""))
19855    (match_scratch:SI 2 "r")]
19856   "!optimize_size && !TARGET_PUSH_MEMORY
19857    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19858   [(set (match_dup 2) (match_dup 1))
19859    (set (match_dup 0) (match_dup 2))]
19860   "")
19861
19862 (define_peephole2
19863   [(set (match_operand:DI 0 "push_operand" "")
19864         (match_operand:DI 1 "memory_operand" ""))
19865    (match_scratch:DI 2 "r")]
19866   "!optimize_size && !TARGET_PUSH_MEMORY
19867    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19868   [(set (match_dup 2) (match_dup 1))
19869    (set (match_dup 0) (match_dup 2))]
19870   "")
19871
19872 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19873 ;; SImode pushes.
19874 (define_peephole2
19875   [(set (match_operand:SF 0 "push_operand" "")
19876         (match_operand:SF 1 "memory_operand" ""))
19877    (match_scratch:SF 2 "r")]
19878   "!optimize_size && !TARGET_PUSH_MEMORY
19879    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19880   [(set (match_dup 2) (match_dup 1))
19881    (set (match_dup 0) (match_dup 2))]
19882   "")
19883
19884 (define_peephole2
19885   [(set (match_operand:HI 0 "push_operand" "")
19886         (match_operand:HI 1 "memory_operand" ""))
19887    (match_scratch:HI 2 "r")]
19888   "!optimize_size && !TARGET_PUSH_MEMORY
19889    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19890   [(set (match_dup 2) (match_dup 1))
19891    (set (match_dup 0) (match_dup 2))]
19892   "")
19893
19894 (define_peephole2
19895   [(set (match_operand:QI 0 "push_operand" "")
19896         (match_operand:QI 1 "memory_operand" ""))
19897    (match_scratch:QI 2 "q")]
19898   "!optimize_size && !TARGET_PUSH_MEMORY
19899    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19900   [(set (match_dup 2) (match_dup 1))
19901    (set (match_dup 0) (match_dup 2))]
19902   "")
19903
19904 ;; Don't move an immediate directly to memory when the instruction
19905 ;; gets too big.
19906 (define_peephole2
19907   [(match_scratch:SI 1 "r")
19908    (set (match_operand:SI 0 "memory_operand" "")
19909         (const_int 0))]
19910   "! optimize_size
19911    && ! TARGET_USE_MOV0
19912    && TARGET_SPLIT_LONG_MOVES
19913    && get_attr_length (insn) >= ix86_cost->large_insn
19914    && peep2_regno_dead_p (0, FLAGS_REG)"
19915   [(parallel [(set (match_dup 1) (const_int 0))
19916               (clobber (reg:CC FLAGS_REG))])
19917    (set (match_dup 0) (match_dup 1))]
19918   "")
19919
19920 (define_peephole2
19921   [(match_scratch:HI 1 "r")
19922    (set (match_operand:HI 0 "memory_operand" "")
19923         (const_int 0))]
19924   "! optimize_size
19925    && ! TARGET_USE_MOV0
19926    && TARGET_SPLIT_LONG_MOVES
19927    && get_attr_length (insn) >= ix86_cost->large_insn
19928    && peep2_regno_dead_p (0, FLAGS_REG)"
19929   [(parallel [(set (match_dup 2) (const_int 0))
19930               (clobber (reg:CC FLAGS_REG))])
19931    (set (match_dup 0) (match_dup 1))]
19932   "operands[2] = gen_lowpart (SImode, operands[1]);")
19933
19934 (define_peephole2
19935   [(match_scratch:QI 1 "q")
19936    (set (match_operand:QI 0 "memory_operand" "")
19937         (const_int 0))]
19938   "! optimize_size
19939    && ! TARGET_USE_MOV0
19940    && TARGET_SPLIT_LONG_MOVES
19941    && get_attr_length (insn) >= ix86_cost->large_insn
19942    && peep2_regno_dead_p (0, FLAGS_REG)"
19943   [(parallel [(set (match_dup 2) (const_int 0))
19944               (clobber (reg:CC FLAGS_REG))])
19945    (set (match_dup 0) (match_dup 1))]
19946   "operands[2] = gen_lowpart (SImode, operands[1]);")
19947
19948 (define_peephole2
19949   [(match_scratch:SI 2 "r")
19950    (set (match_operand:SI 0 "memory_operand" "")
19951         (match_operand:SI 1 "immediate_operand" ""))]
19952   "! optimize_size
19953    && TARGET_SPLIT_LONG_MOVES
19954    && get_attr_length (insn) >= ix86_cost->large_insn"
19955   [(set (match_dup 2) (match_dup 1))
19956    (set (match_dup 0) (match_dup 2))]
19957   "")
19958
19959 (define_peephole2
19960   [(match_scratch:HI 2 "r")
19961    (set (match_operand:HI 0 "memory_operand" "")
19962         (match_operand:HI 1 "immediate_operand" ""))]
19963   "! optimize_size
19964    && TARGET_SPLIT_LONG_MOVES
19965    && get_attr_length (insn) >= ix86_cost->large_insn"
19966   [(set (match_dup 2) (match_dup 1))
19967    (set (match_dup 0) (match_dup 2))]
19968   "")
19969
19970 (define_peephole2
19971   [(match_scratch:QI 2 "q")
19972    (set (match_operand:QI 0 "memory_operand" "")
19973         (match_operand:QI 1 "immediate_operand" ""))]
19974   "! optimize_size
19975    && TARGET_SPLIT_LONG_MOVES
19976    && get_attr_length (insn) >= ix86_cost->large_insn"
19977   [(set (match_dup 2) (match_dup 1))
19978    (set (match_dup 0) (match_dup 2))]
19979   "")
19980
19981 ;; Don't compare memory with zero, load and use a test instead.
19982 (define_peephole2
19983   [(set (match_operand 0 "flags_reg_operand" "")
19984         (match_operator 1 "compare_operator"
19985           [(match_operand:SI 2 "memory_operand" "")
19986            (const_int 0)]))
19987    (match_scratch:SI 3 "r")]
19988   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
19989   [(set (match_dup 3) (match_dup 2))
19990    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19991   "")
19992
19993 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19994 ;; Don't split NOTs with a displacement operand, because resulting XOR
19995 ;; will not be pairable anyway.
19996 ;;
19997 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19998 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19999 ;; so this split helps here as well.
20000 ;;
20001 ;; Note: Can't do this as a regular split because we can't get proper
20002 ;; lifetime information then.
20003
20004 (define_peephole2
20005   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20006         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20007   "!optimize_size
20008    && ((TARGET_NOT_UNPAIRABLE
20009         && (!MEM_P (operands[0])
20010             || !memory_displacement_operand (operands[0], SImode)))
20011        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20012    && peep2_regno_dead_p (0, FLAGS_REG)"
20013   [(parallel [(set (match_dup 0)
20014                    (xor:SI (match_dup 1) (const_int -1)))
20015               (clobber (reg:CC FLAGS_REG))])]
20016   "")
20017
20018 (define_peephole2
20019   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20020         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20021   "!optimize_size
20022    && ((TARGET_NOT_UNPAIRABLE
20023         && (!MEM_P (operands[0])
20024             || !memory_displacement_operand (operands[0], HImode)))
20025        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20026    && peep2_regno_dead_p (0, FLAGS_REG)"
20027   [(parallel [(set (match_dup 0)
20028                    (xor:HI (match_dup 1) (const_int -1)))
20029               (clobber (reg:CC FLAGS_REG))])]
20030   "")
20031
20032 (define_peephole2
20033   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20034         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20035   "!optimize_size
20036    && ((TARGET_NOT_UNPAIRABLE
20037         && (!MEM_P (operands[0])
20038             || !memory_displacement_operand (operands[0], QImode)))
20039        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20040    && peep2_regno_dead_p (0, FLAGS_REG)"
20041   [(parallel [(set (match_dup 0)
20042                    (xor:QI (match_dup 1) (const_int -1)))
20043               (clobber (reg:CC FLAGS_REG))])]
20044   "")
20045
20046 ;; Non pairable "test imm, reg" instructions can be translated to
20047 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20048 ;; byte opcode instead of two, have a short form for byte operands),
20049 ;; so do it for other CPUs as well.  Given that the value was dead,
20050 ;; this should not create any new dependencies.  Pass on the sub-word
20051 ;; versions if we're concerned about partial register stalls.
20052
20053 (define_peephole2
20054   [(set (match_operand 0 "flags_reg_operand" "")
20055         (match_operator 1 "compare_operator"
20056           [(and:SI (match_operand:SI 2 "register_operand" "")
20057                    (match_operand:SI 3 "immediate_operand" ""))
20058            (const_int 0)]))]
20059   "ix86_match_ccmode (insn, CCNOmode)
20060    && (true_regnum (operands[2]) != AX_REG
20061        || satisfies_constraint_K (operands[3]))
20062    && peep2_reg_dead_p (1, operands[2])"
20063   [(parallel
20064      [(set (match_dup 0)
20065            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20066                             (const_int 0)]))
20067       (set (match_dup 2)
20068            (and:SI (match_dup 2) (match_dup 3)))])]
20069   "")
20070
20071 ;; We don't need to handle HImode case, because it will be promoted to SImode
20072 ;; on ! TARGET_PARTIAL_REG_STALL
20073
20074 (define_peephole2
20075   [(set (match_operand 0 "flags_reg_operand" "")
20076         (match_operator 1 "compare_operator"
20077           [(and:QI (match_operand:QI 2 "register_operand" "")
20078                    (match_operand:QI 3 "immediate_operand" ""))
20079            (const_int 0)]))]
20080   "! TARGET_PARTIAL_REG_STALL
20081    && ix86_match_ccmode (insn, CCNOmode)
20082    && true_regnum (operands[2]) != AX_REG
20083    && peep2_reg_dead_p (1, operands[2])"
20084   [(parallel
20085      [(set (match_dup 0)
20086            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20087                             (const_int 0)]))
20088       (set (match_dup 2)
20089            (and:QI (match_dup 2) (match_dup 3)))])]
20090   "")
20091
20092 (define_peephole2
20093   [(set (match_operand 0 "flags_reg_operand" "")
20094         (match_operator 1 "compare_operator"
20095           [(and:SI
20096              (zero_extract:SI
20097                (match_operand 2 "ext_register_operand" "")
20098                (const_int 8)
20099                (const_int 8))
20100              (match_operand 3 "const_int_operand" ""))
20101            (const_int 0)]))]
20102   "! TARGET_PARTIAL_REG_STALL
20103    && ix86_match_ccmode (insn, CCNOmode)
20104    && true_regnum (operands[2]) != AX_REG
20105    && peep2_reg_dead_p (1, operands[2])"
20106   [(parallel [(set (match_dup 0)
20107                    (match_op_dup 1
20108                      [(and:SI
20109                         (zero_extract:SI
20110                           (match_dup 2)
20111                           (const_int 8)
20112                           (const_int 8))
20113                         (match_dup 3))
20114                       (const_int 0)]))
20115               (set (zero_extract:SI (match_dup 2)
20116                                     (const_int 8)
20117                                     (const_int 8))
20118                    (and:SI
20119                      (zero_extract:SI
20120                        (match_dup 2)
20121                        (const_int 8)
20122                        (const_int 8))
20123                      (match_dup 3)))])]
20124   "")
20125
20126 ;; Don't do logical operations with memory inputs.
20127 (define_peephole2
20128   [(match_scratch:SI 2 "r")
20129    (parallel [(set (match_operand:SI 0 "register_operand" "")
20130                    (match_operator:SI 3 "arith_or_logical_operator"
20131                      [(match_dup 0)
20132                       (match_operand:SI 1 "memory_operand" "")]))
20133               (clobber (reg:CC FLAGS_REG))])]
20134   "! optimize_size && ! TARGET_READ_MODIFY"
20135   [(set (match_dup 2) (match_dup 1))
20136    (parallel [(set (match_dup 0)
20137                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20138               (clobber (reg:CC FLAGS_REG))])]
20139   "")
20140
20141 (define_peephole2
20142   [(match_scratch:SI 2 "r")
20143    (parallel [(set (match_operand:SI 0 "register_operand" "")
20144                    (match_operator:SI 3 "arith_or_logical_operator"
20145                      [(match_operand:SI 1 "memory_operand" "")
20146                       (match_dup 0)]))
20147               (clobber (reg:CC FLAGS_REG))])]
20148   "! optimize_size && ! TARGET_READ_MODIFY"
20149   [(set (match_dup 2) (match_dup 1))
20150    (parallel [(set (match_dup 0)
20151                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20152               (clobber (reg:CC FLAGS_REG))])]
20153   "")
20154
20155 ; Don't do logical operations with memory outputs
20156 ;
20157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20158 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20159 ; the same decoder scheduling characteristics as the original.
20160
20161 (define_peephole2
20162   [(match_scratch:SI 2 "r")
20163    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20164                    (match_operator:SI 3 "arith_or_logical_operator"
20165                      [(match_dup 0)
20166                       (match_operand:SI 1 "nonmemory_operand" "")]))
20167               (clobber (reg:CC FLAGS_REG))])]
20168   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20169   [(set (match_dup 2) (match_dup 0))
20170    (parallel [(set (match_dup 2)
20171                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20172               (clobber (reg:CC FLAGS_REG))])
20173    (set (match_dup 0) (match_dup 2))]
20174   "")
20175
20176 (define_peephole2
20177   [(match_scratch:SI 2 "r")
20178    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20179                    (match_operator:SI 3 "arith_or_logical_operator"
20180                      [(match_operand:SI 1 "nonmemory_operand" "")
20181                       (match_dup 0)]))
20182               (clobber (reg:CC FLAGS_REG))])]
20183   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20184   [(set (match_dup 2) (match_dup 0))
20185    (parallel [(set (match_dup 2)
20186                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20187               (clobber (reg:CC FLAGS_REG))])
20188    (set (match_dup 0) (match_dup 2))]
20189   "")
20190
20191 ;; Attempt to always use XOR for zeroing registers.
20192 (define_peephole2
20193   [(set (match_operand 0 "register_operand" "")
20194         (match_operand 1 "const0_operand" ""))]
20195   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20196    && (! TARGET_USE_MOV0 || optimize_size)
20197    && GENERAL_REG_P (operands[0])
20198    && peep2_regno_dead_p (0, FLAGS_REG)"
20199   [(parallel [(set (match_dup 0) (const_int 0))
20200               (clobber (reg:CC FLAGS_REG))])]
20201 {
20202   operands[0] = gen_lowpart (word_mode, operands[0]);
20203 })
20204
20205 (define_peephole2
20206   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20207         (const_int 0))]
20208   "(GET_MODE (operands[0]) == QImode
20209     || GET_MODE (operands[0]) == HImode)
20210    && (! TARGET_USE_MOV0 || optimize_size)
20211    && peep2_regno_dead_p (0, FLAGS_REG)"
20212   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20213               (clobber (reg:CC FLAGS_REG))])])
20214
20215 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20216 (define_peephole2
20217   [(set (match_operand 0 "register_operand" "")
20218         (const_int -1))]
20219   "(GET_MODE (operands[0]) == HImode
20220     || GET_MODE (operands[0]) == SImode
20221     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20222    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20223    && peep2_regno_dead_p (0, FLAGS_REG)"
20224   [(parallel [(set (match_dup 0) (const_int -1))
20225               (clobber (reg:CC FLAGS_REG))])]
20226   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20227                               operands[0]);")
20228
20229 ;; Attempt to convert simple leas to adds. These can be created by
20230 ;; move expanders.
20231 (define_peephole2
20232   [(set (match_operand:SI 0 "register_operand" "")
20233         (plus:SI (match_dup 0)
20234                  (match_operand:SI 1 "nonmemory_operand" "")))]
20235   "peep2_regno_dead_p (0, FLAGS_REG)"
20236   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   "")
20239
20240 (define_peephole2
20241   [(set (match_operand:SI 0 "register_operand" "")
20242         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20243                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20244   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20245   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20246               (clobber (reg:CC FLAGS_REG))])]
20247   "operands[2] = gen_lowpart (SImode, operands[2]);")
20248
20249 (define_peephole2
20250   [(set (match_operand:DI 0 "register_operand" "")
20251         (plus:DI (match_dup 0)
20252                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20253   "peep2_regno_dead_p (0, FLAGS_REG)"
20254   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20255               (clobber (reg:CC FLAGS_REG))])]
20256   "")
20257
20258 (define_peephole2
20259   [(set (match_operand:SI 0 "register_operand" "")
20260         (mult:SI (match_dup 0)
20261                  (match_operand:SI 1 "const_int_operand" "")))]
20262   "exact_log2 (INTVAL (operands[1])) >= 0
20263    && peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20265               (clobber (reg:CC FLAGS_REG))])]
20266   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20267
20268 (define_peephole2
20269   [(set (match_operand:DI 0 "register_operand" "")
20270         (mult:DI (match_dup 0)
20271                  (match_operand:DI 1 "const_int_operand" "")))]
20272   "exact_log2 (INTVAL (operands[1])) >= 0
20273    && peep2_regno_dead_p (0, FLAGS_REG)"
20274   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20275               (clobber (reg:CC FLAGS_REG))])]
20276   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20277
20278 (define_peephole2
20279   [(set (match_operand:SI 0 "register_operand" "")
20280         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20281                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20282   "exact_log2 (INTVAL (operands[2])) >= 0
20283    && REGNO (operands[0]) == REGNO (operands[1])
20284    && peep2_regno_dead_p (0, FLAGS_REG)"
20285   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20286               (clobber (reg:CC FLAGS_REG))])]
20287   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20288
20289 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20290 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20291 ;; many CPUs it is also faster, since special hardware to avoid esp
20292 ;; dependencies is present.
20293
20294 ;; While some of these conversions may be done using splitters, we use peepholes
20295 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20296
20297 ;; Convert prologue esp subtractions to push.
20298 ;; We need register to push.  In order to keep verify_flow_info happy we have
20299 ;; two choices
20300 ;; - use scratch and clobber it in order to avoid dependencies
20301 ;; - use already live register
20302 ;; We can't use the second way right now, since there is no reliable way how to
20303 ;; verify that given register is live.  First choice will also most likely in
20304 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20305 ;; call clobbered registers are dead.  We may want to use base pointer as an
20306 ;; alternative when no register is available later.
20307
20308 (define_peephole2
20309   [(match_scratch:SI 0 "r")
20310    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20311               (clobber (reg:CC FLAGS_REG))
20312               (clobber (mem:BLK (scratch)))])]
20313   "optimize_size || !TARGET_SUB_ESP_4"
20314   [(clobber (match_dup 0))
20315    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20316               (clobber (mem:BLK (scratch)))])])
20317
20318 (define_peephole2
20319   [(match_scratch:SI 0 "r")
20320    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20321               (clobber (reg:CC FLAGS_REG))
20322               (clobber (mem:BLK (scratch)))])]
20323   "optimize_size || !TARGET_SUB_ESP_8"
20324   [(clobber (match_dup 0))
20325    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20326    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20327               (clobber (mem:BLK (scratch)))])])
20328
20329 ;; Convert esp subtractions to push.
20330 (define_peephole2
20331   [(match_scratch:SI 0 "r")
20332    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20333               (clobber (reg:CC FLAGS_REG))])]
20334   "optimize_size || !TARGET_SUB_ESP_4"
20335   [(clobber (match_dup 0))
20336    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20337
20338 (define_peephole2
20339   [(match_scratch:SI 0 "r")
20340    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20341               (clobber (reg:CC FLAGS_REG))])]
20342   "optimize_size || !TARGET_SUB_ESP_8"
20343   [(clobber (match_dup 0))
20344    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20345    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20346
20347 ;; Convert epilogue deallocator to pop.
20348 (define_peephole2
20349   [(match_scratch:SI 0 "r")
20350    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20351               (clobber (reg:CC FLAGS_REG))
20352               (clobber (mem:BLK (scratch)))])]
20353   "optimize_size || !TARGET_ADD_ESP_4"
20354   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20355               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20356               (clobber (mem:BLK (scratch)))])]
20357   "")
20358
20359 ;; Two pops case is tricky, since pop causes dependency on destination register.
20360 ;; We use two registers if available.
20361 (define_peephole2
20362   [(match_scratch:SI 0 "r")
20363    (match_scratch:SI 1 "r")
20364    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20365               (clobber (reg:CC FLAGS_REG))
20366               (clobber (mem:BLK (scratch)))])]
20367   "optimize_size || !TARGET_ADD_ESP_8"
20368   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20369               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20370               (clobber (mem:BLK (scratch)))])
20371    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20372               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20373   "")
20374
20375 (define_peephole2
20376   [(match_scratch:SI 0 "r")
20377    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20378               (clobber (reg:CC FLAGS_REG))
20379               (clobber (mem:BLK (scratch)))])]
20380   "optimize_size"
20381   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20382               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20383               (clobber (mem:BLK (scratch)))])
20384    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20385               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20386   "")
20387
20388 ;; Convert esp additions to pop.
20389 (define_peephole2
20390   [(match_scratch:SI 0 "r")
20391    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20392               (clobber (reg:CC FLAGS_REG))])]
20393   ""
20394   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20395               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20396   "")
20397
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20400 (define_peephole2
20401   [(match_scratch:SI 0 "r")
20402    (match_scratch:SI 1 "r")
20403    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20404               (clobber (reg:CC FLAGS_REG))])]
20405   ""
20406   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20407               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20408    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20409               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20410   "")
20411
20412 (define_peephole2
20413   [(match_scratch:SI 0 "r")
20414    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20415               (clobber (reg:CC FLAGS_REG))])]
20416   "optimize_size"
20417   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20418               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20419    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20420               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20421   "")
20422 \f
20423 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20424 ;; required and register dies.  Similarly for 128 to plus -128.
20425 (define_peephole2
20426   [(set (match_operand 0 "flags_reg_operand" "")
20427         (match_operator 1 "compare_operator"
20428           [(match_operand 2 "register_operand" "")
20429            (match_operand 3 "const_int_operand" "")]))]
20430   "(INTVAL (operands[3]) == -1
20431     || INTVAL (operands[3]) == 1
20432     || INTVAL (operands[3]) == 128)
20433    && ix86_match_ccmode (insn, CCGCmode)
20434    && peep2_reg_dead_p (1, operands[2])"
20435   [(parallel [(set (match_dup 0)
20436                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20437               (clobber (match_dup 2))])]
20438   "")
20439 \f
20440 (define_peephole2
20441   [(match_scratch:DI 0 "r")
20442    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20443               (clobber (reg:CC FLAGS_REG))
20444               (clobber (mem:BLK (scratch)))])]
20445   "optimize_size || !TARGET_SUB_ESP_4"
20446   [(clobber (match_dup 0))
20447    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20448               (clobber (mem:BLK (scratch)))])])
20449
20450 (define_peephole2
20451   [(match_scratch:DI 0 "r")
20452    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20453               (clobber (reg:CC FLAGS_REG))
20454               (clobber (mem:BLK (scratch)))])]
20455   "optimize_size || !TARGET_SUB_ESP_8"
20456   [(clobber (match_dup 0))
20457    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20458    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20459               (clobber (mem:BLK (scratch)))])])
20460
20461 ;; Convert esp subtractions to push.
20462 (define_peephole2
20463   [(match_scratch:DI 0 "r")
20464    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20465               (clobber (reg:CC FLAGS_REG))])]
20466   "optimize_size || !TARGET_SUB_ESP_4"
20467   [(clobber (match_dup 0))
20468    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20469
20470 (define_peephole2
20471   [(match_scratch:DI 0 "r")
20472    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20473               (clobber (reg:CC FLAGS_REG))])]
20474   "optimize_size || !TARGET_SUB_ESP_8"
20475   [(clobber (match_dup 0))
20476    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20477    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20478
20479 ;; Convert epilogue deallocator to pop.
20480 (define_peephole2
20481   [(match_scratch:DI 0 "r")
20482    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20483               (clobber (reg:CC FLAGS_REG))
20484               (clobber (mem:BLK (scratch)))])]
20485   "optimize_size || !TARGET_ADD_ESP_4"
20486   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20487               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20488               (clobber (mem:BLK (scratch)))])]
20489   "")
20490
20491 ;; Two pops case is tricky, since pop causes dependency on destination register.
20492 ;; We use two registers if available.
20493 (define_peephole2
20494   [(match_scratch:DI 0 "r")
20495    (match_scratch:DI 1 "r")
20496    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20497               (clobber (reg:CC FLAGS_REG))
20498               (clobber (mem:BLK (scratch)))])]
20499   "optimize_size || !TARGET_ADD_ESP_8"
20500   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20501               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20502               (clobber (mem:BLK (scratch)))])
20503    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20504               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20505   "")
20506
20507 (define_peephole2
20508   [(match_scratch:DI 0 "r")
20509    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20510               (clobber (reg:CC FLAGS_REG))
20511               (clobber (mem:BLK (scratch)))])]
20512   "optimize_size"
20513   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20514               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20515               (clobber (mem:BLK (scratch)))])
20516    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20517               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20518   "")
20519
20520 ;; Convert esp additions to pop.
20521 (define_peephole2
20522   [(match_scratch:DI 0 "r")
20523    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20524               (clobber (reg:CC FLAGS_REG))])]
20525   ""
20526   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20527               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20528   "")
20529
20530 ;; Two pops case is tricky, since pop causes dependency on destination register.
20531 ;; We use two registers if available.
20532 (define_peephole2
20533   [(match_scratch:DI 0 "r")
20534    (match_scratch:DI 1 "r")
20535    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20536               (clobber (reg:CC FLAGS_REG))])]
20537   ""
20538   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20539               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20540    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20541               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20542   "")
20543
20544 (define_peephole2
20545   [(match_scratch:DI 0 "r")
20546    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20547               (clobber (reg:CC FLAGS_REG))])]
20548   "optimize_size"
20549   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20550               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20551    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20552               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20553   "")
20554 \f
20555 ;; Convert imul by three, five and nine into lea
20556 (define_peephole2
20557   [(parallel
20558     [(set (match_operand:SI 0 "register_operand" "")
20559           (mult:SI (match_operand:SI 1 "register_operand" "")
20560                    (match_operand:SI 2 "const_int_operand" "")))
20561      (clobber (reg:CC FLAGS_REG))])]
20562   "INTVAL (operands[2]) == 3
20563    || INTVAL (operands[2]) == 5
20564    || INTVAL (operands[2]) == 9"
20565   [(set (match_dup 0)
20566         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20567                  (match_dup 1)))]
20568   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20569
20570 (define_peephole2
20571   [(parallel
20572     [(set (match_operand:SI 0 "register_operand" "")
20573           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20574                    (match_operand:SI 2 "const_int_operand" "")))
20575      (clobber (reg:CC FLAGS_REG))])]
20576   "!optimize_size
20577    && (INTVAL (operands[2]) == 3
20578        || INTVAL (operands[2]) == 5
20579        || INTVAL (operands[2]) == 9)"
20580   [(set (match_dup 0) (match_dup 1))
20581    (set (match_dup 0)
20582         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20583                  (match_dup 0)))]
20584   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20585
20586 (define_peephole2
20587   [(parallel
20588     [(set (match_operand:DI 0 "register_operand" "")
20589           (mult:DI (match_operand:DI 1 "register_operand" "")
20590                    (match_operand:DI 2 "const_int_operand" "")))
20591      (clobber (reg:CC FLAGS_REG))])]
20592   "TARGET_64BIT
20593    && (INTVAL (operands[2]) == 3
20594        || INTVAL (operands[2]) == 5
20595        || INTVAL (operands[2]) == 9)"
20596   [(set (match_dup 0)
20597         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20598                  (match_dup 1)))]
20599   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20600
20601 (define_peephole2
20602   [(parallel
20603     [(set (match_operand:DI 0 "register_operand" "")
20604           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20605                    (match_operand:DI 2 "const_int_operand" "")))
20606      (clobber (reg:CC FLAGS_REG))])]
20607   "TARGET_64BIT
20608    && !optimize_size
20609    && (INTVAL (operands[2]) == 3
20610        || INTVAL (operands[2]) == 5
20611        || INTVAL (operands[2]) == 9)"
20612   [(set (match_dup 0) (match_dup 1))
20613    (set (match_dup 0)
20614         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20615                  (match_dup 0)))]
20616   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20617
20618 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20619 ;; imul $32bit_imm, reg, reg is direct decoded.
20620 (define_peephole2
20621   [(match_scratch:DI 3 "r")
20622    (parallel [(set (match_operand:DI 0 "register_operand" "")
20623                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20624                             (match_operand:DI 2 "immediate_operand" "")))
20625               (clobber (reg:CC FLAGS_REG))])]
20626   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20627    && !satisfies_constraint_K (operands[2])"
20628   [(set (match_dup 3) (match_dup 1))
20629    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20630               (clobber (reg:CC FLAGS_REG))])]
20631 "")
20632
20633 (define_peephole2
20634   [(match_scratch:SI 3 "r")
20635    (parallel [(set (match_operand:SI 0 "register_operand" "")
20636                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20637                             (match_operand:SI 2 "immediate_operand" "")))
20638               (clobber (reg:CC FLAGS_REG))])]
20639   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20640    && !satisfies_constraint_K (operands[2])"
20641   [(set (match_dup 3) (match_dup 1))
20642    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20643               (clobber (reg:CC FLAGS_REG))])]
20644 "")
20645
20646 (define_peephole2
20647   [(match_scratch:SI 3 "r")
20648    (parallel [(set (match_operand:DI 0 "register_operand" "")
20649                    (zero_extend:DI
20650                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20651                               (match_operand:SI 2 "immediate_operand" ""))))
20652               (clobber (reg:CC FLAGS_REG))])]
20653   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20654    && !satisfies_constraint_K (operands[2])"
20655   [(set (match_dup 3) (match_dup 1))
20656    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20657               (clobber (reg:CC FLAGS_REG))])]
20658 "")
20659
20660 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20661 ;; Convert it into imul reg, reg
20662 ;; It would be better to force assembler to encode instruction using long
20663 ;; immediate, but there is apparently no way to do so.
20664 (define_peephole2
20665   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20666                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20667                             (match_operand:DI 2 "const_int_operand" "")))
20668               (clobber (reg:CC FLAGS_REG))])
20669    (match_scratch:DI 3 "r")]
20670   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20671    && satisfies_constraint_K (operands[2])"
20672   [(set (match_dup 3) (match_dup 2))
20673    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20674               (clobber (reg:CC FLAGS_REG))])]
20675 {
20676   if (!rtx_equal_p (operands[0], operands[1]))
20677     emit_move_insn (operands[0], operands[1]);
20678 })
20679
20680 (define_peephole2
20681   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20682                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20683                             (match_operand:SI 2 "const_int_operand" "")))
20684               (clobber (reg:CC FLAGS_REG))])
20685    (match_scratch:SI 3 "r")]
20686   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20687    && satisfies_constraint_K (operands[2])"
20688   [(set (match_dup 3) (match_dup 2))
20689    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20690               (clobber (reg:CC FLAGS_REG))])]
20691 {
20692   if (!rtx_equal_p (operands[0], operands[1]))
20693     emit_move_insn (operands[0], operands[1]);
20694 })
20695
20696 (define_peephole2
20697   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20698                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20699                             (match_operand:HI 2 "immediate_operand" "")))
20700               (clobber (reg:CC FLAGS_REG))])
20701    (match_scratch:HI 3 "r")]
20702   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20703   [(set (match_dup 3) (match_dup 2))
20704    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20705               (clobber (reg:CC FLAGS_REG))])]
20706 {
20707   if (!rtx_equal_p (operands[0], operands[1]))
20708     emit_move_insn (operands[0], operands[1]);
20709 })
20710
20711 ;; After splitting up read-modify operations, array accesses with memory
20712 ;; operands might end up in form:
20713 ;;  sall    $2, %eax
20714 ;;  movl    4(%esp), %edx
20715 ;;  addl    %edx, %eax
20716 ;; instead of pre-splitting:
20717 ;;  sall    $2, %eax
20718 ;;  addl    4(%esp), %eax
20719 ;; Turn it into:
20720 ;;  movl    4(%esp), %edx
20721 ;;  leal    (%edx,%eax,4), %eax
20722
20723 (define_peephole2
20724   [(parallel [(set (match_operand 0 "register_operand" "")
20725                    (ashift (match_operand 1 "register_operand" "")
20726                            (match_operand 2 "const_int_operand" "")))
20727                (clobber (reg:CC FLAGS_REG))])
20728    (set (match_operand 3 "register_operand")
20729         (match_operand 4 "x86_64_general_operand" ""))
20730    (parallel [(set (match_operand 5 "register_operand" "")
20731                    (plus (match_operand 6 "register_operand" "")
20732                          (match_operand 7 "register_operand" "")))
20733                    (clobber (reg:CC FLAGS_REG))])]
20734   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20735    /* Validate MODE for lea.  */
20736    && ((!TARGET_PARTIAL_REG_STALL
20737         && (GET_MODE (operands[0]) == QImode
20738             || GET_MODE (operands[0]) == HImode))
20739        || GET_MODE (operands[0]) == SImode
20740        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20741    /* We reorder load and the shift.  */
20742    && !rtx_equal_p (operands[1], operands[3])
20743    && !reg_overlap_mentioned_p (operands[0], operands[4])
20744    /* Last PLUS must consist of operand 0 and 3.  */
20745    && !rtx_equal_p (operands[0], operands[3])
20746    && (rtx_equal_p (operands[3], operands[6])
20747        || rtx_equal_p (operands[3], operands[7]))
20748    && (rtx_equal_p (operands[0], operands[6])
20749        || rtx_equal_p (operands[0], operands[7]))
20750    /* The intermediate operand 0 must die or be same as output.  */
20751    && (rtx_equal_p (operands[0], operands[5])
20752        || peep2_reg_dead_p (3, operands[0]))"
20753   [(set (match_dup 3) (match_dup 4))
20754    (set (match_dup 0) (match_dup 1))]
20755 {
20756   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20757   int scale = 1 << INTVAL (operands[2]);
20758   rtx index = gen_lowpart (Pmode, operands[1]);
20759   rtx base = gen_lowpart (Pmode, operands[3]);
20760   rtx dest = gen_lowpart (mode, operands[5]);
20761
20762   operands[1] = gen_rtx_PLUS (Pmode, base,
20763                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20764   if (mode != Pmode)
20765     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20766   operands[0] = dest;
20767 })
20768 \f
20769 ;; Call-value patterns last so that the wildcard operand does not
20770 ;; disrupt insn-recog's switch tables.
20771
20772 (define_insn "*call_value_pop_0"
20773   [(set (match_operand 0 "" "")
20774         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20775               (match_operand:SI 2 "" "")))
20776    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20777                             (match_operand:SI 3 "immediate_operand" "")))]
20778   "!TARGET_64BIT"
20779 {
20780   if (SIBLING_CALL_P (insn))
20781     return "jmp\t%P1";
20782   else
20783     return "call\t%P1";
20784 }
20785   [(set_attr "type" "callv")])
20786
20787 (define_insn "*call_value_pop_1"
20788   [(set (match_operand 0 "" "")
20789         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20790               (match_operand:SI 2 "" "")))
20791    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20792                             (match_operand:SI 3 "immediate_operand" "i")))]
20793   "!TARGET_64BIT"
20794 {
20795   if (constant_call_address_operand (operands[1], Pmode))
20796     {
20797       if (SIBLING_CALL_P (insn))
20798         return "jmp\t%P1";
20799       else
20800         return "call\t%P1";
20801     }
20802   if (SIBLING_CALL_P (insn))
20803     return "jmp\t%A1";
20804   else
20805     return "call\t%A1";
20806 }
20807   [(set_attr "type" "callv")])
20808
20809 (define_insn "*call_value_0"
20810   [(set (match_operand 0 "" "")
20811         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20812               (match_operand:SI 2 "" "")))]
20813   "!TARGET_64BIT"
20814 {
20815   if (SIBLING_CALL_P (insn))
20816     return "jmp\t%P1";
20817   else
20818     return "call\t%P1";
20819 }
20820   [(set_attr "type" "callv")])
20821
20822 (define_insn "*call_value_0_rex64"
20823   [(set (match_operand 0 "" "")
20824         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20825               (match_operand:DI 2 "const_int_operand" "")))]
20826   "TARGET_64BIT"
20827 {
20828   if (SIBLING_CALL_P (insn))
20829     return "jmp\t%P1";
20830   else
20831     return "call\t%P1";
20832 }
20833   [(set_attr "type" "callv")])
20834
20835 (define_insn "*call_value_1"
20836   [(set (match_operand 0 "" "")
20837         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20838               (match_operand:SI 2 "" "")))]
20839   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20840 {
20841   if (constant_call_address_operand (operands[1], Pmode))
20842     return "call\t%P1";
20843   return "call\t%A1";
20844 }
20845   [(set_attr "type" "callv")])
20846
20847 (define_insn "*sibcall_value_1"
20848   [(set (match_operand 0 "" "")
20849         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20850               (match_operand:SI 2 "" "")))]
20851   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20852 {
20853   if (constant_call_address_operand (operands[1], Pmode))
20854     return "jmp\t%P1";
20855   return "jmp\t%A1";
20856 }
20857   [(set_attr "type" "callv")])
20858
20859 (define_insn "*call_value_1_rex64"
20860   [(set (match_operand 0 "" "")
20861         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20862               (match_operand:DI 2 "" "")))]
20863   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20864    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20865 {
20866   if (constant_call_address_operand (operands[1], Pmode))
20867     return "call\t%P1";
20868   return "call\t%A1";
20869 }
20870   [(set_attr "type" "callv")])
20871
20872 (define_insn "*call_value_1_rex64_large"
20873   [(set (match_operand 0 "" "")
20874         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20875               (match_operand:DI 2 "" "")))]
20876   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20877   "call\t%A1"
20878   [(set_attr "type" "callv")])
20879
20880 (define_insn "*sibcall_value_1_rex64"
20881   [(set (match_operand 0 "" "")
20882         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20883               (match_operand:DI 2 "" "")))]
20884   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20885   "jmp\t%P1"
20886   [(set_attr "type" "callv")])
20887
20888 (define_insn "*sibcall_value_1_rex64_v"
20889   [(set (match_operand 0 "" "")
20890         (call (mem:QI (reg:DI R11_REG))
20891               (match_operand:DI 1 "" "")))]
20892   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20893   "jmp\t{*%%}r11"
20894   [(set_attr "type" "callv")])
20895 \f
20896 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20897 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20898 ;; caught for use by garbage collectors and the like.  Using an insn that
20899 ;; maps to SIGILL makes it more likely the program will rightfully die.
20900 ;; Keeping with tradition, "6" is in honor of #UD.
20901 (define_insn "trap"
20902   [(trap_if (const_int 1) (const_int 6))]
20903   ""
20904   { return ASM_SHORT "0x0b0f"; }
20905   [(set_attr "length" "2")])
20906
20907 (define_expand "sse_prologue_save"
20908   [(parallel [(set (match_operand:BLK 0 "" "")
20909                    (unspec:BLK [(reg:DI 21)
20910                                 (reg:DI 22)
20911                                 (reg:DI 23)
20912                                 (reg:DI 24)
20913                                 (reg:DI 25)
20914                                 (reg:DI 26)
20915                                 (reg:DI 27)
20916                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20917               (use (match_operand:DI 1 "register_operand" ""))
20918               (use (match_operand:DI 2 "immediate_operand" ""))
20919               (use (label_ref:DI (match_operand 3 "" "")))])]
20920   "TARGET_64BIT"
20921   "")
20922
20923 (define_insn "*sse_prologue_save_insn"
20924   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20925                           (match_operand:DI 4 "const_int_operand" "n")))
20926         (unspec:BLK [(reg:DI 21)
20927                      (reg:DI 22)
20928                      (reg:DI 23)
20929                      (reg:DI 24)
20930                      (reg:DI 25)
20931                      (reg:DI 26)
20932                      (reg:DI 27)
20933                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20934    (use (match_operand:DI 1 "register_operand" "r"))
20935    (use (match_operand:DI 2 "const_int_operand" "i"))
20936    (use (label_ref:DI (match_operand 3 "" "X")))]
20937   "TARGET_64BIT
20938    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20939    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20940   "*
20941 {
20942   int i;
20943   operands[0] = gen_rtx_MEM (Pmode,
20944                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20945   output_asm_insn (\"jmp\\t%A1\", operands);
20946   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20947     {
20948       operands[4] = adjust_address (operands[0], DImode, i*16);
20949       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20950       PUT_MODE (operands[4], TImode);
20951       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20952         output_asm_insn (\"rex\", operands);
20953       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20954     }
20955   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20956                              CODE_LABEL_NUMBER (operands[3]));
20957   return \"\";
20958 }
20959   "
20960   [(set_attr "type" "other")
20961    (set_attr "length_immediate" "0")
20962    (set_attr "length_address" "0")
20963    (set_attr "length" "135")
20964    (set_attr "memory" "store")
20965    (set_attr "modrm" "0")
20966    (set_attr "mode" "DI")])
20967
20968 (define_expand "prefetch"
20969   [(prefetch (match_operand 0 "address_operand" "")
20970              (match_operand:SI 1 "const_int_operand" "")
20971              (match_operand:SI 2 "const_int_operand" ""))]
20972   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20973 {
20974   int rw = INTVAL (operands[1]);
20975   int locality = INTVAL (operands[2]);
20976
20977   gcc_assert (rw == 0 || rw == 1);
20978   gcc_assert (locality >= 0 && locality <= 3);
20979   gcc_assert (GET_MODE (operands[0]) == Pmode
20980               || GET_MODE (operands[0]) == VOIDmode);
20981
20982   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20983      supported by SSE counterpart or the SSE prefetch is not available
20984      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20985      of locality.  */
20986   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20987     operands[2] = GEN_INT (3);
20988   else
20989     operands[1] = const0_rtx;
20990 })
20991
20992 (define_insn "*prefetch_sse"
20993   [(prefetch (match_operand:SI 0 "address_operand" "p")
20994              (const_int 0)
20995              (match_operand:SI 1 "const_int_operand" ""))]
20996   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20997 {
20998   static const char * const patterns[4] = {
20999    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21000   };
21001
21002   int locality = INTVAL (operands[1]);
21003   gcc_assert (locality >= 0 && locality <= 3);
21004
21005   return patterns[locality];
21006 }
21007   [(set_attr "type" "sse")
21008    (set_attr "memory" "none")])
21009
21010 (define_insn "*prefetch_sse_rex"
21011   [(prefetch (match_operand:DI 0 "address_operand" "p")
21012              (const_int 0)
21013              (match_operand:SI 1 "const_int_operand" ""))]
21014   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21015 {
21016   static const char * const patterns[4] = {
21017    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21018   };
21019
21020   int locality = INTVAL (operands[1]);
21021   gcc_assert (locality >= 0 && locality <= 3);
21022
21023   return patterns[locality];
21024 }
21025   [(set_attr "type" "sse")
21026    (set_attr "memory" "none")])
21027
21028 (define_insn "*prefetch_3dnow"
21029   [(prefetch (match_operand:SI 0 "address_operand" "p")
21030              (match_operand:SI 1 "const_int_operand" "n")
21031              (const_int 3))]
21032   "TARGET_3DNOW && !TARGET_64BIT"
21033 {
21034   if (INTVAL (operands[1]) == 0)
21035     return "prefetch\t%a0";
21036   else
21037     return "prefetchw\t%a0";
21038 }
21039   [(set_attr "type" "mmx")
21040    (set_attr "memory" "none")])
21041
21042 (define_insn "*prefetch_3dnow_rex"
21043   [(prefetch (match_operand:DI 0 "address_operand" "p")
21044              (match_operand:SI 1 "const_int_operand" "n")
21045              (const_int 3))]
21046   "TARGET_3DNOW && TARGET_64BIT"
21047 {
21048   if (INTVAL (operands[1]) == 0)
21049     return "prefetch\t%a0";
21050   else
21051     return "prefetchw\t%a0";
21052 }
21053   [(set_attr "type" "mmx")
21054    (set_attr "memory" "none")])
21055
21056 (define_expand "stack_protect_set"
21057   [(match_operand 0 "memory_operand" "")
21058    (match_operand 1 "memory_operand" "")]
21059   ""
21060 {
21061 #ifdef TARGET_THREAD_SSP_OFFSET
21062   if (TARGET_64BIT)
21063     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21064                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21065   else
21066     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21067                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21068 #else
21069   if (TARGET_64BIT)
21070     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21071   else
21072     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21073 #endif
21074   DONE;
21075 })
21076
21077 (define_insn "stack_protect_set_si"
21078   [(set (match_operand:SI 0 "memory_operand" "=m")
21079         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21080    (set (match_scratch:SI 2 "=&r") (const_int 0))
21081    (clobber (reg:CC FLAGS_REG))]
21082   ""
21083   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21084   [(set_attr "type" "multi")])
21085
21086 (define_insn "stack_protect_set_di"
21087   [(set (match_operand:DI 0 "memory_operand" "=m")
21088         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21089    (set (match_scratch:DI 2 "=&r") (const_int 0))
21090    (clobber (reg:CC FLAGS_REG))]
21091   "TARGET_64BIT"
21092   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21093   [(set_attr "type" "multi")])
21094
21095 (define_insn "stack_tls_protect_set_si"
21096   [(set (match_operand:SI 0 "memory_operand" "=m")
21097         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21098    (set (match_scratch:SI 2 "=&r") (const_int 0))
21099    (clobber (reg:CC FLAGS_REG))]
21100   ""
21101   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21102   [(set_attr "type" "multi")])
21103
21104 (define_insn "stack_tls_protect_set_di"
21105   [(set (match_operand:DI 0 "memory_operand" "=m")
21106         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21107    (set (match_scratch:DI 2 "=&r") (const_int 0))
21108    (clobber (reg:CC FLAGS_REG))]
21109   "TARGET_64BIT"
21110   {
21111      /* The kernel uses a different segment register for performance reasons; a
21112         system call would not have to trash the userspace segment register,
21113         which would be expensive */
21114      if (ix86_cmodel != CM_KERNEL)
21115         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21116      else
21117         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21118   }
21119   [(set_attr "type" "multi")])
21120
21121 (define_expand "stack_protect_test"
21122   [(match_operand 0 "memory_operand" "")
21123    (match_operand 1 "memory_operand" "")
21124    (match_operand 2 "" "")]
21125   ""
21126 {
21127   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21128   ix86_compare_op0 = operands[0];
21129   ix86_compare_op1 = operands[1];
21130   ix86_compare_emitted = flags;
21131
21132 #ifdef TARGET_THREAD_SSP_OFFSET
21133   if (TARGET_64BIT)
21134     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21135                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21136   else
21137     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21138                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21139 #else
21140   if (TARGET_64BIT)
21141     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21142   else
21143     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21144 #endif
21145   emit_jump_insn (gen_beq (operands[2]));
21146   DONE;
21147 })
21148
21149 (define_insn "stack_protect_test_si"
21150   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21151         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21152                      (match_operand:SI 2 "memory_operand" "m")]
21153                     UNSPEC_SP_TEST))
21154    (clobber (match_scratch:SI 3 "=&r"))]
21155   ""
21156   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21157   [(set_attr "type" "multi")])
21158
21159 (define_insn "stack_protect_test_di"
21160   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21161         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21162                      (match_operand:DI 2 "memory_operand" "m")]
21163                     UNSPEC_SP_TEST))
21164    (clobber (match_scratch:DI 3 "=&r"))]
21165   "TARGET_64BIT"
21166   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21167   [(set_attr "type" "multi")])
21168
21169 (define_insn "stack_tls_protect_test_si"
21170   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21171         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21172                      (match_operand:SI 2 "const_int_operand" "i")]
21173                     UNSPEC_SP_TLS_TEST))
21174    (clobber (match_scratch:SI 3 "=r"))]
21175   ""
21176   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21177   [(set_attr "type" "multi")])
21178
21179 (define_insn "stack_tls_protect_test_di"
21180   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21181         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21182                      (match_operand:DI 2 "const_int_operand" "i")]
21183                     UNSPEC_SP_TLS_TEST))
21184    (clobber (match_scratch:DI 3 "=r"))]
21185   "TARGET_64BIT"
21186   {
21187      /* The kernel uses a different segment register for performance reasons; a
21188         system call would not have to trash the userspace segment register,
21189         which would be expensive */
21190      if (ix86_cmodel != CM_KERNEL)
21191         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21192      else
21193         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21194   }
21195   [(set_attr "type" "multi")])
21196
21197 (define_mode_iterator CRC32MODE [QI HI SI])
21198 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21199 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21200
21201 (define_insn "sse4_2_crc32<mode>"
21202   [(set (match_operand:SI 0 "register_operand" "=r")
21203         (unspec:SI
21204           [(match_operand:SI 1 "register_operand" "0")
21205            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21206           UNSPEC_CRC32))]
21207   "TARGET_SSE4_2"
21208   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21209   [(set_attr "type" "sselog1")
21210    (set_attr "prefix_rep" "1")
21211    (set_attr "prefix_extra" "1")
21212    (set_attr "mode" "SI")])
21213
21214 (define_insn "sse4_2_crc32di"
21215   [(set (match_operand:DI 0 "register_operand" "=r")
21216         (unspec:DI
21217           [(match_operand:DI 1 "register_operand" "0")
21218            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21219           UNSPEC_CRC32))]
21220   "TARGET_SSE4_2 && TARGET_64BIT"
21221   "crc32q\t{%2, %0|%0, %2}"
21222   [(set_attr "type" "sselog1")
21223    (set_attr "prefix_rep" "1")
21224    (set_attr "prefix_extra" "1")
21225    (set_attr "mode" "DI")])
21226
21227 (include "mmx.md")
21228 (include "sse.md")
21229 (include "sync.md")